2021-05-07 Release of the Checked C Clang compiler
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 ofe2
and the bounds ofe3
. - 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:
x
is not equivalent to an integer constant, and:- There is no relational information between
x
and any of the expressions in the declared bounds ofp
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.