> On Dec 7, 2024, at 03:57, Martin Uecker <uec...@tugraz.at> wrote:
> 
> Am Freitag, dem 06.12.2024 um 16:13 +0000 schrieb Qing Zhao:
>> 
>>> On Dec 6, 2024, at 10:56, Martin Uecker <uec...@tugraz.at> wrote:
>>> 
>>> Am Freitag, dem 06.12.2024 um 14:16 +0000 schrieb Qing Zhao:
>>>> 
> 
> ...
> 
>>>>> 
>>>>> I think the relevant scenario is where you assign the struct and
>>>>> not a pointer to the struct, i.e. something like the following:
>>>>> 
>>>>> #include "builtin-object-size-common.h"
>>>>> 
>>>>> struct annotated {
>>>>> int b;
>>>>> int *c __attribute__ ((counted_by (b)));
>>>>> };
>>>>> 
>>>>> struct annotated __attribute__((__noinline__)) setup (int attr_count)
>>>>> {
>>>>> struct annotated p_array_annotated;
>>>>> p_array_annotated.c = (int *) malloc (sizeof (int) * attr_count);
>>>>> p_array_annotated.b = attr_count;
>>>>> 
>>>>> return p_array_annotated;
>>>>> }
>>>>> 
>>>>> 
>>>>> int main(int argc, char *argv[])
>>>>> {
>>>>> struct annotated x = setup (10);     
>>>>> int *p = x.c;
>>>>> x = setup (20);
>>>>> EXPECT(__builtin_dynamic_object_size (p, 1), 10 * sizeof (int));
>>>>> EXPECT(__builtin_dynamic_object_size (x.c, 1), 20 * sizeof (int));
>>>>> DONE ();
>>>>> }
>>>>> 
>>>> 
>>>> With the above testing case, my current implementation based on 
>>>> .ACCESS_WITH_SIZE succeed without any issue.  -:)
>>>> The design of .ACCESS_WITH_SIZE already resolved this issue.
>>> 
>>> Ok, thanks!  But I am a bit confused, because it seems it behaves 
>>> this way also for FAMs 
>>> 
>>> https://godbolt.org/z/64a6z4cna
>> 
>> The behavior of the above testing case is exactly the additional feature we 
>> provided for counted_by attribute for FAM:
>> 
>> =====
>>     One important feature of the attribute is, a reference to the
>>     flexible array member field uses the latest value assigned to the
>>     field that represents the number of the elements before that
>>     reference.  For example,
>> 
>>            p->count = val1;
>>            p->array[20] = 0;  // ref1 to p->array
>>            p->count = val2;
>>            p->array[30] = 0;  // ref2 to p->array
>> 
>>     in the above, 'ref1' uses 'val1' as the number of the elements in
>>     'p->array', and 'ref2' uses 'val2' as the number of elements in
>>     'p->array’.
>> =====
>> 
>> So, it’s the correct behavior for the counted_by attribute for FAM based on 
>> our previous discussion and agreement. 
> 
> If it is indeed that the value of p->count last stored before p->array is
> *referenced* which counts, then everything is well.  

Yes, For FAM, every “reference” to p->array will be converted as a call to 
(*.ACCESS_WITH_SIZE (p->array, &p->count, …))

The count value for p->array is  *(&p->count), which is guaranteed to be the 
last stored value of the address of p->count before the current reference to 
p->array. 

Similarly, for the pointer array,  every “reference” to p->pa will be converted 
as a call to .ACCESS_WITH_SIZE(p->pa, &p->count…). The count value of the 
pointer array p->pa is *(&p->count), which is also guaranteed to be the last 
stored value of the address of p->count before the current reference to p->pa. 

> Somehow I thought for FAMs it is the value p->count last stored before
> p->array is *accessed* (possibly indirectly via another pointer).  Probably
> it was just me being confused.
> 
>> 
>> However, as you pointed out, when the “counted_by” attribute is extended to  
>> the pointer field, this feature will be problematic.
>> And we need to add the following additional new requirement for the 
>> “counted_by” attribute of pointer field:
>> 
>> p->count and  p->array  can only be changed by changing the whole structure 
>> at the same time.
> 
> Actually, I am then not even sure we need this requirement. My point was only 
> that
> setting the whole structure at the time should work correctly, i.e. without 
> changing
> the bounds for old pointers which were stored in the struct previously.  With 
> the
> semantics  above it seems this case also works automatically.

For pointer field with counted_by attribute, if the p->count and p->pa are not 
set together when changing the whole structure, then for example: 

struct annotated {
  int b;
  int *c __attribute__ ((counted_by (b)));
};

/* note, this routine only allocate the space for the pointer array field, but 
does NOT set the counted_by field.  */
struct annotated __attribute__((__noinline__)) setup (int attr_count)
{
  struct annotated p_array_annotated;
  p_array_annotated.c = (int *) malloc (sizeof (int) * attr_count);

  return p_array_annotated;
}

int main(int argc, char *argv[])
{
  struct annotated x = setup (10);
  x.b = 10;  /* the counted_by is set here.  */
  int *p = x.c;       /* x.c’s count should be 10, which is correct.  */
  x = setup (20);
  __builtin_dynamic_object_size (x.c, 1); /* x.c’s count now should be 20, but 
it’s not set yet, the object size is unknown at this moment.  Shall we ask the 
user to always set the counted_by value when the corresponding pointer is 
changed?  */

 }

thanks.

Qing

> 
> Martin
> 
>> 
>> So for a structure that includes a pointer field with a counted_by 
>> attribute, the p->count and p->array must be updated at the same time by 
>> changing the whole structure, therefore the testing case will not be valid 
>> for pointer field, we MUST change it as  the following to make it valid for 
>> pointer field with counted_by attribute:
>> 
>> int main(int argc, char *argv[])
>> {
>> struct annotated *x = setup(10); 
>> int *p = x->c;
>> x = setup(5);
>> printf("%d\n", (int)__builtin_dynamic_object_size (p, 1));
>> printf("%d\n", (int)__builtin_dynamic_object_size (x->c, 1));
>> exit(0);
>> }
>> 
>> 
>> Hope this is clear this time -:).
> 
> 
>> 
>> Qing
>>> 
>>> and I thought this was changed, i.e. so that the bounds
>>> track the current value of b for this case.  But apparently 
>>> I was mistaken.  I am fine with the behavior as shown here.
>>> 
>>> Martin
>>> 
>>>> 
>>>> Qing
>>>>> Martin
>>>>> 
>>>>> 
>>>>> 
>>>> 
>>> 
>>> -- 
>>> Univ.-Prof. Dr. rer. nat. Martin Uecker
>>> Graz University of Technology
>>> Institute of Biomedical Imaging


Reply via email to