Summary
This is a developer build of the Checked C clang compiler. It is for use by developers who want to try out the Checked C extension while it is being implemented.
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 #864: Correctly determine bounds for array-typed compound literal expressions (see issue #859).
- PR #813: Fill in some missing cases for bounds-safe interface assignments (see issue #810). Assignments to nested pointers with bounds-safe interfaces are now allowed (see issue #797). Assigning an unchecked
nt_array_ptr
with a bounds-safe interface to a checkednt_array_ptr
is now allowed (see issue #806). - PR #865: Allow an
_Assume_bounds_cast
to be used for function pointers. An_Assume_bounds_cast
can now be used to convert an unchecked function pointer (includingNULL
) to a checked function pointer (see issue #855).
Bounds widening for null-terminated arrays
The static checking of bounds declarations now makes use of properties of null-terminated arrays to widen the bounds using a dataflow analysis (PR #821). The bounds of a null-terminated array can be widened based on the number of elements read. For example:
nt_array_ptr<T> V : bounds (low, high);
if (*V) { // Ptr dereference is NOT at the current upper bound. No bounds widening.
if (*(V + high)) { // Ptr dereference is at the current upper bound. Widen bounds by 1. New bounds for V are (low, high + 1).
if (*(V + high + 1)) { // Ptr dereference is at the current upper bound. Widen bounds by 1. New bounds for V are (low, high + 2).
if (*(V + high + 2)) { // Ptr dereference is at the current upper bound. Widen bounds by 1. New bounds for V are (low, high + 3).
See the wiki for more information.
Updating variables used in bounds declarations
The static checking of bounds declarations now uses a bounds context to detect errors that result from updates to variables that are used in declared bounds (PR #853).
If a variable i
used in the declared bounds of variable p
is updated and the value for i
is lost, the bounds of p
are unknown.
int i;
array_ptr<int> p : count(i) = 0;
// The value of i is lost. The bounds for p are now unknown.
i = 0;
If a variable i
used in the declared bounds of variable p
is updated and the previous value v
of i
is known, then v
is substituted for i
in the bounds of p
.
unsigned int i;
array_ptr<int> p : count(i) = 0;
// The previous value of i is i - 1. The bounds for p are now bounds(p, p + i - 1).
i = i + 1;
Bug fixes
Extension features implemented
See the implementation roadmap and status. Some runtime checks and a lot of the static checking is not implemented yet.