Skip to content

Releases: checkedc/checkedc-clang

Checked C clang 12.0.2 release

01 Sep 17:15
9d329e1
Compare
Choose a tag to compare

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 choose Keep.
  • Double click on the executable to start the installer.
  • Follow the installer directions.

2021-09-14 Release of the Checked C Clang compiler

15 Sep 01:26
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

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) for e 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, and p is never assigned a checked pointer value, then the declared bounds of p 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.

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:

  1. When an expression e is returned from a function f, the inferred bounds of e imply the declared bounds of f.
  2. 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 and x + 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

03 Aug 19:30
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

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 pointer p is p - 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 and p2 have the same incomplete type, and c1 and c2 are constants, and p1 is equal to p2, then bounds(p1, p1 + c1) implies bounds(p2, p2 + c2) if and only if c1 >= 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

07 May 16:23
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.

2020-07-31 Developer Build of Checked C clang compiler

31 Jul 21:28
2745f7d
Compare
Choose a tag to compare

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 checked nt_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 (including NULL) 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

  • Issue #861: Fix CodeGen assert failure for bounds-safe interfaces (fixed by PR #869).

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

29 Feb 00:45
f9bb238
Compare
Choose a tag to compare

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

22 Jul 18:45
Compare
Choose a tag to compare

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

01 Dec 01:43
02aeff2
Compare
Choose a tag to compare

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

01 Aug 23:32
8fb96d9
Compare
Choose a tag to compare

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 and array_ptr arguments. Use the _Nt_array_ptr interface for strncmp and provide an alternate inline definition strncmp_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

07 Jun 22:55
b88a40f
Compare
Choose a tag to compare

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 to CHECKED_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.