Am Mittwoch, dem 01.11.2023 um 14:47 +0000 schrieb Qing Zhao: > > > On Oct 31, 2023, at 6:14 PM, Joseph Myers <jos...@codesourcery.com> wrote: > > > > On Tue, 31 Oct 2023, Qing Zhao wrote: > > > > > 2.3 A new semantic requirement in the user documentation of "counted_by" > > > > > > For the following structure including a FAM with a counted_by attribute: > > > > > > struct A > > > { > > > size_t size; > > > char buf[] __attribute__((counted_by(size))); > > > }; > > > > > > for any object with such type: > > > > > > struct A *obj = __builtin_malloc (sizeof(struct A) + sz * sizeof(char)); > > > > > > The setting to the size field should be done before the first reference > > > to the FAM field. > > > > > > Such requirement to the user will guarantee that the first reference to > > > the FAM knows the size of the FAM. > > > > > > We need to add this additional requirement to the user document. > > > > Make sure the manual is very specific about exactly when size is > > considered to be an accurate representation of the space available for buf > > (given that, after malloc or realloc, it's going to be temporarily > > inaccurate). If the intent is that inaccurate size at such a time means > > undefined behavior, say so explicitly. > > Yes, good point. We need to define this clearly in the beginning. > We need to explicit say that > > the size of the FAM is defined by the latest “counted_by” value. And it’s an > undefined behavior when the size field is not defined when the FAM is > referenced.
It is defined by the latest "counted_by" value before x.buf is referenced, but not the latest before x.buf is dereferenced. > > Is the above good enough? > > > > > > > 2.4 Replace FAM field accesses with the new function ACCESS_WITH_SIZE > > > > > > In C FE: > > > > > > for every reference to a FAM, for example, "obj->buf" in the small > > > example, > > > check whether the corresponding FIELD_DECL has a "counted_by" attribute? > > > if YES, replace the reference to "obj->buf" with a call to > > > .ACCESS_WITH_SIZE (obj->buf, obj->size, -1); > > > > This seems plausible - but you should also consider the case of static > > initializers - remember the GNU extension for statically allocated objects > > with flexible array members (unless you're not allowing it with > > counted_by). > > > > static struct A x = { sizeof "hello", "hello" }; > > static char *y = &x.buf; > > > > I'd expect that to be valid - and unless you say such a usage is invalid, > > At this moment, I think that this should be valid. > > I,e, the following: > > struct A > { > size_t size; > char buf[] __attribute__((counted_by(size))); > }; > > static struct A x = {sizeof "hello", "hello”}; > > Should be valid, and x.size represents the number of elements of x.buf. > Both x.size and x.buf are initialized statically. Joseph is talking about the compile-time initialization of y. > > > you should avoid the replacement in such a static initializer context when > > the FAM reference is to an object with a constant address (if > > .ACCESS_WITH_SIZE would not act as an lvalue whose address is a constant > > expression; if it works fine as a constant-address lvalue, then the > > replacement would be OK). > > Then if such usage for the “counted_by” is valid, we need to replace the FAM > reference by a call to .ACCESS_WITH_SIZE as well. > Otherwise the “counted_by” relationship will be lost to the Middle end. > > With the current definition of .ACCESS_WITH_SIZE > > PTR = .ACCESS_WITH_SIZE (PTR, SIZE, ACCESS_MODE) > > Isn’t the PTR (return value of the call) a LVALUE? The question is whether we get an address constant that can be used for compile-time initialization. I think it would be good to collect a list of test cases and to include this example. Martin > > Qing > > > > -- > > Joseph S. Myers > > jos...@codesourcery.com >