Skip to content

2021-05-07 Release of the Checked C Clang compiler

Compare
Choose a tag to compare

Summary

This is a release build of the Checked C Clang compiler for Windows 32-bit and 64-bit platforms. It is for use by developers who want to experiment with the Checked C language extensions to guarantee the type safety of their C code. It is based on the Checked C specification version 0.9, which is also one of the released artifacts.

Release Date and Tag

7th May 2021 CheckedC-Clang-11.1.0-rel1

Installation Notes

Clang expects an existing C/C++ compiler before running the installer. If installing on a fresh machine, first install the C/C++ compiler. We recommend Visual Studio 2019, which has a free Community version available. Use Visual Studio 2019's installer to ensure a C/C++ compiler and runtime are present before installing Checked C Clang.

  • The binaries are installers for 32-bit and 64-bit Windows versions of the compiler
  • The compiler will be installed in a separate directory from your existing Clang install. If you are also using the production version of Clang, do not add the Checked C version to your path.

Using the Compiler

See the Checked C Clang users manual for directions on how to use the compiler.

There are now two ways to use the Checked C Clang compiler in Visual Studio. The LLVM project has created a Visual Studio extension. You can use a property page for your project to directly choose the Checked C Clang compiler binary.

Visual Studio 2019 also now directly supports Clang/LLVM. This blog post describes the support for CMake projects. This blog post describes support for MSBuild projects. If you installed the Checked C Clang compiler and added it to your PATH variable, Visual Studio should directly pick it up. Otherwise, you can follow the directions to use a custom installation of Clang.

Change Notes

Core features

  • PR #924: Infer bounds for conditional operators. The inferred bounds of a conditional operator e1 ? e2 : e3 are the greatest lower bound of the bounds of e2 and the bounds of e3.
  • PR #984: Upgrade to LLVM/Clang 11.
  • PR #998: Implicit inclusion of checked header files.

Free variables in bounds checking

The static checking of bounds declarations now detects errors that result from a lack of relational information between variables used in inferred and declared bounds (PR #903).

If the inferred bounds of a variable p use the value of a variable x, and:

  1. x is not equivalent to an integer constant, and:
  2. There is no relational information between x and any of the expressions in the declared bounds of p

Then x is considered a free variable and the compiler will emit an error: "it is not possible to prove that the inferred bounds of 'p' imply the declared bounds of 'p'".

A similar definition applies for variables that appear in the declared bounds of a variable p and have no relation to the expressions in the inferred bounds of p.

void f(_Array_ptr<int> p : count(3), _Array_ptr<int> q : bounds(p, p + x), int x) {
  // The inferred bounds of p after this assignment are bounds(p, p + x).
  // The declared bounds of p are bounds(p, p + 3).
  // x is not equivalent to an integer constant.
  // There is no relational information between x and any of the expressions
  // in the declared bounds of p (bounds(p, p + 3)).
  // x is a free variable.
  // It is not possible for the compiler to prove that bounds(p, p + x) imply bounds(p, p + 3).
  p = q;
}

Implicit inclusion of checked header files

By default, the Checked C Clang compiler implicitly includes the checked counterpart of an included system header file, if one is present. Implicit inclusion can be turned off by compiling with the flag -DNO_IMPLICIT_INCLUDE_CHECKED_HDRS. In the sample code snippet below, the default behavior is indicated by DEF:<comment> and behavior when implicit inclusion is turned off is indicated by OFF:<comment>.

#include <stdio.h>            // DEF: stdio_checked.h is included;  OFF: stdio.h is included.
#include <stdlib_checked.h>   // DEF: stdlib_checked.h is included; OFF: stdlib_checked.h is included (explicit inclusion overrides).
#include <float.h>            // DEF: float.h is included (float_checked.h is not present); OFF: float.h is included.

int main() {
    return 0;
}

Bug fixes

  • Issue #969: Unexpected bounds error after PR #903 (fixed by PR #973).
  • Issue #925: ResetKilledBounds adds out-of-scope variables to bounds context (fixed by PR #926).
  • Issue #935: Inconsistency with bounds on NT arrays and NT array pointers (fixed by PR #942, tests in microsoft/checkedc #429).
  • Issue #933: Correctly widen bounds for expressions not containing addition or multiplication (fixed by PR #944).
  • Issue #932: Fix assert in bounds widening "BinaryNode operator must equal parent operator" (fixed by PR #943).
  • Issue #895: Assignments within conditional expressions should kill widened bounds (fixed by PR #898).
  • Issue #987: Fix sarif-multi-diagnostic-test.c failure on Windows.
  • Issue #951: Fix x64 Windows builds break.
  • Issue #1017: Improper compiler error when checked variable is out of scope (fixed by PR #1031).
  • Issue #1026: Enabling the LifetimeEnds CFGElement crashes the compiler during CFG construction (fixed by PR #1028).
  • Issue #1009: Introduce temporaries for argument expressions that have side-effects and are used in parameter or return bounds (fixed for the short-term by PR #1014).

Extension Features Implemented

See the implementation roadmap and status page. Some runtime checks and some static checking is not implemented yet.