On Tue, Apr 15, 2025 at 09:07:44PM +0200, Martin Uecker wrote: > Am Dienstag, dem 15.04.2025 um 14:50 +0200 schrieb Michael Matz: > > Hello, > ... > > > > struct A { > > > int *buf __counted_by(len); // 'len' *must* be in the struct. > > > int len; > > > }; > > > > ... means that we would have to implement general delayed parsing for > > expressions in C parsers. > > I have to agree with Michael. This was the main reason > we rejected the original approach. > > I also think consistency with general syntax for arrays in structs > is far more important for C than consistency for the special case of > having only one identifier in counted_by.
Okay, so I think the generally recognized way forward is with two attributes: counted_by(struct_member) and counted_by_expr(type struct_member; ...; expression) This leaves flexible array members with counted_by unchanged from current behavior. Questions I am left with: 1) When applying counted_by to pointer members, are out-of-order member declarations expected to be handled? As in, is this expected to be valid? struct foo { struct bar *p __attribute__((counted_by(count))); int count; }; 1.A) If it is _not_ valid, is it valid to use it when the member has been declared earlier? Such as: struct foo { int count; struct bar *p __attribute__((counted_by(count))); }; 1.B) If "1" isn't valid, but "1.A" is valid, I would expect that way to allow the member ordering in "1" is through counted_by_expr? For example: struct foo { struct bar *p __attribute__((counted_by_expr(int count; count))); int count; }; 1.C) If "1" isn't valid, and "1.A" isn't valid, then counted_by of pointer members must always use counted_by_expr. Is that expected? (I ask because it seems like a potentially weird case there member order forces choosing between two differently named attributes. It'd be really nice if "1" could be valid.) 2) For all counted_by of pointer members, I understand this to only be about the parsing step, not further analysis where the full sizes of all objects will need to be known. Which means that this is valid: struct bar; // empty declaration struct foo { struct bar *p __attribute__((counted_by_expr(int count; count))); int count; }; ... // defined after being referenced by counted_by_expr above struct bar { int a, b, c; struct foo *p; }; Is that correct? 3) It seems it will be possible to provide a "singleton" alias to indicate that a given pointer member is not an array of objects, but rather a pointer to a single object instance: struct bar { int a, b, c; struct foo *p __attribute__((counted_by_expr(1))); }; Is that correct? (This will be useful once we can apply counted_by to function arguments...) 4) If there are type mismatches between the counted_by_expr struct member declaration and the later actual struct member declaration, I assume that will be a hard error. For example, this would fail to compile: struct foo { struct bar *p __attribute__((counted_by_expr(int count; count))); unsigned long count; }; Is that correct? It feels like if we're already able to do this analysis, then "1" should be possible also. Perhaps I'm misunderstanding something about the parser. Thanks! -Kees -- Kees Cook