(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
builtin-stringop-chk-9.c
       1  /* PR middle-end/82646 - bogus -Wstringop-overflow with -D_FORTIFY_SOURCE=2
       2     on strncpy with range to a member array
       3     { dg-do compile }
       4     { dg-options "-O2 -Wstringop-overflow -ftrack-macro-expansion=0" } */
       5  
       6  #define bos(p)   __builtin_object_size (p, 1)
       7  
       8  struct S {
       9    char a[5];
      10    void (*pf)(void);
      11  };
      12  
      13  /* Verify that none of the string function calls below triggers a warning.  */
      14  
      15  char* test_stpncpy_const_nowarn (struct S *p)
      16  {
      17    int n = sizeof p->a;
      18  
      19    return __builtin_stpncpy (p->a, "123456", n);
      20  }
      21  
      22  char* test_strncpy_const_nowarn (struct S *p)
      23  {
      24    int n = sizeof p->a;
      25  
      26    return __builtin_strncpy (p->a, "1234567", n);
      27  }
      28  
      29  char* test_stpncpy_chk_const_nowarn (struct S *p)
      30  {
      31    int n = sizeof p->a;
      32  
      33    return __builtin___stpncpy_chk (p->a, "12345678", n, bos (p->a));
      34  }
      35  
      36  char* test_strncpy_chk_const_nowarn (struct S *p)
      37  {
      38    int n = sizeof p->a;
      39  
      40    return __builtin___strncpy_chk (p->a, "123456789", n, bos (p->a));
      41  }
      42  
      43  
      44  char* test_stpncpy_range_nowarn (struct S *p, int n)
      45  {
      46    if (n < sizeof p->a)
      47      n = sizeof p->a;
      48  
      49    return __builtin_stpncpy (p->a, "123456", n);
      50  }
      51  
      52  char* test_strncpy_range_nowarn (struct S *p, int n)
      53  {
      54    if (n < sizeof p->a)
      55      n = sizeof p->a;
      56  
      57    return __builtin_strncpy (p->a, "1234567", n);
      58  }
      59  
      60  char* test_stpncpy_chk_range_nowarn (struct S *p, int n)
      61  {
      62    if (n < sizeof p->a)
      63      n = sizeof p->a;
      64  
      65    return __builtin___stpncpy_chk (p->a, "12345678", n, bos (p->a));   /* { dg-bogus "\\\[-Wstringop-overflow=]" } */
      66  }
      67  
      68  char* test_strncpy_chk_range_nowarn (struct S *p, int n)
      69  {
      70    if (n < sizeof p->a)
      71      n = sizeof p->a;
      72  
      73    return __builtin___strncpy_chk (p->a, "123456789", n, bos (p->a));  /* { dg-bogus "\\\[-Wstringop-overflow=]" } */
      74  }
      75  
      76  
      77  /* Verify that all of the string function calls below trigger a warning.  */
      78  
      79  char* test_stpncpy_const_warn (struct S *p)
      80  {
      81    int n = sizeof p->a;
      82  
      83    ++n;
      84  
      85    return __builtin_stpncpy (p->a, "123456", n);                       /* { dg-warning "\\\[-Wstringop-overflow=]" } */
      86  }
      87  
      88  char* test_strncpy_const_warn (struct S *p)
      89  {
      90    int n = sizeof p->a;
      91  
      92    /* A call to strncpy() with a known string and small bound is folded
      93       into memcpy() which defeats the warning in this case since memcpy
      94       uses Object Size Type 0, i.e., the largest object that p->a may
      95       be a part of.  Use a larger bound to get around this here.  */
      96    n += 11;
      97  
      98    return __builtin_strncpy (p->a, "1234567", n);                      /* { dg-warning "\\\[-Wstringop-overflow=]" } */
      99  }
     100  
     101  char* test_stpncpy_chk_const_warn (struct S *p)
     102  {
     103    int n = sizeof p->a;
     104  
     105    ++n;
     106  
     107    return __builtin___stpncpy_chk (p->a, "12345678", n, bos (p->a));   /* { dg-warning "\\\[-Wstringop-overflow=]" } */
     108  }
     109  
     110  char* test_strncpy_chk_const_warn (struct S *p)
     111  {
     112    int n = sizeof p->a;
     113  
     114    ++n;
     115  
     116    return __builtin___strncpy_chk (p->a, "123456789", n, bos (p->a));  /* { dg-warning "\\\[-Wstringop-overflow=]" } */
     117  }
     118  
     119  
     120  char* test_stpncpy_range_warn (struct S *p, int n)
     121  {
     122    if (n < sizeof p->a + 1)
     123      n = sizeof p->a + 1;
     124  
     125    return __builtin_stpncpy (p->a, "123456", n);                       /* { dg-warning "\\\[-Wstringop-overflow=]" } */
     126  }
     127  
     128  char* test_strncpy_range_warn (struct S *p, int n)
     129  {
     130    if (n < sizeof p->a + 1)
     131      n = sizeof p->a + 1;
     132  
     133    return __builtin_strncpy (p->a, "1234567", n);                      /* { dg-warning "\\\[-Wstringop-overflow=]" } */
     134  }
     135  
     136  char* test_stpncpy_chk_range_warn (struct S *p, int n)
     137  {
     138    if (n < sizeof p->a + 1)
     139      n = sizeof p->a + 1;
     140  
     141    return __builtin___stpncpy_chk (p->a, "12345678", n, bos (p->a));   /* { dg-warning "\\\[-Wstringop-overflow=]" } */
     142  }
     143  
     144  char* test_strncpy_chk_range_warn (struct S *p, int n)
     145  {
     146    if (n < sizeof p->a + 1)
     147      n = sizeof p->a + 1;
     148  
     149    return __builtin___strncpy_chk (p->a, "123456789", n, bos (p->a));  /* { dg-warning "\\\[-Wstringop-overflow=]" } */
     150  }