[all-commits] [llvm/llvm-project] fefdef: [Clang] Implement the 'counted_by' attribute (#76348)

Bill Wendling via All-commits all-commits at lists.llvm.org
Wed Jan 10 15:21:21 PST 2024


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: fefdef808c230c79dca2eb504490ad0f17a765a5
      https://github.com/llvm/llvm-project/commit/fefdef808c230c79dca2eb504490ad0f17a765a5
  Author: Bill Wendling <5993918+bwendling at users.noreply.github.com>
  Date:   2024-01-10 (Wed, 10 Jan 2024)

  Changed paths:
    M clang/docs/ReleaseNotes.rst
    M clang/include/clang/AST/DeclBase.h
    M clang/include/clang/Basic/Attr.td
    M clang/include/clang/Basic/AttrDocs.td
    M clang/include/clang/Basic/DiagnosticSemaKinds.td
    M clang/include/clang/Sema/Sema.h
    M clang/include/clang/Sema/TypoCorrection.h
    M clang/lib/AST/ASTImporter.cpp
    M clang/lib/AST/DeclBase.cpp
    M clang/lib/AST/Expr.cpp
    M clang/lib/CodeGen/CGBuiltin.cpp
    M clang/lib/CodeGen/CGExpr.cpp
    M clang/lib/CodeGen/CodeGenFunction.h
    M clang/lib/Sema/SemaDecl.cpp
    M clang/lib/Sema/SemaDeclAttr.cpp
    M clang/lib/Sema/SemaExpr.cpp
    A clang/test/CodeGen/attr-counted-by.c
    M clang/test/CodeGen/bounds-checking.c
    M clang/test/Misc/pragma-attribute-supported-attributes-list.test
    A clang/test/Sema/attr-counted-by.c

  Log Message:
  -----------
  [Clang] Implement the 'counted_by' attribute (#76348)

The 'counted_by' attribute is used on flexible array members. The
argument for the attribute is the name of the field member holding the
count of elements in the flexible array. This information is used to
improve the results of the array bound sanitizer and the
'__builtin_dynamic_object_size' builtin. The 'count' field member must
be within the same non-anonymous, enclosing struct as the flexible array
member. For example:

```
  struct bar;
  struct foo {
    int count;
    struct inner {
      struct {
        int count; /* The 'count' referenced by 'counted_by' */
      };
      struct {
        /* ... */
        struct bar *array[] __attribute__((counted_by(count)));
      };
    } baz;
  };
```

This example specifies that the flexible array member 'array' has the
number of elements allocated for it in 'count':

```
  struct bar;
  struct foo {
    size_t count;
     /* ... */
    struct bar *array[] __attribute__((counted_by(count)));
  };
```

This establishes a relationship between 'array' and 'count';
specifically that 'p->array' must have *at least* 'p->count' number of
elements available. It's the user's responsibility to ensure that this
relationship is maintained throughout changes to the structure.

In the following, the allocated array erroneously has fewer elements
than what's specified by 'p->count'. This would result in an
out-of-bounds access not not being detected:

```
  struct foo *p;

  void foo_alloc(size_t count) {
    p = malloc(MAX(sizeof(struct foo),
                   offsetof(struct foo, array[0]) + count *
                       sizeof(struct bar *)));
    p->count = count + 42;
  }
```

The next example updates 'p->count', breaking the relationship
requirement that 'p->array' must have at least 'p->count' number of
elements available:

```
  void use_foo(int index, int val) {
    p->count += 42;
    p->array[index] = val; /* The sanitizer can't properly check this access */
  }
```

In this example, an update to 'p->count' maintains the relationship
requirement:

```
  void use_foo(int index, int val) {
    if (p->count == 0)
      return;
    --p->count;
    p->array[index] = val;
  }
```




More information about the All-commits mailing list