(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overflow-50.c
       1  /* Verify that writes at excessive offsets into objects of unknown size
       2     pointed to by function arguments are diagnosed.
       3     { dg-do compile }
       4     { dg-options "-O2" } */
       5  
       6  #define DIFF_MAX __PTRDIFF_MAX__
       7  
       8  typedef __PTRDIFF_TYPE__ ptrdiff_t;
       9  typedef __SIZE_TYPE__    size_t;
      10  
      11  void* memset (void*, int, size_t);
      12  
      13  void sink (void*);
      14  
      15  char* fcall (void);
      16  
      17  void char_ptr_cst_off_cst_size (char *p)
      18                                          // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'p'" "note" { target *-*-* } .-1 }
      19  {
      20    size_t idx = DIFF_MAX - 3;
      21  
      22    memset (p + idx, 0, 3);
      23    sink (p);
      24  
      25    ++idx;
      26    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 2" }
      27    sink (p);
      28  
      29    ++idx;
      30    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 1" }
      31  
      32    ++idx;
      33    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 0" }
      34  }
      35  
      36  
      37  void char_ptr_var_difoff_cst_size (ptrdiff_t idx)
      38  {
      39    char *p = fcall ();
      40    /* The offset is a range with a very large lower bound and an upper
      41       bound of DIFF_MAX.  There's not point in also mentioning the latter
      42       (it wouldn't make the note any more meaningful) so verify it only
      43       mentions the lower bound.
      44       { dg-message "at offset \\d+ into destination object of size \\\[0, \\d+] (allocated|returned) by 'fcall'" "note" { target *-*-* } .-5 } */
      45  
      46    if (idx < DIFF_MAX - 3)
      47      idx = DIFF_MAX - 3;
      48  
      49    memset (p + idx, 0, 3);
      50    sink (p);
      51  
      52    memset (p + idx, 0, 5);               // { dg-warning "writing 5 bytes into a region of size 3" }
      53  }
      54  
      55  
      56  void char_ptr_var_szoff_cst_size (size_t idx)
      57  {
      58    extern char* gptr;
      59    // { dg-message "at offset \\d+ into destination object 'gptr'" "note" { target *-*-* } .-1 }
      60  
      61    char *p = gptr;
      62  
      63    if (idx < DIFF_MAX - 3)
      64      idx = DIFF_MAX - 3;
      65  
      66    memset (p + idx, 0, 3);
      67    sink (p);
      68  
      69    memset (p + idx, 0, 5);               // { dg-warning "writing 5 bytes into a region of size 3" "" { xfail *-*-* } }
      70  
      71    if (idx > DIFF_MAX)
      72      idx = DIFF_MAX;
      73  
      74    memset (p + idx, 0, 7);               // { dg-warning "writing 7 bytes into a region of size 3" }
      75  }
      76  
      77  
      78  void char_ptr_var_difoff_var_size (char *p, ptrdiff_t idx, size_t n)
      79                                          // { dg-message "at offset \\d+ into destination object 'p'" "note" { target *-*-* } .-1 }
      80  {
      81    if (idx < DIFF_MAX - 3)
      82      idx = DIFF_MAX - 3;
      83  
      84    if (n < 3 || 7 < n)
      85      n = 3;
      86  
      87    memset (p + idx, 0, n);
      88    sink (p);
      89  
      90    ++n;
      91    memset (p + idx, 0, n);               // { dg-warning "writing between 4 and 8 bytes into a region of size 3" }
      92  }
      93  
      94  
      95  void char_ptr_var_szoff_var_size (char *p, size_t idx, size_t n)
      96                                          // { dg-message "at offset \\\[\[1-9\]\[0-9\]+, \[1-9\]\[0-9\]+] into destination object 'p'" "note" { xfail *-*-* } .-1 }
      97  {
      98    if (idx < DIFF_MAX - 3)
      99      idx = DIFF_MAX - 3;
     100  
     101    if (n < 3 || 7 < n)
     102      n = 3;
     103  
     104    memset (p + idx, 0, n);
     105    sink (p);
     106  
     107    ++n;
     108    /* With an unsigned offset large values are interpreted as negative
     109       so the addition (p + idx) is effectively treated as subtraction,
     110       making an overflow indistinguishable from a valid (if unlikely)
     111       store.  */
     112    memset (p + idx, 0, n);               // { dg-warning "writing between 4 and 8 bytes into a region of size 3" "pr?????" { xfail *-*-* } }
     113  }
     114  
     115  
     116  void int_ptr_cst_off_cst_size (int *p)
     117                                          // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'p'" "note" { target *-*-* } .-1 }
     118  {
     119    size_t idx = DIFF_MAX / sizeof *p;
     120  
     121    memset (p + idx, 0, 3);
     122    sink (p);
     123  
     124    memset (p + idx, 0, 5);               // { dg-warning "writing 5 bytes into a region of size 3" }
     125  }