https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123160

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2026-06-16

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
In reply to Andrew Macleod from comment #6)
> Here's a short testcase which shows that pointer_plus is not being folded
> very well, and causes incorrect code at -O2.
> 
> struct A
> {
>   char a[10];
>   char c[10];
> } a;
> 
> extern void dead1 (void);
> extern void dead2 (void);
> 
> int
> main (void)
> {
>   void *r = &a.a[6];
>   if (__builtin_object_size (r, 3) != sizeof (a.a) - 6)
>     dead1 ();
>   void *r2 = &a.a[4] + 2;
>   if (__builtin_object_size (r2, 3) != sizeof (a.a) - 6)
>     dead2 ();
> }
> 
> Neither dead1() nor dead2() should be called, but the program produced is:
> 
> int main ()
> {
>   <bb 2> [local count: 1073741824]:
>   dead2 ();
>   return 0;
> }
> 
> Visiting statement:
> r_5 = &a.a[6];
> which is likely CONSTANT
> Lattice value changed to CONSTANT &a.a[6].  Adding SSA edges to worklist.
> marking stmt to be not simulated again
> 
> Visiting statement:
> _11 = __builtin_object_size (r_5, 3);
> which is likely CONSTANT
> Lattice value changed to CONSTANT 4. 
> 
> vs
> 
> Visiting statement:
> r2_8 = &a.a[4] + 2;
> which is likely CONSTANT
> Lattice value changed to CONSTANT &MEM <char> [(void *)&a + 6B].  Adding SSA
> edges to worklist.
> marking stmt to be not simulated again

It's specifically gimple_fold_stmt_to_constant_1 that choses a GIMPLE
representation for the invariant this resembles which is quite important.
You could say it's lack of a proper representation of the access path
in the address, but we've been there before (and splat some PROP_objsz
checks everywhere).

Adding a cfun->curr_properties & PROP_objsz guard to this transform
will probably fix this case, but as said, not propagating address
constants early is going to be detrimental.

Just to throw in an idea to preserve the access path, we could add a
OFFSET_REF tcc_reference handled_component_p, so &a.a[4] + 2 becomes
&a.a[4].<offset_ref 2>.  Alternatively hack up COMPONENT_REF to accept
a NULL FIELD_DECL with populated operand 2 and "standard" DECL_OFFSET_ALIGN
(BITS_PER_UNIT).  It'll get interesting to then make sure to contract
adjacent OFFSET_REFs and eventually get rid of those after objsz runs.
  • [Bug tree-optimization/123160] ... rguenth at gcc dot gnu.org via Gcc-bugs

Reply via email to