(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overflow-45.c
       1  /* PR middle-end/97023 - missing warning on buffer overflow in chained mempcpy
       2     Verify that out of bounds writes by built-ins to objects through pointers
       3     returned by other built-ins are diagnosed.
       4     { dg-do compile }
       5     { dg-options "-O2" } */
       6  
       7  #include "range.h"
       8  
       9  void* malloc (size_t);
      10  void* memcpy (void*, const void*, size_t);
      11  void* memmove (void*, const void*, size_t);
      12  void* mempcpy (void*, const void*, size_t);
      13  
      14  void sink (void*, ...);
      15  
      16  
      17  void nowarn_memcpy (const void *s)
      18  {
      19    extern char cpy_a4[4];
      20    unsigned n = sizeof cpy_a4;
      21  
      22    void *p = cpy_a4;
      23    p = memcpy (p, s, n);
      24    sink (p);
      25    memcpy (p, s, n);
      26    sink (p);
      27  
      28    p = cpy_a4 + 1;
      29    p = memcpy (p, s, n - 1);
      30    sink (p);
      31    memcpy (p, s, n - 1);
      32    sink (p);
      33  
      34    p = cpy_a4 + 2;
      35    p = memcpy (p, s, n - 2);
      36    sink (p);
      37    memcpy (p, s, n - 2);
      38    sink (p);
      39  
      40    p = cpy_a4 + 3;
      41    p = memcpy (p, s, n - 3);
      42    sink (p);
      43    memcpy (p, s, n - 3);
      44    sink (p);
      45  
      46    p = cpy_a4 + 4;
      47    p = memcpy (p, s, n - 4);
      48    sink (p);
      49    memcpy (p, s, n - 4);
      50    sink (p);
      51  }
      52  
      53  
      54  void nowarn_memcpy_chain (const void *s)
      55  {
      56    extern char cpy_a8[8];
      57  
      58    char *p = cpy_a8;
      59  
      60    p = memcpy (p + 1, s, 7);
      61    sink (p);
      62  
      63    p = memcpy (p + 2 , s, 5);
      64    sink (p);
      65  
      66    p = memcpy (p + 3 , s, 2);
      67    sink (p);
      68  
      69    p = memcpy (p + 1 , s, 1);
      70    sink (p);
      71  
      72    p = memcpy (p - 7 , s, 8);
      73    sink (p);
      74  
      75    memcpy (p + 1, s, 7);
      76  }
      77  
      78  
      79  void warn_memcpy (const void *s)
      80  {
      81    extern char cpy_a5[5];                // { dg-message "destination object 'cpy_a5'" "note" }
      82  
      83    unsigned n = sizeof cpy_a5;
      84    void *p = cpy_a5;
      85  
      86    p = memcpy (p, s, n);
      87    sink (p);
      88    memcpy (p, s, n + 1);                 // { dg-warning "writing 6 bytes into a region of size 5" }
      89    sink (p);
      90  
      91    p = cpy_a5;
      92    p = memcpy (p, s, n);
      93    sink (p);
      94    memcpy (p, s, n + 1);                 // { dg-warning "writing 6 bytes into a region of size 5" }
      95    sink (p);
      96  
      97    p = cpy_a5 + 1;
      98    p = memcpy (p, s, n - 1);
      99    sink (p);
     100    memcpy (p, s, n);                     // { dg-warning "writing 5 bytes into a region of size 4" }
     101    sink (p);
     102  }
     103  
     104  
     105  void warn_memcpy_chain (const void *s)
     106  {
     107    extern char cpy_a8[8];                // { dg-message "destination object 'cpy_a8'" "note" }
     108  
     109    char *p = cpy_a8;
     110  
     111    p = memcpy (p, s, 9);                 // { dg-warning "writing 9 bytes into a region of size 8" }
     112    sink (p);
     113  
     114    p = memcpy (p + 2, s, 7);             // { dg-warning "writing 7 bytes into a region of size 6" }
     115    sink (p);
     116  
     117    p = memcpy (p + 3, s, 5);             // { dg-warning "writing 5 bytes into a region of size 3" }
     118    sink (p);
     119  
     120    p = memcpy (p + 3, s, 3);             // { dg-warning "writing 3 bytes into a region of size 0" }
     121    sink (p);
     122  }
     123  
     124  
     125  void nowarn_mempcpy (const void *s)
     126  {
     127    extern char a4[4];
     128    unsigned n = sizeof a4;
     129  
     130    char *p = mempcpy (a4, s, n);
     131    sink (p);
     132    mempcpy (p - 4, s, n);
     133    sink (p);
     134  
     135    p = mempcpy (a4 + 1, s, n - 1);
     136    sink (p);
     137    mempcpy (p - 4, s, n);
     138    sink (p);
     139  
     140    p = mempcpy (a4 + 2, s, n - 2);
     141    sink (p);
     142    mempcpy (p - 4, s, n);
     143    sink (p);
     144  
     145    p = mempcpy (a4 + 3, s, n - 3);
     146    sink (p);
     147    mempcpy (p - 4, s, n);
     148    sink (p);
     149  
     150    p = mempcpy (a4 + 4, s, n - 4);
     151    sink (p);
     152    mempcpy (p - 4, s, n);
     153    sink (p);
     154  }
     155  
     156  
     157  void nowarn_mempcpy_chain (const void *s)
     158  {
     159    extern char pcpy_a8[8];
     160  
     161    char *p = pcpy_a8;
     162  
     163    p = mempcpy (p + 1, s, 7);
     164    sink (p);
     165  
     166    p = mempcpy (p - 7 , s, 7);
     167    sink (p);
     168  
     169    p = mempcpy (p - 5 , s, 5);
     170    sink (p);
     171  
     172    p = mempcpy (p - 3 , s, 3);
     173    sink (p);
     174  
     175    p = mempcpy (p - 2 , s, 2);
     176    sink (p);
     177  
     178    mempcpy (p - 1, s, 1);
     179    sink (p);
     180  
     181    mempcpy (p - 8, s, 8);
     182  }
     183  
     184  
     185  void warn_mempcpy (const void *s)
     186  {
     187    extern char pcpy_a5[5];               // { dg-message "destination object 'pcpy_a5'" "note" }
     188  
     189    char *p = pcpy_a5;
     190  
     191    p = mempcpy (p, s, 5);
     192    sink (p);
     193    mempcpy (p - 5, s, 6);                // { dg-warning "writing 6 bytes into a region of size 5 " }
     194    sink (p);
     195  
     196    p = pcpy_a5;
     197    p = mempcpy (p, s, 3);
     198    sink (p);
     199    mempcpy (p, s, 3);                    // { dg-warning "writing 3 bytes into a region of size 2 " }
     200    sink (p);
     201  
     202    p = pcpy_a5 + 1;
     203    p = mempcpy (p, s, 3);
     204    sink (p);
     205    mempcpy (p - 1, s, 5);                // { dg-warning "writing 5 bytes into a region of size 2 " }
     206    sink (p);
     207  }
     208  
     209  
     210  void warn_mempcpy_chain_3 (const void *s)
     211  {
     212    char *p = malloc (5);                 // { dg-message "at offset \\\[3, 5] into destination object of size 5" "note" }
     213    p = mempcpy (p, s, UR (1, 2));
     214    p = mempcpy (p, s, UR (2, 3));
     215    p = mempcpy (p, s, UR (3, 4));        // { dg-warning "writing between 3 and 4 bytes into a region of size 2 " }
     216  
     217    sink (p);
     218  }
     219  
     220  void warn_mempcpy_offrng_chain_3 (const void *s)
     221  {
     222    char *p = malloc (11);                 // { dg-message "at offset \\\[9, 11] into destination object of size 11 " "note" }
     223    size_t r1_2 = UR (1, 2);
     224    size_t r2_3 = r1_2 + 1;
     225    size_t r3_4 = r2_3 + 1;
     226  
     227    p = mempcpy (p + r1_2, s, r1_2);
     228    p = mempcpy (p + r2_3, s, r2_3);
     229    p = mempcpy (p + r3_4, s, r3_4);       // { dg-warning "writing between 3 and 4 bytes into a region of size 2 " }
     230  
     231    sink (p);
     232  }
     233  
     234  void warn_mempcpy_chain_4 (const void *s)
     235  {
     236    char *p = malloc (9);                 // { dg-message "at offset \\\[6, 9] into destination object of size 9 " "note" }
     237    p = mempcpy (p, s, UR (1, 2));
     238    p = mempcpy (p, s, UR (2, 3));
     239    p = mempcpy (p, s, UR (3, 4));
     240    p = mempcpy (p, s, UR (4, 5));        // { dg-warning "writing between 4 and 5 bytes into a region of size 3 " }
     241  
     242    sink (p);
     243  }
     244  
     245  void warn_mempcpy_chain_5 (const void *s)
     246  {
     247    char *p = malloc (14);                // { dg-message "at offset \\\[10, 14] into destination object of size 14 " "note" }
     248    p = mempcpy (p, s, UR (1, 2));
     249    p = mempcpy (p, s, UR (2, 3));
     250    p = mempcpy (p, s, UR (3, 4));
     251    p = mempcpy (p, s, UR (4, 5));
     252    p = mempcpy (p, s, UR (5, 6));        // { dg-warning "writing between 5 and 6 bytes into a region of size 4 " }
     253  
     254    sink (p);
     255  }