> On Nov 1, 2023, at 11:00 AM, Martin Uecker <uec...@tugraz.at> wrote: > > 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.
Then: The size of the FAM is defined by the latest “counted_by” value before the FAM is referenced. It’s an undefined behavior when the “counted_by” value is not initialized before the FAM is referenced. > >> >> 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. Okay, -:) so, this is the point where the x.buf is referenced, and I think that replacing this reference to a call to .ACCESS_WITH_SIZE is still needed. Otherwise, the “counted_by” relationship will NOT be seen by the middle-end anymore. > >> >>> 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. Oh, I see. So, now, PTR is already an constant at FE, the replacement will be .ACCESS_WITH_SIZE( CONSTANT_ADDRESS, SIZE, ACCESS_MODE) This looks awkward…. Should we allow this? If not allowed, then the “counted_by” attribute will not work for the static initialization. > > I think it would be good to collect a list of test > cases and to include this example. Yes, I will put this into the testing case list. Qing > > Martin > >> >> Qing >>> >>> -- >>> Joseph S. Myers >>> jos...@codesourcery.com