(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overflow-39.c
       1  /* PR middle-end/95667 - unintended warning for memset writing across multiple
       2     members
       3     { dg-do compile }
       4     { dg-options "-O2 -Wall" }
       5     { dg-require-effective-target alloca } */
       6  
       7  extern void sink (void*);
       8  
       9  struct S1 { char a[3], b[5]; };
      10  
      11  void warn_strcpy_s1 (void)
      12  {
      13    struct S1 *p = __builtin_malloc (sizeof *p);
      14    char s[] = "1234567";
      15    __builtin_strcpy (p->a, s);         // { dg-warning "\\\[-Wstringop-overflow" }
      16    sink (p);
      17  }
      18  
      19  void nowarn_memset_s1 (void)
      20  {
      21    struct S1 *p = __builtin_malloc (sizeof *p);
      22    __builtin_memset (p->a, 0, 8);      // { dg-bogus "\\\[-Wstringop-overflow" }
      23    sink (p);
      24  }
      25  
      26  struct S2 { char a[2], b[2][2], c[3]; };
      27  
      28  void nowarn_memset_s2 (void)
      29  {
      30    struct S2 *p = __builtin_malloc (sizeof *p);
      31  
      32    __builtin_memset (p->a, 0, sizeof *p);
      33    sink (p);
      34  
      35    __builtin_memset (p->b, 0, 7);
      36    sink (p);
      37  
      38    __builtin_memset (&p->b[0], 0, 7);
      39    sink (p);
      40  
      41    __builtin_memset (&p->b[1], 0, 5);
      42    sink (p);
      43  
      44    __builtin_memset (&p->b[0][0], 0, 7);
      45    sink (p);
      46  
      47    __builtin_memset (&p->b[0][1], 0, 6);
      48    sink (p);
      49  
      50    __builtin_memset (&p->b[1][0], 0, 5);
      51    sink (p);
      52  
      53    __builtin_memset (&p->b[1][1], 0, 4);
      54    sink (p);
      55  }
      56  
      57  void warn_memset_s2 (void)
      58  {
      59    const unsigned n = sizeof (struct S2);
      60    struct S2 *p = __builtin_malloc (n);
      61  
      62    /* These should trigger -Wstringop-overflow rather than -Warray-bounds
      63       but the main purpose of the test is to verify the absence of warnings
      64       above so the exact warning for these overflwing calls isn't important
      65       here.  */
      66  
      67    __builtin_memset (p->a, 0, n + 1);  // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
      68    sink (p);
      69  
      70    __builtin_memset (p->b, 0, 8);      // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
      71    sink (p);
      72  
      73    __builtin_memset (&p->b[0], 0, 8);  // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
      74    sink (p);
      75  
      76    __builtin_memset (&p->b[0][0], 0, 8); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
      77    sink (p);
      78  
      79    __builtin_memset (&p->b[1], 0, 6);  // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
      80    sink (p);
      81  
      82    __builtin_memset (&p->b[0][1], 0, 7); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
      83    sink (p);
      84  }
      85  
      86  void nowarn_vl_struct (unsigned n)
      87  {
      88    if (n < 3 || 5 < n)
      89      n = 3;
      90  
      91    struct V { char a[3], b[n], c[7]; } v;
      92  
      93    __builtin_memset (v.a, 0, 15);
      94    sink (&v);
      95  
      96    __builtin_memset (v.b, 0, 12);
      97    sink (&v);
      98  
      99    __builtin_memset (v.c, 0, 7);
     100    sink (&v);
     101  
     102    __builtin_memset (v.a, 0, 16);      // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
     103    sink (&v);
     104  
     105    __builtin_memset (v.b, 0, 13);      // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" }
     106    sink (&v);
     107  
     108    /* The &V.C argument is represented as a variable offset from
     109       the beginning of the allocated object and there's no good
     110       way to figure out from its variable offset that it's base
     111       is the C member:
     112         s.1_12 = __builtin_alloca_with_align (prephitmp_24, 8);
     113         _9 = s.1_12 + prephitmp_27;
     114         __builtin_memset (_9, 0, 2);
     115    */
     116  
     117    __builtin_memset (v.c, 0, 8);       // { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr?????" { xfail *-*-* } }
     118    sink (&v);
     119  }