On 2025-07-05 07:23, Richard Biener wrote:
OK, should I revert right away or can we wait till Qing returns on Monday?
Monday is OK with me.
Thanks, so I thought about this some more and I think when I said in
bugzilla:
"In fact, maybe the .ACCESS_WITH_SIZE handling in objsz probably needs
improvement to express it better, but that's an orthogonal matter."
I had the right intuition but I was completely wrong about it being an
orthogonal matter. That *is* the issue and it only becomes relevant
when the member being described is a pointer and not a FAM. e.g. for
the following:
```
struct A
{
int count;
#ifndef PTR
char c[] __attribute ((__counted_by__ (count)));
#else
char *c __attribute ((__counted_by__ (count)));
#endif
} a;
unsigned long
foo (struct A *a)
{
return __builtin_dynamic_object_size (a->c, 1);
}
```
the .ACCESS_WITH_SIZE abstraction records the size using &a->c:
_2 = &a->c;
_3 = &a->count;
_1 = .ACCESS_WITH_SIZE (_2, _3, 1, 0, -1, 0B);
D.2964 = __builtin_dynamic_object_size (_1, 1);
this doesn't make a difference when c is an array since the & operator
is a nop. However when the same is applied to the pointer a->c, it
becomes an additional dereference, which changes the semantic meaning:
_2 = &a->c;
_3 = &a->count;
_1 = .ACCESS_WITH_SIZE (_2, _3, 1, 0, -1, 0B);
_4 = *_1;
D.2964 = __builtin_dynamic_object_size (_4, 1);
Since the intent of the .ACCESS_WITH_SIZE was to associate the storage
of count with c to prevent reordering, maybe the semantically correct
solution here is that when c is a pointer, the frontend emits:
_2 = a->c;
_3 = &a->count;
_1 = .ACCESS_WITH_SIZE (_2, _3, 1, 0, -1, 0B);
D.2964 = __builtin_dynamic_object_size (_, 1);
so a->c instead of &a->c. In fact, maybe taking the address of a->c
doesn't make sense in general and .ACCESS_WITH_SIZE should always be the
above even for FAM? Does that sound correct?
Sid