On Thu, Nov 2, 2023 at 9:27 AM Jakub Jelinek <ja...@redhat.com> wrote: > > On Thu, Nov 02, 2023 at 08:57:36AM +0100, Richard Biener wrote: > > You probably want to specify that when a pointer to the array is taken the > > pointer has to be to the first array element (or do we want to mangle the > > 'size' accordingly for the instrumentation?). You also want to specify that > > the 'size' associated with such pointer is assumed to be unchanging and > > after changing the size such pointer has to be re-obtained. Plus that > > changes to the allocated object/size have to be performed through an > > lvalue where the containing type and thus the 'counted_by' attribute is > > visible. That is, > > > > size_t *s = &a.size; > > *s = 1; > > > > is invoking undefined behavior, likewise modifying 'buf' (makes it a bit > > awkward since for example that wouldn't support using posix_memalign > > for allocation, though aligned_alloc would be fine). > > Depends on what behavior we want to guarantee and what kind of price we want > to pay for it. If the size is .ACCESS_WITH_SIZE operand, the size used in > __bdos will be whatever counted_by size an array had upon taking address of > the array, wherever that happens in the program. And while we can CSE > the calls, they'd be CSEd only if they have the same size. > > Or, if we want to pay further price, .ACCESS_WITH_SIZE could take as one of > the arguments not the size value, but its address. Then at __bdos time > we would dereference that pointer to get the size. > So, > struct S { int a; char b __attribute__((counted_by (a))) []; }; > struct S s; > s.a = 5; > char *p = &s.b[2]; > int i1 = __builtin_dynamic_object_size (p, 0); > s.a = 3; > int i2 = __builtin_dynamic_object_size (p, 0); > would then yield 3 and 1 rather than 3 and 3.
I fail to see how we can get the __builtin_dynamic_object_size call data dependent on s.a, thus avoid re-ordering or even DSE of the store. Basically the model is that __builtin_dynamic_object_size will get you the size at the point 'p' was formed from something that "last" had the container with the counted_by attribute visible (plus adjustments to 'p' inbetween that we are able to track). s.a = 5; char *p = &a.b[0]; will get you '5' as size, char *p = &a.b[0]; s.a = 7; will get you whatever was in 's.a' at the point of the address taking, s.a = 7 will _not_ be honored for __builtin_dynamic_object_size calls on 'p'. > But dunno if we wouldn't > need to drop leaf attribute from __bdos to make that work, that would be > I think a significant case against doing that, because while in all the > current plans one just pay code performance price when using counted_by > attribute, even when not using __bdos for it, if we had to make __bdos > non-leaf we'd pay extra price even when nobody is using that attribute > just in -D_FORTIFY_SOURCE=3 / -fhardened compilations, which is how > several distros build basically everything. > > Jakub >