On 2025-07-23 13:11, Qing Zhao wrote:


On Jul 23, 2025, at 12:55, Siddhesh Poyarekar <siddh...@gotplt.org> wrote:

On 2025-07-23 11:08, Qing Zhao wrote:
We always generate a call to .ACCESS_WITH_SIZE for every f->p whatever it’s a 
reference
or a definition in C FE parser. (This is the case for FAM)

Hmm, that's not correct then and I have been misreading the code all this 
while; .ACCESS_WITH_SIZE does not make sense for a definition because the size 
in question may or may not even be correct w.r.t. the definition at the point 
that it is emitted.  I reckon this too does not come up in the FAM case because 
the FAM is not allocated separately from its containing object, whereas in the 
case of a pointer, it is allocated separately.  So...

For pointer with counted by,  Yes, if we can determine whether a f->p is an 
object reference or
an object definition, and ONLY emitting .ACCESS_WITH_SIZE for the f->p when 
it’s a object reference,
then the approach that passes the VALUE of f->p to .ACCESS_WITH_SIZE is safe.
However, I have two questions for this:
Question 1: Can we make sure this in C FE?  (Determine whether a f->p is an 
object reference of an object definition)

... it probably makes sense to focus on resolving this question to make sure 
that .ACCESS_WITH_SIZE is generated for a reference only when the reference is 
a read and not when it's a write because that's the only place where the call 
actually has a correct meaning.

Yes, this is the most important question we need to answer first to move on to 
the next step:

Whether it’s able to distinguish a reference “p->f” is a read or a write to in 
C FE?
If Yes, how to do this?

For the following example:

struct S {
int n;
int *p __attribute__((counted_by(n)));
} *f;

Int *g;

void setup (int **ptr, int count)
{
  *ptr = __builtin_malloc (sizeof (int) * count);
   g = *ptr;
};

int main ()
{
  f = __builtin_malloc (sizeof (struct S));
  setup (&f->p, 10);
}

In the above code, Is the “f->p” in the above example a read or a write when we 
are in C FE?

Then, should we emit .ACCESS_WITH_SIZE for it or not?

Strictly from a correctness perspective, this shouldn't be wrapped around a .ACCESS_FOR_SIZE. However, I don't know how, maybe someone else could help with that.

I wonder if it would make sense to make the .ACCESS_WITH_SIZE use much narrower, e.g. by emitting it only for __builtin_dynamic_object_size. That is, see if the input PTR to the function is a struct component ref with a counted_by and only then emit .ACCESS_WITH_SIZE right before the __builtin_dynamic_object_size call. One would have to walk through the input PTR to see if it reaches a component_ref with a counted_by.

Thanks,
Sid

Reply via email to