On Thu, Nov 2, 2023 at 11:40 AM Jakub Jelinek <ja...@redhat.com> wrote: > > On Thu, Nov 02, 2023 at 11:18:09AM +0100, Richard Biener wrote: > > > 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. > > If &s.b[2] is lowered as > sz_1 = s.a; > tmp_2 = .ACCESS_WITH_SIZE (&s.b[0], sz_1); > p_3 = &tmp_2[2]; > then sure, there is no way, you get the size from that point. > tree-object-size.cc tracking then determines that in a particular > case the pointer is size associated with sz_1 and use that value > as the size (with the usual adjustments for pointer arithmetics and the > like). > > What I meant is to emit > tmp_4 = .ACCESS_WITH_SIZE (&s.b[0], &s.a, (typeof (&s.a)) 0); > p_5 = &tmp_4[2]; > i.e. don't associate the pointer with a value of the size, but with > an address where to find the size (plus how large it is), basically escape > pointer to the size at that point. And __builtin_dynamic_object_size is pure, > so supposedly it can depend on what the escaped pointer points to.
Well, yeah - that would work but depend on .ACCESS_WITH_SIZE being an escape point (quite bad IMHO) and __builtin_dynamic_object_size being non-const (that's probably not too bad). > We'd see that a particular pointer is size associated with &s.a address > and would use that address cast to the type of the third argument (to > preserve the exact pointer type on INTEGER_CST, though not sure, wouldn't > VN CSE it anyway if one has say > union U { struct S { int a; char b __attribute__((counted_by (a))) []; } s; > struct T { char c, d, e, f; char g __attribute__((counted_by (c))) > []; } t; }; > and > .ACCESS_WITH_SIZE (&v.s.b[0], &v.s.a, (int *) 0); > ... > .ACCESS_WITH_SIZE (&v.t.g[0], &v.t.c, (int *) 0); > ? We'd probably CSE that - the usual issue of address-with-same-value. > It would mean though that counted_by wouldn't be allowed to be a > bit-field... Yup. We could also pass a pointer to the container though, that's good enough for the escape, and pass the size by value in addition to that. > Jakub >