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

--- Comment #3 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
Warray-bounds-4.C is about missed warning on array bounds. It also goes back
with -fno-ipa-sra
b.C: In function ‘int main()’:
b.C:25:27: warning: array subscript 0 is above array bounds of ‘char [0]’
[-Warray-bounds]
   25 |   FixedString() { contents[0] = '\0'; } // { dg-warning "above array
bounds" }
      |                   ~~~~~~~~^

With -fno-ipa-sra we get in vrp:
main ()
{
  const struct FixedString empty;

  <bb 2> [local count: 1073741824]:
  MEM[(struct FixedString *)&empty] ={v} {CLOBBER};
  MEM[(struct FixedString *)&empty].D.2435._vptr.String = &MEM <int (*) ()[8]>
[(void *)&_ZTV11FixedStringILm0EE + 16B];
  MEM[(struct FixedString *)&empty].contents[0] = 0;
  print_length (&empty.D.2435);
  empty ={v} {CLOBBER};
  empty ={v} {CLOBBER};
  return 0;

}

while with ipa-sra decides to to SRA
String::~String (struct String * const this)
{
  <bb 2> :
  *this_3(D) ={v} {CLOBBER};
  return;

}
again it does not choose to SRA all those functions.
this makes us to get the following main at the vrp time:
main ()
{
  const struct FixedString empty;

  <bb 2> [local count: 1073741824]:
  MEM[(int (*) () * *)&empty] = &MEM <int (*) ()[8]> [(void
*)&_ZTV11FixedStringILm0EE + 16B];
  MEM[(char *)&empty + 8B] = 0;
  print_length (&empty.D.2435);
  empty ={v} {CLOBBER};
  empty ={v} {CLOBBER};
  return 0;

}
So this time it simply looks like we removed store to contents as dead
bypassing the warning. This store is taken away by IPA-SRA too:

We ISRA:
FixedString<0>::_ZN11FixedStringILm0EEC1Ev.isra.0 (int (*) () * * ISRA.10, char
* ISRA.11)
{                                                                               
  struct FixedString * const this;                                              
  struct FixedString * const this;                                              

  <bb 3> :                                                                      

  <bb 2> :                                                                      
  *ISRA.10_6(D) = 0B;                                                           
  *ISRA.10_6(D) = &MEM <int (*) ()[8]> [(void *)&_ZTV11FixedStringILm0EE +
16B];
  *ISRA.11_7(D) = 0;                                                            
  return;                                                                       

}                                                                               
where *ISRA.11_7(D) = 0 used to be the out of bounds array store.
Now it happens by
FixedString<0>::_ZN11FixedStringILm0EEC1Ev.isra.0 (&empty, &MEM[(char *)&empty
+ 8B]);

Reply via email to