Releases: checkedc/checkedc-clang
Checked C clang 12.0.2 release
Summary
This is a release of the Checked C clang compiler. It is based on the Checked C specification version 1.0.
Release Date
November 13, 2023
Installation Notes
Verifying signatures of downloaded files
We use cosign to sign the distribution files. To verify a file, download the file and the associated file.bundle, install cosign and then run:
cosign verify-blob <file> --bundle <file>.bundle --certificate-identity=david.tarditi@secure-software-development-project.org --certificate-oidc-issuer=https://accounts.google.com
You can install cosign following these directions or from the GitHub releases page for cosign.
MacOS (ARM64)
To install:
- Download the file CheckedC-Clang-12.0.2-Darwin-arm64.tar.gz.
- Create an installation directory and move the file there.
- Use:
gunzip CheckedC-Clang-12.0.2-Darwin-arm64.tar.gz
tar xf CheckedC-Clang-12.0.0-Darwin.tar
The clang compiler will be located at <your installation directory>/bin/CheckedC-Clang-12.0.0git-Darwin/clang
.
The 3c tool will be located at <your installation directory>/bin/CheckedC-Clang-12.0.0git-Darwin/3c
.
Ubuntu 22.04
To install:
- Download the file CheckedC-Clang-12.0.2-gnu-ubuntu-22.04.tar.gz.
- Create an installation directory and move the file there.
- Use:
gunzip CheckedC-Clang-12.0.2-gnu-ubuntu-22.04.tar.gz
tar xf CheckedC-Clang-12.0.0-gnu-ubuntu-22.04.tar
The clang compiler will be located at <your installation directory>/bin/CheckedC-Clang-12.0.0git-Linux/clang
.
The 3c tool will be located at <your installation directory>/bin/CheckedC-Clang-12.0.0git-Linux/3c
.
Windows 10/11 (64-bit)
To install:
- Download the file CheckedC-clang-12.0.2-win64.exe. If you are using the Edge browser, it may try to block the download as unsafe. Select the
...
next to the file name and chooseKeep
. - Double click on the executable to start the installer.
- Follow the installer directions.
2021-09-14 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
14th September 2021 CheckedC-Clang-12.0.1-rel3
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 #1183: Get rvalue bounds for the value of lvalue expressions from the CheckingState. The observed bounds of an lvalue expression
e
are the bounds (if any) fore
that are currently stored in the checking state. - PR #1181: Member expression bounds checking in multiple assignments. The behavior for checking member expression bounds in full expressions that contain multiple assignments is now consistent with the behavior for checking the bounds of variables.
- PR #1176: Bounds checking for pointer dereferences and array subscripts. The static checking for bounds declarations has been extended to check the bounds of pointers of type
_Ptr<T>
or_Nt_array_ptr<T>
that are stored in pointer dereferences or array subscripts. - PR #1169: Bounds checking bounds-safe interfaces in unchecked scopes. In an unchecked scope, if
p
is an unchecked pointer with a bounds-safe interface, andp
is never assigned a checked pointer value, then the declared bounds ofp
are not validated. - PR #1166: Update bounds checking notes. Only one note is emitted per statement per lvalue expression for an expression with unknown bounds being assigned to an lvalue expression.
- PR #1149: Handle complex conditionals in bounds widening. Bounds widening is now possible in presence of complex conditionals like:
if (*p != 0)", "if ((c = *p) == 'a')
, etc. - PRs #1174, #1182: Support variadic function calls in checked scope. The compiler now supports calling variadic functions in checked scope. These are functions like
printf
,scanf
, etc that take a format string and have a variable number of arguments. The arguments and format specifiers for these functions are checked. The checking of variadic functions in checked scope follows these rules:- All warnings issued by the
-Wformat
family of flags are errors in checked scope. - No bounds checking of arguments to variadic functions like
printf/scanf
, etc is done. - For
printf
-like functions:%s
is allowed only with argument type_Nt_array_ptr
or_Nt_checked
.%p
is allowed with any argument type.%n
is disallowed.- For all other format specifiers, only scalar argument types are allowed.
- For
scanf
-like functions:%s
is disallowed.- All width modifiers to format specifiers are disallowed.
%p
is disallowed%n
is disallowed- For all other format specifiers, only
_Ptr
argument types are allowed.
- All warnings issued by the
Checking return bounds
The static checking for bounds declarations has been extended to check the declared bounds for a function. The static checking validates that:
- When an expression
e
is returned from a functionf
, the inferred bounds ofe
imply the declared bounds off
. - Parameters used in the declared bounds of
f
are unmodified.
For example, consider the following sample program involving declared function bounds:
_Array_ptr<int> f1(_Array_ptr<int> p : count(2),
_Array_ptr<int> q : count(1),
int test) : count(2) {
if (test)
// No errors or warnings.
// bounds(p, p + 2) implies bounds(_Return_value, _Return_value + 2).
return p;
// error: return value bounds do not imply declared return bounds for 'f1'
return q;
}
_Array_ptr<int> f2(int i) : count(i) {
// error: modified expression 'i' used in the declared return bounds for 'f2'
i++;
}
Support for bundled blocks
The compiler now supports the grouping of expression statements and declarations into bundled blocks. Bounds declarations are checked only at the end of bundled blocks. For more details, please refer to Sections 3.5 and 4.7 of the Checked C specification. Given below is an example that illustrates the use of bundled blocks.
#include <string.h>
struct Node {
_Nt_array_ptr<char> name;
unsigned int age;
};
struct Group {
_Array_ptr<struct Node> list : count (n);
unsigned int n;
};
// get the first name that starts with the letters 'Ar'
_Nt_array_ptr<char> get_name(_Array_ptr<struct Group> groups : count(gcnt), unsigned int gcnt)
_Checked {
unsigned int n = 0;
_Array_ptr<struct Node> group : count(n) = 0;
for (int i = 0; i < gcnt; i++) {
_Bundled {
group = groups[i].list;
n = groups[i].n;
}
for (int j = 0; j < n; j++) {
_Nt_array_ptr<char> name = group[j].name;
unsigned int m = strlen(name) _Where name : count(m);
if (m >= 2 && name[0] == 'A' && name[1] == 'r')
return name;
}
}
return "";
}
Bug fixes
- Issue #1148: Inconsistent behavior with
str
and&str[0]
(fixed by PR #1163). - Issue #1184: Equality should not be recorded between expressions such as
x
andx + 1
(fixed by PR #1162). - Issue #1153: Assertion fail during bounds widening (fixed by PR #1154).
Extension Features Implemented
See the implementation roadmap and status page. Some runtime checks and some static checking is not implemented yet.
2021-08-03 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
3rd August 2021 CheckedC-Clang-12.0.1-rel2
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 #1136: Upgrade to LLVM/Clang 12.
-
PR #1127: Invertibility for unchecked pointers. For example, in a statement
p = p + 1
, the inverse of an unchecked pointerp
isp - 1
. -
PR #1128: Simple normalizations for +1/-1 bounds scenarios. The bounds checker is able to validate bounds in examples such as:
void f(_Nt_array_ptr<char> p : count(len), unsigned int len) { if (*(p + len)) { // The inferred bounds of p are bounds(p, (p + (len - 1)) + 1). // The bounds checker recognizes that these are equivalent to // the declared bounds of bounds(p, p + len). ++len; } }
-
PR #1117: Handle incomplete types in BaseRange. If
p1
andp2
have the same incomplete type, andc1
andc2
are constants, andp1
is equal top2
, thenbounds(p1, p1 + c1
) impliesbounds(p2, p2 + c2)
if and only ifc1 >= c2
.
Bounds checking for member expressions
The static checking for bounds declarations has been extended to check the bounds of pointers stored in struct members. For example, consider the following sample program involving variables:
void f(_Array_ptr<int> p : count(len), // note: (expanded) declared bounds are 'bounds(p, p + len)'
_Array_ptr<int> q : bounds(unknown),
unsigned int len) {
// warning: cannot prove declared bounds for 'p' are valid after increment
// note: (expanded) inferred bounds are 'bounds(p, p + len - 1U)'
++len;
// error: inferred bounds for 'p' are unknown after assignment
// note: assigned expression 'q' with unknown bounds to 'p'
p = q;
// no errors or warnings
// inferred bounds of p after the statement are bounds(any)
len = 1, p = 0;
}
The bounds checker exhibits similar behavior in an analogous program involving struct members:
struct S {
_Array_ptr<int> p : count(len); // note: (expanded) declared bounds are 'bounds(s.p, s.p + len)'
_Array_ptr<int> q : bounds(unknown);
unsigned int len;
};
void f(struct S s) {
// warning: cannot prove declared bounds for 's.p' are valid after increment
// note: (expanded) inferred bounds are 'bounds(s.p, s.p + s.len - 1U)'
++s.len;
// error: inferred bounds for 's.p' are unknown after assignment
// note: assigned expression 's.q' with unknown bounds to 's.p'
s.p = s.q;
// no errors or warnings
// inferred bounds of s.p are the statement are bounds(any)
s.len = 1, s.p = 0;
}
-
PR #1122: Support bounds widening of null-terminated arrays in presence of Where clauses.
We have added support to widen the bounds of a null-terminated array in case its bounds are redeclared using a Where clause. This enables us to widen the bounds of a null-terminated array when its length is obtained using a call to
strlen
.void foo(_Nt_array_ptr<char> p : count(n), unsigned n) { if (*(p + n)) { // bounds of p widened to bounds(p, p + n + 1) char x = *(p + n + 1); //valid access } int len = strlen(p) _Where p : bounds(p, p + len); // bounds of p redeclared to bounds(p, p + len) if (*(p + len)) { // bounds of p widened to bounds(p, p + len + 1) char x = *(p + len + 1); // valid access } }
-
PR #1137: Use invertibility to support bounds widening of null-terminated arrays inside loops.
We have improved support to widen the bounds of a null-terminated array when the elements of the null-terminated array are iterated in a loop.
void foo(_Nt_array_ptr<char> p : count(len), unsigned len) { while (*(p + len)) { // bounds of p widened to bounds(p, p + len + 1) if (*(p + len + 1)) { // bounds of p widened to bounds(p, p + len + 2) len++; // bounds of p adjusted to bounds(p, p + len - 1 + 2) char x = *(p + len + 1); // valid access } } }
Where clauses can be used to specify program invariants and pre/post conditions. In this release we have added the support for parsing Where clauses in Checked C as part of the ongoing design and implementation of the complete support for Where clauses.
We have added support to parse Where clauses on:
-
Expression statements
int a; a = foo() _Where a > 0 _And a < 10;
-
Variable declarations
int a = b _Where a > 0 _And a < 10;
-
Parameter declarations
void foo(int a _Where a > 0, int b, int c _Where c < 0); void bar(_Nt_array_ptr<char> p _Where p: bounds(p, p + len), unsigned len); void baz(int *p : itype(_Ptr<int>) _Where p != 0);
-
Null statements
void foo(_Nt_array_ptr<char> p, unsigned len) { _Where p : bounds(p, p + len); ... }
Bug fixes
- Issue #974: Wrong error from #903 when passing _Assume_bounds_cast directly to function with itype (fixed by PR #978).
- Issue #1084: Crash while compilation (fixed by PR #1090).
- Issue #1120: An nt_checked array with an empty initializer list should be an error (fixed by PR #1121).
Extension Features Implemented
See the implementation roadmap and status page. Some runtime checks and some static checking is not implemented yet.
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.
2020-07-31 Developer Build of Checked C clang compiler
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.
2020-02-28 Developer Build of Checked C clang compiler
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
Clang source update
We have upgraded to the sources for clang version 9.0.0.
Core features
- PR #663: Add a dynamic check for pointer arithmetic of null pointers.
- PR #626: Disallow explicit cast to nt_array_ptr in checked scopes. These casts are disallowed since the source of the cast may not point to a null-terminated array.
- PR #718: Prevent static variables declarations from using free type variables. These uses are disallowed since the storage of static variables in generic functions persists, and different generic type instantiations could be used to overwrite memory (see issue #684).
- PR #673: Correctly determine bounds for predefined literals. The compiler can now determine bounds for preprocessor constants (see issue #650).
Dataflow analysis for bounds checking
The static checking of bounds declarations now makes use of facts from conditional statements, such as i < j
(PR #657). This results in fewer warnings during bounds declaration checking. See the wiki for more information.
Generic structs and existential structs
Checked C now supports generic structs and existential structs (PR #683).
A generic struct can be created using an underlying representation type:
struct IntSet _For_any(T) {
T *rep;
void (*add)(T *rep, int x);
void (*rem)(T *rep, int x);
int (*find)(T *rep, int x);
}
The new builtin pack
function can be used to create a existential struct using a generic struct:
exist_type e = _Pack(expr, exist_type, subst_type);
where expr
is an instance of a generic struct.
This work is still missing support for the sizeof(T) constraints, which would allow us to do pointer arithmetic on pointers to T. See the wiki for more information.
(Experimental) Static analyzer with Z3
We have added a clang static analyzer (SimpleBounds
) to check whether the memory accesses within unchecked code are following the bounds-safe interface. This experimental checker uses the Z3 theorem prover to analyze Checked C bounds expressions and verify memory accesses within unchecked code. See the wiki for more information.
Bug fixes
- Issue #704: Add checked information for function declarations to AST reading/writing (fixed by PR #723).
- Issue #419: Add checked information for compound blocks to AST reading/writer (fixed by PR #716).
- Introduce temporary bindings to bounds cast expression (PR #694). This allows modifying expressions to be used as the subexpression of a bounds cast (
_Dynamic_bounds_cast
or_Assume_bounds_cast
). - Issue #331: Relative alignment information missing from statement profiling (fixed by PR #692).
Extension features implemented
See the implementation roadmap and status. Some runtime checks and a lot of the static checking is not implemented yet.
2019-07-22 Developer Build of Checked C clang compiler
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
We have upgraded to the sources for clang version 8.0.0.
We implemented the following features:
- Disallow explicit casts from ptr, array_ptr, or unchecked pointers to nt_array_ptr in checked scopes.
- The compiler now infers bounds for call subexpressions that return pointers with bounds. This was a representational issue in the compiler. the compiler needed to introduce temporaries to hold the values of call subexpressions.
- With that inference in place, the generated code now does dynamic bounds checking for call subexpressions that are immediately subscripted or dereferenced.
- This also makes the checking of bounds declarations more strict. At assignments to variables with declared bounds and initalizers for such variables, the compiler needs to check that the right-hand side of tje assignment or initializer implies the declared bounds. The compiler was not doing checking when the right-hand side was a call expression. Now it does.
We added a bounds-safe interface for strdup.
Extension features implemented
See the implementation roadmap and status. Some runtime checks and a lot of the static checking is not implemented yet.
2018-11-30 Developer Build of Checked C clang compiler
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 using Visual Studio 2017, which has a free Community version available. Use Visual Studio 2017'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.
To change the compiler to Checked C clang in a Visual Studio project, open the project Properties and set "Platform Toolset" to one of the "CheckedC-LLVM" versions in the drop-down. (If there are no CheckedC-LLVM options in the "Platform Toolset" dropdown, try reinstalling Checked C clang.)
Change notes
Void pointers are a feature in C that can lead to type confusion. Any pointer type can be converted implicitly to a void pointer and a void pointer can be converted implicitly to any pointer types. We took our first steps in this release toward eliminating unsafe uses of void pointers in checked scopes.
We now support declaring existing library functions to have generic bounds-safe interfaces. This causes those functions to be treated as generic functions in checked scopes (or when type arguments are supplied in unchecked scopes). This eliminate the possibility of type confusion errors at calls to those functions.
- Implemented support for redeclaring existing functions to have generic bounds-safe interfaces (PR #546)
- Fixed bugs in the implementation (PR #581).
We updated the Checked C header files to provide generic bound-safe interfaces for memcpy
, bsearch
,
calloc
, malloc
, realloc
, free
, and thrd_create
(PR #315), This means that type arguments must be supplied at calls to those functions in checked scopes.
We improved the Checked C header files. We added bounds-safe interfaces for:
- assert.h
- errno.h
- POSIX socket header functions in sys/socket_checked.h.
- Unistd file commands in unitsd.h
inet_addr
function in arpa\inet.h
We now have two kinds of checked scopes: memory-safe checked scopes (assuming there are no memory management errors) and bounds-only checked scopes. Memory-safe checked scopes will enforce memory safety be requiring bounds-safety and disallowing some kinds of pointer casts. Bounds-only checked scope only enforce that memory accesses are bounds checked. They allow potentially unsafe pointer casts.
In memory-safe checked scopes, we no longer allow implicit conversions to or from void pointers when the non-void pointer type points to data that contains a checked pointer.
We added support for saving/restoring pragma CHECKED_SCOPE
state, using #pragma CHECKED_SCOPE push
, and #pragma CHECKED_SCOPE pop
. This is useful for placing header file declarations in checked scopes, regardless of whether the header file is included in a checked scope or an unchecked scope.
We now insert bounds checks for subscript and pointer dereference operations where the pointer-typed expression is a string or array literal or a pointer derived from a string or array literal (for example, "abcde"[index]
, where index is an integer variable) (PR #561).
Add support for parsing and representing the Return_value
expression (PR #544). We still need to extend inference of bounds and checking of bounds declarations to handle this expression.
Add support for using expression temporaries to track bounds during expression evaluation,. The specification proposes the idea of _Current_expr_value
, but that requires adjustments to recompute a value that was already computed to a temporary (PR #561).
We fixed the following bugs:
- Issue #484, where the compiler would complain about converting a checked function pointer to a fully checked type (fixed by PR #576).
- Fixed wrong use of assert (PR #568).
- Fixed duplicate messages about illegal void pointer arithmetic (PR #563).
Extension features implemented
See the implementation roadmap and status. Some runtime checks and a lot of the static checking is not implemented yet.
2018-08-01 Developer build of Checked C clang compiler
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 using Visual Studio 2017, which has a free Community version available. Use Visual Studio 2017'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.
To change the compiler to Checked C clang in a Visual Studio project, open the project Properties and set "Platform Toolset" to one of the "CheckedC-LLVM" versions in the drop-down. (If there are no CheckedC-LLVM options in the "Platform Toolset" dropdown, try reinstalling Checked C clang.)
Change notes
We implemented the following static checks required by the language extension:
- Validate that initializers for _Nt_checked arrays are null-terminated (issue #397)
- Check that local variables with array types or struct/union types that contain checked pointers have initializers (issue #445).
- Implement restrictions on taking address of members and variables with bounds (issue #490).
We made improvements to the Checked C header files for the C standard library:
- Add
unistd_checked.h
. - Add guards to the header files (issue #293): only parse the header declarations once and don't add the checked declarations if included in a C++ file.
- Improve bounds-safe interface for
strncmp
.strncmp
has different bounds-safe interfaces for_Nt_array_ptr
andarray_ptr
arguments. Use the_Nt_array_ptr
interface forstrncmp
and provide an alternate inline definitionstrncmp_array_ptr
for the_Array_ptr
interface..
We fixed the following issues:
- Build release compilers of clang for Windows installers (issue #495). The prior installers were using debug versions of the compiler.
- Fix compiler assert about bounds expression already existing (issue #537). The compiler would crash with an assert when checking a
dynamic_bounds_cast
whose expression argument required a bounds check. - Fix compiler crash reported by user (issue #488). The compiler could crash after checking a bounds declaration for a function call where an argument was implicitly widened.
We made some internal changes that should not be visible externally:
- Traverse expressions during bounds declaration checking using a control-flow graph (in preparation to incorporating dataflow information during bounds declaration checking).
Extension features implemented
See the implementation roadmap and status. Some runtime checks and a lot of the static checking is not implemented yet.
2018-04-27 Developer build of Checked C clang compiler
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. We do not recommend using this compiler in production environments because core extension features are still under active development.
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 using Visual Studio 2017, which has a free Community version available. Use Visual Studio 2017's built in feature 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.
- If you could use prebuilt binaries for another OS, please open an issue.
Using the compiler
See the Checked C clang users manual for directions on how to use the compiler.
To change the compiler to Checked C clang in a Visual Studio project, open the project Properties and set "Platform Toolset" to one of the "CheckedC-LLVM" versions in the drop-down. (If there are no CheckedC-LLVM options in the "Platform Toolset" dropdown, try reinstalling Checked C clang.)
Change notes
- Rename
BOUNDS_CHECKED
pragma toCHECKED_SCOPE
. - Static checking now produces an error message when inferred bounds contain modifying expressions (#480).
- Fix compiler crash when using a function in a checked scope that returns a function pointer with a bounds-safe interface (#483).
- Fix incorrect typechecking error when making an indirect function call via a const member (#482).
Extension features implemented
See the implementation roadmap and status. Some runtime checks and a lot of the static checking is not implemented yet.