On Sat, Jul 5, 2025 at 2:10 PM Siddhesh Poyarekar <siddh...@gotplt.org> wrote: > > 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.
Yes. That's what I'd have expected happens? I thought .ACCESS_WITH_SIZE annotates the pointer, it doesn't perform an access itself - correct? Where is .ACCESS_WITH_SIZE documented? I can't find it documented in the internals manual, internal-fn.def has /* A function to associate the access size and access mode information with the corresponding reference to an object. It only reads from the 2nd argument. */ DEF_INTERNAL_FN (ACCESS_WITH_SIZE, ECF_PURE | ECF_LEAF | ECF_NOTHROW, NULL) that suggests .ACCESS_WITH_SIZE performs a read on the size. It doesn't say what the function returns at all. Is the above only happening when using __builtin_dynamic_object_size (_1, 1) or also when performing an actual access like return a->c[i]; ? > 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