[clang] [BoundsSafety] Allow 'counted_by' attribute on pointers in structs in C (PR #90786)

Bill Wendling via cfe-commits cfe-commits at lists.llvm.org
Fri May 10 14:50:20 PDT 2024


bwendling wrote:

@apple-fcloutier:

> think that there's room to allow `__counted_by` on incomplete types so that a TU where it's complete could use it (and we have use cases where that would be handy), but our implementation doesn't support it at this time. This can be added without disruptions at a later time. FWIW, the point of bounds-checking an index is moot at least while the type is incomplete, since it's an error to dereference a pointer to an incomplete type. Aside from indexing, operations that would cast the pointer (such as `memset(x->foo, 0, some_value)`, assuming `memset(void *__sized_by(n), int, size_t n)`) would still have to be illegal when `struct foo` is incomplete because there's no way to know how many bytes we have at x->foo without `sizeof(struct foo)`.

What I'm thinking is something like:

```c
a.c:
struct foo;

struct bar {
  size_t count;
  struct foo *ptr __counted_by(count);
};

struct bar *alloc_bar(size_t num_elems) {
  struct bar *p = malloc(sizeof(bar));

  p->count = num_elems;
  p->ptr = malloc(sizeof(struct foo *) * num_elems);
  return p;
}

/* later on, or in another TU */

struct foo {
  /* fields */
};

void bork(size_t num_elems) {
  struct bar *p = alloc_bar(num_elems);

  for (size_t i = 0; i < num_elems; ++i) {
    p->ptr[i] = alloc_foo();
  }

  /* some use of p */
}
}
```

I was incorrect about `void *`. It's valid to cast any pointer to `void *` and back to the original type.

> For structs with a flexible array member, the reason is that sizeof(struct bar) is a lie. How would we reconcile, for instance, a count of 1 (implying there's like 4 bytes at x->bar) with a x->bar->a of 10 (implying that x->bar->fam[8] is in bounds)? How do we feel that x->bar[0]->fam[0] aliases with x->bar[1]->a?

It's not a lie, because the contents of a pointer don't contribute to the size of the struct containing that pointer.

https://github.com/llvm/llvm-project/pull/90786


More information about the cfe-commits mailing list