(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overflow-54.c
       1  /* Verify that writes at excessive offsets into flexible array members
       2     of extern or allocated objects of unknow size 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  void char_flexarray_cst_off_cst_size (void)
      16  {
      17    extern struct { char n, a[]; }
      18      caxcc;                              // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'caxcc'" "note" }
      19  
      20    char *p = caxcc.a;
      21    size_t idx = DIFF_MAX - 4;
      22  
      23    memset (p + idx, 0, 3);
      24    sink (p);
      25  
      26    ++idx;
      27    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 2" }
      28    sink (p);
      29  
      30    ++idx;
      31    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 1" }
      32  
      33    ++idx;
      34    memset (p + idx, 0, 3);               // { dg-warning "writing 3 bytes into a region of size 0" }
      35  }
      36  
      37  
      38  void char_flexarray_var_off_cst_size (ptrdiff_t idx)
      39  {
      40    extern struct { char n, a[]; }
      41      caxvc;                              // { dg-message "destination object 'caxvc'" "note" }
      42  
      43    char *p = caxvc.a;
      44  
      45    if (idx < DIFF_MAX - 4)
      46      idx = DIFF_MAX - 4;
      47  
      48    memset (p + idx, 0, 3);
      49    sink (p);
      50  
      51    memset (p + idx, 0, 5);               // { dg-warning "writing 5 bytes into a region of size 3" }
      52  }
      53  
      54  
      55  void char_flexarray_var_off_var_size (size_t n, ptrdiff_t idx)
      56  {
      57    extern struct { char n, a[]; }
      58      caxvv;                              // { dg-message "destination object 'caxvv'" "note" }
      59  
      60    char *p = caxvv.a;
      61  
      62    if (idx < DIFF_MAX - 4)
      63      idx = DIFF_MAX - 4;
      64  
      65    if (n < 3 || 7 < n)
      66      n = 3;
      67  
      68    memset (p + idx, 0, n);
      69    sink (p);
      70  
      71    ++n;
      72    memset (p + idx, 0, n);               // { dg-warning "writing between 4 and 8 bytes into a region of size 3" }
      73  }
      74  
      75  
      76  void alloc_array_var_off_cst_size (size_t n, ptrdiff_t idx)
      77  {
      78    struct { char n, a[]; }
      79      *p = __builtin_malloc (n);          // { dg-message "at offset \\d+ into destination object" "note" }
      80  
      81    if (idx < DIFF_MAX - 4)
      82      idx = DIFF_MAX - 4;
      83  
      84    memset (p->a + idx, 0, 3);
      85    sink (p);
      86  
      87    memset (p->a + idx, 0, 5);            // { dg-warning "writing 5 bytes into a region of size 3" }
      88  }
      89  
      90  
      91  void int_array_cst_off_cst_size (void)
      92  {
      93    extern struct { int n, a[]; }
      94      iaxc;                               // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'iaxc'" "note" }
      95  
      96    int *p = iaxc.a;
      97    size_t idx = DIFF_MAX / sizeof *p - 1;
      98  
      99    memset (p + idx, 0, 3);
     100    sink (p);
     101  
     102    memset (p + idx, 0, 5);               // { dg-warning "writing 5 bytes into a region of size 3" }
     103  }