(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overflow-41.c
       1  /* Verify that writes at excessive offsets into declared or allocated
       2     objects of unknown size are diagnosed.
       3     { dg-do compile }
       4     { dg-options "-O2" } */
       5  
       6  #define DIFF_MAX __PTRDIFF_MAX__
       7  
       8  typedef __SIZE_TYPE__ size_t;
       9  
      10  void* malloc (size_t);
      11  void* memcpy (void*, const void*, size_t);
      12  void* memset (void*, int, size_t);
      13  
      14  void sink (void*);
      15  
      16  
      17  void char_array_cst_off_cst_size (void)
      18  {
      19    extern char caxcc[];                  // { dg-message "at offset \\d+ into destination object 'caxcc'" }
      20  
      21    char *p = caxcc;
      22    size_t idx = DIFF_MAX - 3;
      23  
      24    memset (p + idx, 0, 3);
      25    sink (p);
      26  
      27    ++idx;
      28    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 2" }
      29    sink (p);
      30  
      31    ++idx;
      32    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 1" }
      33    sink (p);
      34  
      35    ++idx;
      36    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 0" }
      37    sink (p);
      38  }
      39  
      40  
      41  void char_array_var_off_cst_size (size_t idx)
      42  {
      43    /* The offset is a range with a very large lower bound and an upper
      44       bound of DIFF_MAX.  There's not point in also mentioning the latter
      45       (it wouldn't make the note any more meaningful) so verify it only
      46       mentions the lower bound.  */
      47    extern char caxvc[];                  // { dg-message "at offset \\d+ into destination object 'caxvc'" "note" }
      48  
      49    char *p = caxvc;
      50  
      51    if (idx < DIFF_MAX - 3)
      52      idx = DIFF_MAX - 3;
      53  
      54    memset (p + idx, 0, 3);
      55    sink (p);
      56  
      57    memset (p + idx, 0, 5);               // { dg-warning "writing 5 bytes into a region of size 3" }
      58    sink (p);
      59  }
      60  
      61  
      62  void char_array_var_off_var_size (size_t idx, size_t n)
      63  {
      64    extern char caxvv[];                  // { dg-message "at offset \\d+ into destination object 'caxvv'" "note" }
      65  
      66    char *p = caxvv;
      67  
      68    if (idx < DIFF_MAX - 3)
      69      idx = DIFF_MAX - 3;
      70  
      71    if (n < 3 || 7 < n)
      72      n = 3;
      73  
      74    memset (p + idx, 0, n);
      75    sink (p);
      76  
      77    ++n;
      78    memset (p + idx, 0, n);               // { dg-warning "writing between 4 and 8 bytes into a region of size 3" }
      79    sink (p);
      80  }
      81  
      82  
      83  void alloc_array_var_off_cst_size (size_t n, size_t idx)
      84  {
      85    char *p = malloc (n);                 // { dg-message "at offset \\d+ into destination object" "note" }
      86  
      87    if (idx < DIFF_MAX - 3)
      88      idx = DIFF_MAX - 3;
      89  
      90    memset (p + idx, 0, 3);
      91    sink (p);
      92  
      93    memset (p + idx, 0, 5);               // { dg-warning "writing 5 bytes into a region of size 3" }
      94    sink (p);
      95  }
      96  
      97  
      98  void int_array_cst_off_cst_size (void)
      99  {
     100    extern int iaxc[];                    // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'iaxc'" }
     101  
     102    int *p = iaxc;
     103    size_t idx = DIFF_MAX / sizeof *iaxc;
     104  
     105    memset (p + idx, 0, 3);
     106    sink (p);
     107  
     108    memset (p + idx, 0, 5);               // { dg-warning "writing 5 bytes into a region of size 3" }
     109    sink (p);
     110  }
     111  
     112  
     113  void* nowarn_anti_range_1 (char *p, char *q)
     114  {
     115    size_t n = q - p;
     116    if (!n) return 0;
     117  
     118    char *d = __builtin_malloc (n + 1);
     119    memcpy (d, p, n + 1);                 // { dg-bogus "-Wstringop-overflow" }
     120    return d;
     121  }