(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overread-2.c
       1  /* Verify -Wstringop-overread is issued for reading more than the maximum
       2     object size but not for writing.
       3    { dg-do compile }
       4    { dg-options "-O2 -Wno-stringop-overflow -ftrack-macro-expansion=0" } */
       5  
       6  #define PTRDIFF_MAX   __PTRDIFF_MAX__
       7  #define SIZE_MAX      __SIZE_MAX__
       8  
       9  #define NOIPA         __attribute__ ((noipa))
      10  
      11  typedef __SIZE_TYPE__ size_t;
      12  
      13  void* memchr (const void*, int, size_t);
      14  int memcmp (const void*, const void*, size_t);
      15  void* memcpy (const void*, const void*, size_t);
      16  
      17  int strncmp (const char*, const char*, size_t);
      18  char* strncat (char*, const char*, size_t);
      19  char* strncpy (char*, const char*, size_t);
      20  size_t strnlen (const char*, size_t);
      21  
      22  void sink (int, ...);
      23  #define sink(...) sink (0, __VA_ARGS__)
      24  #define T(exp)   sink (exp)
      25  
      26  NOIPA void test_memchr (const void *p, int x)
      27  {
      28    size_t dmax = PTRDIFF_MAX;
      29    size_t smax = SIZE_MAX;
      30  
      31    T (memchr (p, x, dmax));
      32  
      33    T (memchr (p, x, dmax + 1));     // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
      34    T (memchr (p, x, dmax * 2));     // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
      35    T (memchr (p, x, smax));         // { dg-warning "\\\[-Wstringop-overread" }
      36  }
      37  
      38  
      39  NOIPA void test_memcmp (const void *p, const void *q)
      40  {
      41    size_t dmax = PTRDIFF_MAX;
      42    size_t smax = SIZE_MAX;
      43  
      44    T (memcmp (p, q, dmax));
      45  
      46    T (memcmp (p, q, dmax + 1));     // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
      47    T (memcmp (p, q, dmax * 2));     // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
      48    T (memcmp (p, q, smax));         // { dg-warning "\\\[-Wstringop-overread" }
      49  }
      50  
      51  
      52  NOIPA void test_memcpy (void *p, const void *q)
      53  {
      54    size_t dmax = PTRDIFF_MAX;
      55    size_t smax = SIZE_MAX;
      56  
      57    T (memcpy (p, q, dmax));
      58  
      59    T (memcpy (p, q, dmax + 1));    // -Wstringop-overflow disabled
      60    T (memcpy (p, q, dmax * 2));    // ditto
      61    T (memcpy (p, q, smax));        // ditto
      62  }
      63  
      64  
      65  NOIPA void test_strncmp (const char *p, const char *q)
      66  {
      67    size_t dmax = PTRDIFF_MAX;
      68    size_t smax = SIZE_MAX;
      69  
      70    T (strncmp (p, q, dmax));
      71  
      72    T (strncmp (p, q, dmax + 1));   // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" "strncmp" }
      73    T (strncmp (p, q, dmax * 2));   // { dg-warning "\\\[-Wstringop-overread" "strncmp" }
      74    T (strncmp (p, q, smax));       // { dg-warning "\\\[-Wstringop-overread" "strncmp" }
      75  }
      76  
      77  NOIPA void test_strncat (char *p, const char *q)
      78  {
      79    size_t dmax = PTRDIFF_MAX;
      80    size_t smax = SIZE_MAX;
      81  
      82    T (strncat (p, q, dmax));
      83  
      84    T (strncat (p, q, dmax + 1));   // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
      85    T (strncat (p, q, dmax * 2));   // { dg-warning "\\\[-Wstringop-overread" }
      86    T (strncat (p, q, smax));       // { dg-warning "\\\[-Wstringop-overread" }
      87  }
      88  
      89  NOIPA void test_strncpy (char *p, const char *q)
      90  {
      91  #if 0
      92    /* Disabled: strncpy calls with an excissve bound trigger both
      93       -Wstringop-overflow and, when the former option is disabled,
      94       -Wstringop-overread.  The latter should probably not trigger.  */
      95  
      96    size_t dmax = PTRDIFF_MAX;
      97    size_t smax = SIZE_MAX;
      98  
      99    T (strncpy (p, q, dmax));
     100  
     101    T (strncpy (p, q, dmax + 1));    // -Wstringop-overflow disabled
     102    T (strncpy (p, q, dmax * 2));    // ditto
     103    T (strncpy (p, q, smax));        // ditto
     104  #endif
     105  }
     106  
     107  NOIPA void test_strnlen (const char *p)
     108  {
     109    size_t dmax = PTRDIFF_MAX;
     110    size_t smax = SIZE_MAX;
     111  
     112    T (strnlen (p, dmax));
     113  
     114    T (strnlen (p, dmax + 1));      // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
     115    T (strnlen (p, dmax * 2));      // { dg-warning "\\\[-Wstringop-overread" }
     116    T (strnlen (p, smax));          // { dg-warning "\\\[-Wstringop-overread" }
     117  }