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 >