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

Reply via email to