Hi,  Jakub,

I re-read your other email sent last week (see below) in order to understand 
the email you sent yesterday.  -:)

And I think that I fully understand your point this time (hopefully -:), see 
below:

> On Jul 7, 2025, at 08:48, Jakub Jelinek <ja...@redhat.com> wrote:
> 
> The original use of .ACCESS_WITH_SIZE was designed for FAMs, for those
> it IMHO does the right thing, it is a pass through first arg function
> which attaches size information to the passed as well as returned pointer.
> That pointer is &FAM, so address of the containing structure plus offsetof
> of the FAM first element.
> 
> The way it is used for non-FAMs looks just wrong.
> It passes as first argument the address of the pointer, not the pointer
> itself.  

Yes, that’s the case.  
When I generate the first argument for .ACCESS_WITH_SIZE in the 8th version of 
the patch:

  tree first_param = is_fam ? array_to_pointer_conversion (loc, ref)
                     : build_unary_op (loc, ADDR_EXPR, ref, false);

For FAM, it’s just an conversion from array to pointer; however, for pointer, 
it’s the ADDR_EXPR
of the pointer

> So we have ifn used for two completely different purposes with
> different meanings, while the arguments are otherwise pretty much the same
> (or how do you uniquely distinguish the cases where it provides object
> size for what it returns vs. where it provides object size for what the
> pointer it returns points to).

Yes, this is true. And we need to distinguish this two cases in the IFN. 

>  That is like the spaghetti code in certain
> middle end warnings.  For warnings it is really bad, for code generation
> decisions it is a fatal design flaw.
> 
> So, either you need a different ifn, or add some flag in bitfield
> that clearly distinguishes the 2 cases, or different number of arguments,

How about add a new flag to distinguish these two cases, and put it to the 3th 
argument:

   ACCESS_WITH_SIZE (REF_TO_OBJ, REF_TO_SIZE,
                     TYPE_OF_SIZE + ACCESS_MODE + IS_POINTER, TYPE_SIZE_UNIT 
for element)
   which returns the REF_TO_OBJ same as the 1st argument;

   1st argument REF_TO_OBJ: The reference to the object when IS_POINTER is 
false;
                                                   The address of the reference 
to the object when IS_POINTER is true;
   2nd argument REF_TO_SIZE: The reference to the size of the object,
   3rd argument TYPE_OF_SIZE + ACCESS_MODE + IS_POINTER An integer constant 
with a pointer
     TYPE.
     The pointee TYPE of the pointer TYPE is the TYPE of the object referenced
        by REF_TO_SIZE.
     The integer constant value represents the ACCESS_MODE + IS_POINTER:
        00: none
        01: read_only
        10: write_only
        11: read_write
       100:  IS_POINTER

   4th argument: The TYPE_SIZE_UNIT of the element TYPE of the array.

Thanks.

Qing

> or perhaps most easily, why do the dereference at all?
> When I have
>  struct U { int n; int fam[n] __attribute__((counted_by (n))); } *u;
> continue passing &u->fam as first argument and &u->n as second, while for
>  struct S {
>    int n;
>    int (*p)[n] __attribute__((counted_by(n)));
>  } *f;
> don't pass &f->p to the builtin but pass f->p.  You are providing size
> for f->p pointer, not for &f->p pointer, while for FAM it is for &u->fam
> pointer.  The second argument would be &f->n.
> 
> So, my recommendation would be to revert the counted_by GCC 16 series,
> rework it and submit again.  Unless you can fix it up in a day or two.
> 
> Jakub
> 

Reply via email to