[clang] [Clang][Sema] Allow counted_by on void* in GNU mode (PR #164737)
Kees Cook via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 23 23:09:08 PDT 2025
kees wrote:
> > For `counted_by` to be usable in Linux, it needs `sized_by` behavior for `void *` members. Putting this behind the GNU extension which also covers `void *` arithmetic should be a reasonable compromise.
>
> I didn't quite get the context for why this is the case - maybe I missed something. If a user can write:
>
> ```
> struct with_counted_by_void {
> int count;
> void* buf __counted_by(count);
> };
> ```
>
> why would they not be able to instead write this?
>
> ```
> struct with_sized_by_void {
> int size;
> void* buf __sized_by(size);
> };
> ```
Please know that I'm not trying to be difficult with this reply; I'm just trying to state the reality of the situation: because they(we) just will not. The Linux developer community is extraordinarily [opinionated](https://lore.kernel.org/lkml/20251021095447.GL3245006@noisy.programming.kicks-ass.net/) about these kinds of things and from their(our) perspective, `void *` points to an incomplete type whose allocation size is measured in bytes and always has. And `counted_by` is seen as counting elements which makes `sized_by` redundant. They(we) do not want 2 different spellings for doing conceptually the same thing. (In the same linked thread you'll see I am even getting push back for a versioned macro for flexible arrays vs pointer members, which is needed to handle the compiler version skew between `counted_by` coverage of those two cases.)
Since I have no preprocessor way to interrogate the type of the member when applying an attribute, I have no way to make Linux's `__counted_by` macro hide the implementation details. So, to make this work for Linux and retain the intended strict behavior, we can control it with a toggle. And since `void *ptr = foo + 1` is valid under the GNU extensions, that seems the clear toggle for it.
Alternatively, if there were some other attribute name (strawman: `alloc_elements`) that internally used `counted_by` for non-`void *` and used `sized_by` for `void *` members, I could trivially hide that behind the `__counted_by` macro. What is critically needed for Linux to adopt this is having a single spelling for "the number of elements of this pointer is counted by this other member". Or just convert `counted_by` into `sized_by` with no need for another spelling (i.e. I could nudge this patch slightly so that `CountAttributedType::SizedBy` gets set earlier in Sema and then ` CodeGenFunction::emitCountedByPointerSize` would need no changes, etc.)
I just need to find a way to keep both camps happy: both have legitimate reasons for why they want things the way they do, so I just need a knob to select between them (without compromising either side's implementation details).
https://github.com/llvm/llvm-project/pull/164737
More information about the cfe-commits
mailing list