RFC: Enforcing Bounds Safety in C (-fbounds-safety)

As we only briefly touched on this here, the expression can be a simple reference to a declaration, a constant (including calls to constant functions), or an arithmetic expression that does not have side effects. Therefore, the following examples will work:

// Single arithmetic expression without side effect
void foo(int tens, int ones, int *__counted_by(10 * tens + ones) ptr);

// Call to a const function
void const_foo(void) __attribute__((const));
int *__counted_by(const_foo()) var;

However, the current implementation doesn’t allow ternary operators, and we were planning to extend our specification to support ternary operators.

I’ve slightly adjusted the examples for C since the current proposal doesn’t support C++. An expression passed to a bounds annotation can refer to other members of the same struct, so the following example is allowed.

struct S {
  int n;
  // Allowed: Counted by a member variable
  int *__counted_by(n) ptr;
};

However, referring to a member of another struct, including nested structs (or the base struct) is not allowed. This is because of complications to maintain the soundness of the count value in a different struct. In the following example, bp , which is a pointer to Base , is used to update n . This could potentially break the correctness of the bounds information if the dynamic type of bp is Derived (or aliased with a pointer to Derived ) but Sema won’t be able to identify this.

struct Base {
  int n;
};
struct Derived {
  struct Base header;
  // Not allowed: Counted by a member of other struct member
  int * __counted_by(header.n) ptr;
};

void foo(struct Base *bp, struct Derived *dp) {
    // Potentially unsafe and compiler doesn't know if `bp` and `dp` alias 
    bp->n++;
}

Currently, the extension does not support the patten of “counted by an array element” to support the example below, but we are open to hearing about use cases and suggestions to extend the model.

// Not allowed: Counted by an array element
void func(int n, int array[static 2], int * __counted_by(array[n]) ptr);

-fbounds-safety rejects any mismatched annotations for function redeclarations. As a result, the compiler reports errors for most of the examples provided below.

void foo(int n, int *ptr);
void foo(int n, int * __counted_by(n)) {} // error due to a bounds annotation mismatch

void bar(int n, int * __counted_by(n) ptr);
void bar(int n, int *ptr) {} // error due to a bounds annotation mismatch

// In File1.c
void baz(int n, int *ptr) {}

// In File2.c
void baz(int n, int * __counted_by(n) ptr); // missing an error as the compiler cannot see the other decl in File1.c 

void quux(int n, int m, int * __counted_by(n) ptr);
void quux(int n, int m, int * __counted_by(m) ptr); // error due to a bounds annotation mismatch

void barf(int n, int m, int * __counted_by(n) ptr1, int *ptr2);
void barf(int n, int m, int *ptr1, int * __counted_by(m) ptr2); // error due to bounds annotation mismatches