(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
Wstringop-overflow-2.c
       1  /* PR middle-end/91458 - inconsistent warning for writing past the end
       2     of an array member
       3     { dg-do compile }
       4     { dg-options "-O2 -Wall -Wno-array-bounds -fno-ipa-icf" } */
       5  
       6  void sink (void*);
       7  
       8  // Exercise flexible array members.
       9  
      10  struct Ax
      11  {
      12    char n;
      13    char a[];                     // { dg-message "destination object" "note" }
      14  };
      15  
      16  // Verify warning for a definition with no initializer.
      17  struct Ax ax_;
      18  
      19  void gax_ (void)
      20  {
      21    ax_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
      22    ax_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
      23    ax_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
      24  }
      25  
      26  // Verify warning for access to a definition with an initializer that doesn't
      27  // initialize the flexible array member.
      28  struct Ax ax0 = { 0 };
      29  
      30  void gax0 (void)
      31  {
      32    ax0.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
      33    ax0.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
      34    ax0.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
      35  }
      36  
      37  // Verify warning for access to a definition with an initializer that
      38  // initializes the flexible array member to empty.
      39  struct Ax ax0_ = { 0, { } };
      40  
      41  void gax0_ (void)
      42  {
      43    ax0_.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" }
      44    ax0_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
      45    ax0_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
      46  }
      47  
      48  // Verify warning for out-of-bounds accesses to a definition with
      49  // an initializer.
      50  struct Ax ax1 = { 1, { 0 } };
      51  
      52  void gax1 (void)
      53  {
      54    ax1.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store_unalign } } }
      55    ax1.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
      56    ax1.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
      57  }
      58  
      59  struct Ax ax2 = { 2, { 1, 0 } };
      60  
      61  void gax2 (void)
      62  {
      63    ax2.a[0] = 0;
      64    ax2.a[1] = 1;
      65    ax2.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
      66  }
      67  
      68  
      69  // Verify no warning for an unknown struct object.
      70  void gaxp (struct Ax *p)
      71  {
      72    p->a[0] = 0;
      73    p->a[3] = 3;
      74    p->a[9] = 9;
      75  }
      76  
      77  
      78  // Verify no warning for an extern struct object whose array may be
      79  // initialized to any number of elements.
      80  extern struct Ax axx;
      81  
      82  void gaxx (void)
      83  {
      84    axx.a[0] = 0;
      85    axx.a[3] = 3;
      86    axx.a[9] = 9;
      87  }
      88  
      89  // Exercise zero-length array members.
      90  
      91  struct A0
      92  {
      93    char n;
      94    char a[0];                    // { dg-message "destination object" "note" }
      95  };
      96  
      97  // Verify warning for a definition with no initializer.
      98  struct A0 a0_;
      99  
     100  void ga0_ (void)
     101  {
     102    a0_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
     103    a0_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     104    a0_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
     105  }
     106  
     107  // Verify warning for access to a definition with an initializer that doesn't
     108  // initialize the flexible array member.
     109  struct A0 a00 = { 0 };
     110  
     111  void ga00 (void)
     112  {
     113    a00.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
     114    a00.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     115    a00.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
     116  }
     117  
     118  // Verify warning for access to a definition with an initializer that
     119  // initializes the flexible array member to empty.
     120  struct A0 a00_ = { 0, { } };
     121  
     122  void ga00_ (void)
     123  {
     124    a00_.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" }
     125    a00_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     126    a00_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
     127  }
     128  
     129  // The following are rejected with
     130  //   error: too many initializers for 'char [0]'
     131  // A0 a01 = { 1, { 0 } };
     132  // A0 a02 = { 2, { 1, 0 } };
     133  
     134  
     135  // Verify no warning for an unknown struct object.
     136  void ga0p (struct A0 *p)
     137  {
     138    p->a[0] = 0;
     139    p->a[3] = 3;
     140    p->a[9] = 9;
     141  }
     142  
     143  
     144  // Verify warning for an extern struct object which (unlike a true
     145  // flexible array member) may not be initialized.
     146  extern struct A0 a0x;
     147  
     148  void ga0x (void)
     149  {
     150    a0x.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
     151    a0x.a[3] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
     152    a0x.a[9] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
     153  }
     154  
     155  
     156  // Exercise trailing one-element array members.
     157  
     158  struct A1
     159  {
     160    char n;
     161    char a[1];                    // { dg-message "destination object" "note" }
     162  };
     163  
     164  // Verify warning for a definition with no initializer.
     165  struct A1 a1_;
     166  
     167  void ga1_ (void)
     168  {
     169    a1_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store_unalign } } }
     170    a1_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     171    a1_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
     172  
     173    struct A1 a;
     174    a.a[0] = 0;                   // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store_unalign } } }
     175    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     176    a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
     177    sink (&a);
     178  }
     179  
     180  // Verify warning for access to a definition with an initializer that doesn't
     181  // initialize the one-element array member.
     182  struct A1 a1__ = { 0 };
     183  
     184  void ga1__ (void)
     185  {
     186    a1__.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store_unalign } } }
     187    a1__.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     188    a1__.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
     189  
     190    struct A1 a = { 1 };
     191    a.a[0] = 0;
     192    a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
     193    a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store_align } } }
     194    sink (&a);
     195  }
     196  
     197  // Verify warning for access to a definition with an initializer that
     198  // initializes the one-element array member to empty.
     199  struct A1 a1_0 = { 0, { } };
     200  
     201  void ga1_0_ (void)
     202  {
     203    a1_0.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store_unalign } } }
     204    a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     205    a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
     206  
     207    struct A1 a = { 1, { } };
     208    a.a[0] = 0;
     209    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
     210    a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store_align } } }
     211    sink (&a);
     212  }
     213  
     214  // Verify warning for access to a definition with an initializer that
     215  // initializes the one-element array member.
     216  struct A1 a1_1 = { 0, { 1 } };
     217  
     218  void ga1_1 (void)
     219  {
     220    a1_1.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store_unalign } } }
     221    a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     222    a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
     223  
     224    struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store_align } } }
     225    a.a[0] = 0;
     226    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store_align } } }
     227    a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store_align } } }
     228    sink (&a);
     229  }
     230  
     231  
     232  // Verify no warning for an unknown struct object.
     233  void ga1p (struct A1 *p)
     234  {
     235    p->a[0] = 0;
     236    p->a[3] = 3;
     237    p->a[9] = 9;
     238  }
     239  
     240  
     241  // Verify warning for an extern struct object.  Similar to the zero-length
     242  // array case, a one-element trailing array can be initialized to at most
     243  // a single element.
     244  extern struct A1 a1x;
     245  
     246  void ga1x (void)
     247  {
     248    a1x.a[0] = 0;
     249    a1x.a[3] = 3;                 // { dg-warning "\\\[-Wstringop-overflow" }
     250    a1x.a[9] = 9;                 // { dg-warning "\\\[-Wstringop-overflow" }
     251  }
     252  
     253  // Exercise interior one-element array members (verify they're not
     254  // treated as trailing.
     255  
     256  struct A1i
     257  {
     258    char n;
     259    char a[1];                    // { dg-message "destination object" }
     260    char x;
     261  };
     262  
     263  // Verify warning for a definition with no initializer.
     264  struct A1i a1i_;
     265  
     266  void ga1i_ (void)
     267  {
     268    a1i_.a[0] = 0;
     269    a1i_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     270    a1i_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
     271  
     272    struct A1i a;
     273    a.a[0] = 1;
     274    a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     275    a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" }
     276    sink (&a);
     277  }
     278  
     279  // Verify warning for access to a definition with an initializer that doesn't
     280  // initialize the one-element array member.
     281  struct A1i a1i__ = { 0 };
     282  
     283  void ga1i__ (void)
     284  {
     285    a1i__.a[0] = 0;
     286    a1i__.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     287    a1i__.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
     288  
     289    struct A1i a = { 0 };
     290    a.a[0] = 0;
     291    a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
     292    a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store_align } } }
     293    sink (&a);
     294  }
     295  
     296  // Verify warning for access to a definition with an initializer that
     297  // initializes the one-element array member to empty.
     298  struct A1 a1i_0 = { 0, { } };
     299  
     300  void ga1i_0_ (void)
     301  {
     302    a1i_0.a[0] = 0;               // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store_unalign } } }
     303    a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     304    a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
     305  
     306    struct A1 a = { 0, { } };
     307    a.a[0] = 0;
     308    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
     309    a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store_align } } }
     310    sink (&a);
     311  }
     312  
     313  // Verify warning for access to a definition with an initializer that
     314  // initializes the one-element array member.
     315  struct A1 a1i_1 = { 0, { 1 } };
     316  
     317  void ga1i_1 (void)
     318  {
     319    a1i_1.a[0] = 0;               // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store_unalign } } }
     320    a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store_unalign } } }
     321    a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
     322  
     323    struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { target { vect_slp_v4qi_store_align } } }
     324    a.a[0] = 1;
     325    a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v4qi_store_align } } }
     326    a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v4qi_store_align } } }
     327    sink (&a);
     328  }
     329  
     330  
     331  // Verify no warning for an unknown struct object.
     332  void ga1ip (struct A1i *p)
     333  {
     334    p->a[0] = 0;
     335    p->a[3] = 3;                  // { dg-warning "\\\[-Wstringop-overflow" }
     336    p->a[9] = 9;                  // { dg-warning "\\\[-Wstringop-overflow" }
     337  }
     338  
     339  
     340  // Verify no warning for an extern struct object.
     341  extern struct A1i a1ix;
     342  
     343  void ga1ix (void)
     344  {
     345    a1ix.a[0] = 0;
     346    a1ix.a[3] = 3;                 // { dg-warning "\\\[-Wstringop-overflow" }
     347    a1ix.a[9] = 9;                 // { dg-warning "\\\[-Wstringop-overflow" }
     348  }