(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wzero-length-array-bounds-2.c
       1  /* Test to verify that -Wzero-length-bounds and not -Warray-bounds is
       2     issued for accesses to interior zero-length array members that are
       3     within the bounds of the enclosing struct.
       4     { dg-do compile }
       5     { dg-options "-O2 -Wall" } */
       6  
       7  /* pr102706: disabled warnings because the now-disabled conditions for the
       8     bogus warnings to come up do not take cost analysis into account, and often
       9     come up wrong.  */
      10  /* { dg-additional-options "-Wno-stringop-overflow" } */
      11  
      12  void sink (void*);
      13  
      14  struct A { int i; };
      15  struct B { int j; struct A a[0]; };
      16  
      17  struct C
      18  {
      19    struct B b1;
      20    struct B b2;
      21  };
      22  
      23  
      24  void test_B_ref (struct B *p)
      25  {
      26    // References with negative indices are always diagnosed by -Warray-bounds
      27    // even though they could be considered the same as past the end accesses
      28    // to trailing zero-length arrays.
      29    p->a[-1].i = 0;       // { dg-warning "\\\[-Warray-bounds" }
      30    p->a[ 0].i = 0;
      31    p->a[ 1].i = 0;
      32    sink (p);
      33  
      34    p[1].a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      35    p[1].a[ 0].i = 0;
      36    p[1].a[ 1].i = 0;
      37  }
      38  
      39  
      40  void test_C_ref (struct C *p)
      41  {
      42    p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      43    p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
      44    p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
      45  
      46    // Accesses to trailing zero-length arrays are not diagnosed (should
      47    // they be?)
      48    p->b2.a[ 0].i = 0;
      49    p->b2.a[ 9].i = 0;
      50  }
      51  
      52  
      53  void test_C_decl (void)
      54  {
      55    struct C c, *p = &c;
      56  
      57    p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      58  
      59    // c.b1.a[0].i overlaps c.b2.j.
      60    p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
      61  
      62    // c.b1.a[1].i is past the end of c...
      63    p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      64    sink (p);
      65  
      66    // ...and so are references to all elements of c.b2.a
      67    p->b2.a[ 0].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      68    p->b2.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      69    sink (p);
      70  }
      71  
      72  
      73  char cbuf1[1 * sizeof (struct C)];
      74  char cbuf2[2 * sizeof (struct C)] = { };
      75  
      76  void test_C_global_buf (void)
      77  {
      78    struct C *p = (struct C*)&cbuf1;
      79  
      80    p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      81    p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
      82    p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      83    sink (p);
      84  
      85    p->b2.a[ 0].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      86    p->b2.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      87    sink (p);
      88  
      89    p = (struct C*)&cbuf2;
      90    p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      91    p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
      92    p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
      93    sink (p);
      94  
      95    p->b2.a[ 0].i = 0;    // { dg-bogus "\\\[-Wstringop-overflow" "pr102706" }
      96                          //   { xfail { vect_slp_v2si_store_align &&  { ! vect_slp_v4si_store_unalign } } }
      97    p->b2.a[ 1].i = 0;
      98    p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
      99    p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
     100    sink (p);
     101  }
     102  
     103  
     104  void test_C_local_buf (void)
     105  {
     106    char cbuf1[1 * sizeof (struct C)] = "";
     107    char cbuf2[2 * sizeof (struct C)] = { };
     108  
     109    struct C *p = (struct C*)&cbuf1;
     110  
     111    p->b1.a[-1].i = 1;     // { dg-warning "\\\[-Warray-bounds" }
     112    p->b1.a[ 0].i = 2;     // { dg-warning "\\\[-Wzero-length-bounds" }
     113    p->b1.a[ 1].i = 3;     // { dg-warning "\\\[-Warray-bounds" }
     114    sink (p);
     115  
     116    p->b2.a[ 0].i = 4;     // { dg-warning "\\\[-Warray-bounds" }
     117    p->b2.a[ 1].i = 5;     // { dg-warning "\\\[-Warray-bounds" }
     118    sink (p);
     119  
     120    p = (struct C*)&cbuf2;
     121    p->b1.a[-1].i = 6;     // { dg-warning "\\\[-Warray-bounds" }
     122    p->b1.a[ 0].i = 7;     // { dg-warning "\\\[-Wzero-length-bounds" }
     123    p->b1.a[ 1].i = 8;     // { dg-warning "\\\[-Wzero-length-bounds" }
     124    sink (p);
     125  
     126    p->b2.a[ 0].i = 9;    // { dg-bogus "\\\[-Wstringop-overflow" "pr102706" }
     127                          //   { xfail { vect_slp_v2si_store_align &&  { ! vect_slp_v4si_store_unalign } } }
     128    p->b2.a[ 1].i = 10;
     129    p->b2.a[ 2].i = 11;    // { dg-warning "\\\[-Warray-bounds" }
     130    p->b2.a[ 3].i = 12;    // { dg-warning "\\\[-Warray-bounds" }
     131    sink (p);
     132  }