1  /* PR middle-end/91977 - missing -Wstringop-overflow on memcpy into
       2     a pointer plus offset
       3     { dg-do compile }
       4     { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
       5  
       6  #define NOIPA          __attribute__ ((noipa))
       7  #define CONCAT(a, b)   a ## b
       8  #define CAT(a, b)      CONCAT (a, b)
       9  
      10  #define S3 "123"
      11  #define S4 "1234"
      12  
      13  char a1[1], a2[2], a3[3], a4[4], a5[5], a6[6], a7[7], a8[8];
      14  char b1[1], b2[2], b3[3], b4[4], b5[5], b6[6], b7[7], b8[8];
      15  
      16  #define T(dst, src, off, n)					\
      17    NOIPA void CAT (test_on_line_, __LINE__) (const void *s)	\
      18    {								\
      19      __builtin_memcpy (dst + off, src, n);			\
      20    } typedef void dummy_type
      21  
      22  T (a4, s, 0, 1);
      23  T (a4, s, 1, 1);
      24  T (a4, s, 2, 1);
      25  T (a4, s, 3, 1);
      26  T (a4, s, 4, 1);    // { dg-warning "writing 1 byte into a region of size 0" }
      27  
      28  T (a4, s, 0, 2);
      29  T (a4, s, 1, 2);
      30  T (a4, s, 2, 2);
      31  T (a4, s, 3, 2);    // { dg-warning "writing 2 bytes into a region of size 1" }
      32  T (a4, s, 4, 2);    // { dg-warning "writing 2 bytes into a region of size 0" }
      33  
      34  T (a4, s, 0, 3);
      35  T (a4, s, 1, 3);
      36  T (a4, s, 2, 3);    // { dg-warning "writing 3 bytes into a region of size 2" }
      37  T (a4, s, 3, 3);    // { dg-warning "writing 3 bytes into a region of size 1" }
      38  T (a4, s, 4, 3);    // { dg-warning "writing 3 bytes into a region of size 0" }
      39  
      40  T (a4, s, 0, 4);
      41  T (a4, s, 1, 4);    // { dg-warning "writing 4 bytes into a region of size 3" }
      42  T (a4, s, 2, 4);    // { dg-warning "writing 4 bytes into a region of size 2" }
      43  T (a4, s, 3, 4);    // { dg-warning "writing 4 bytes into a region of size 1" }
      44  T (a4, s, 4, 4);    // { dg-warning "writing 4 bytes into a region of size 0" }
      45  
      46  T (a7, s, 3, 3);
      47  T (a7, s, 4, 3);
      48  T (a7, s, 5, 3);    // { dg-warning "writing 3 bytes into a region of size 2" }
      49  T (a7, s, 6, 3);    // { dg-warning "writing 3 bytes into a region of size 1" }
      50  T (a7, s, 7, 3);    // { dg-warning "writing 3 bytes into a region of size 0" }
      51  
      52  T (a7, s, 3, 4);
      53  T (a7, s, 4, 4);    // { dg-warning "writing 4 bytes into a region of size 3" }
      54  T (a7, s, 5, 4);    // { dg-warning "writing 4 bytes into a region of size 2" }
      55  T (a7, s, 6, 4);    // { dg-warning "writing 4 bytes into a region of size 1" }
      56  T (a7, s, 7, 4);    // { dg-warning "writing 4 bytes into a region of size 0" }
      57  
      58  T (a7, s, 1, 6);
      59  T (a7, s, 2, 6);    // { dg-warning "writing 6 bytes into a region of size 5" }
      60  T (a7, s, 3, 6);    // { dg-warning "writing 6 bytes into a region of size 4" }
      61  T (a7, s, 4, 6);    // { dg-warning "writing 6 bytes into a region of size 3" }
      62  T (a7, s, 5, 6);    // { dg-warning "writing 6 bytes into a region of size 2" }
      63  T (a7, s, 6, 6);    // { dg-warning "writing 6 bytes into a region of size 1" }
      64  T (a7, s, 7, 6);    // { dg-warning "writing 6 bytes into a region of size 0" }
      65  
      66  T (a8, s, 1, 7);
      67  T (a8, s, 2, 7);    // { dg-warning "writing 7 bytes into a region of size 6" }
      68  T (a8, s, 3, 7);    // { dg-warning "writing 7 bytes into a region of size 5" }
      69  T (a8, s, 4, 7);    // { dg-warning "writing 7 bytes into a region of size 4" }
      70  T (a8, s, 5, 7);    // { dg-warning "writing 7 bytes into a region of size 3" }
      71  T (a8, s, 6, 7);    // { dg-warning "writing 7 bytes into a region of size 2" }
      72  T (a8, s, 7, 7);    // { dg-warning "writing 7 bytes into a region of size 1" }
      73  T (a8, s, 8, 7);    // { dg-warning "writing 7 bytes into a region of size 0" }
      74  
      75  #undef T
      76  #define T(dst, src, off, n)					\
      77    NOIPA void CAT (test_on_line_, __LINE__) (const void *s)	\
      78    {								\
      79      char *d = dst + off;					\
      80      __builtin_memcpy (d, src, n);				\
      81    } typedef void dummy_type
      82  
      83  T (a4, s, 0, 1);
      84  T (a4, s, 1, 1);
      85  T (a4, s, 2, 1);
      86  T (a4, s, 3, 1);
      87  T (a4, s, 4, 1);    // { dg-warning "writing 1 byte into a region of size 0" }
      88  
      89  T (a4, s, 0, 2);
      90  T (a4, s, 1, 2);
      91  T (a4, s, 2, 2);
      92  T (a4, s, 3, 2);    // { dg-warning "writing 2 bytes into a region of size 1" }
      93  T (a4, s, 4, 2);    // { dg-warning "writing 2 bytes into a region of size 0" }
      94  
      95  T (a4, s, 0, 3);
      96  T (a4, s, 1, 3);
      97  T (a4, s, 2, 3);    // { dg-warning "writing 3 bytes into a region of size 2" }
      98  T (a4, s, 3, 3);    // { dg-warning "writing 3 bytes into a region of size 1" }
      99  T (a4, s, 4, 3);    // { dg-warning "writing 3 bytes into a region of size 0" }
     100  
     101  T (a4, s, 0, 4);
     102  T (a4, s, 1, 4);    // { dg-warning "writing 4 bytes into a region of size 3" }
     103  T (a4, s, 2, 4);    // { dg-warning "writing 4 bytes into a region of size 2" }
     104  T (a4, s, 3, 4);    // { dg-warning "writing 4 bytes into a region of size 1" }
     105  T (a4, s, 4, 4);    // { dg-warning "writing 4 bytes into a region of size 0" }
     106  
     107  T (a7, s, 3, 3);
     108  T (a7, s, 4, 3);
     109  T (a7, s, 5, 3);    // { dg-warning "writing 3 bytes into a region of size 2" }
     110  T (a7, s, 6, 3);    // { dg-warning "writing 3 bytes into a region of size 1" }
     111  T (a7, s, 7, 3);    // { dg-warning "writing 3 bytes into a region of size 0" }
     112  
     113  T (a7, s, 3, 4);
     114  T (a7, s, 4, 4);    // { dg-warning "writing 4 bytes into a region of size 3" }
     115  T (a7, s, 5, 4);    // { dg-warning "writing 4 bytes into a region of size 2" }
     116  T (a7, s, 6, 4);    // { dg-warning "writing 4 bytes into a region of size 1" }
     117  T (a7, s, 7, 4);    // { dg-warning "writing 4 bytes into a region of size 0" }
     118  
     119  T (a7, s, 1, 6);
     120  T (a7, s, 2, 6);    // { dg-warning "writing 6 bytes into a region of size 5" }
     121  T (a7, s, 3, 6);    // { dg-warning "writing 6 bytes into a region of size 4" }
     122  T (a7, s, 4, 6);    // { dg-warning "writing 6 bytes into a region of size 3" }
     123  T (a7, s, 5, 6);    // { dg-warning "writing 6 bytes into a region of size 2" }
     124  T (a7, s, 6, 6);    // { dg-warning "writing 6 bytes into a region of size 1" }
     125  T (a7, s, 7, 6);    // { dg-warning "writing 6 bytes into a region of size 0" }
     126  
     127  #undef T
     128  #define T(dst, src, init, off, n)			\
     129    NOIPA void CAT (test_on_line_, __LINE__) (void)	\
     130    {							\
     131      __builtin_strcpy (src, init);			\
     132      char *d = dst + off;				\
     133      __builtin_memcpy (d, src, n);			\
     134    } typedef void dummy_type
     135  
     136  
     137  T (a6, b6, S4, 0, 4);
     138  T (a6, b6, S4, 1, 4);
     139  T (a6, b6, S4, 2, 4);
     140  T (a6, b6, S4, 3, 4);   // { dg-warning "writing 4 bytes into a region of size 3" } */
     141  T (a6, b6, S4, 4, 4);   // { dg-warning "writing 4 bytes into a region of size 2" } */
     142  T (a6, b6, S4, 5, 4);   // { dg-warning "writing 4 bytes into a region of size 1" } */
     143  T (a6, b6, S4, 6, 4);   // { dg-warning "writing 4 bytes into a region of size 0" } */
     144  
     145  T (a7, b7, S4, 0, 4);
     146  T (a7, b7, S4, 1, 4);
     147  T (a7, b7, S4, 2, 4);
     148  T (a7, b7, S4, 3, 4);
     149  T (a7, b7, S4, 4, 4);   // { dg-warning "writing 4 bytes into a region of size 3" } */
     150  T (a7, b7, S4, 5, 4);   // { dg-warning "writing 4 bytes into a region of size 2" } */
     151  T (a7, b7, S4, 6, 4);   // { dg-warning "writing 4 bytes into a region of size 1" } */
     152  T (a7, b7, S4, 7, 4);   // { dg-warning "writing 4 bytes into a region of size 0" } */
     153  
     154  T (a8, b4, S3, 0, 4);
     155  T (a8, b4, S3, 1, 4);
     156  T (a8, b4, S3, 2, 4);
     157  T (a8, b4, S3, 3, 4);
     158  T (a8, b4, S3, 4, 4);
     159  T (a8, b4, S3, 5, 4);   // { dg-warning "writing 4 bytes into a region of size 3" } */
     160  T (a8, b4, S3, 6, 4);   // { dg-warning "writing 4 bytes into a region of size 2" } */
     161  T (a8, b4, S3, 7, 4);   // { dg-warning "writing 4 bytes into a region of size 1" } */
     162  T (a8, b4, S3, 8, 4);   // { dg-warning "writing 4 bytes into a region of size 0" } */
     163  
     164  T (a8, b8, S3, 0, 4);
     165  T (a8, b8, S3, 1, 4);
     166  T (a8, b8, S3, 2, 4);
     167  T (a8, b8, S3, 3, 4);
     168  T (a8, b8, S3, 4, 4);
     169  T (a8, b8, S3, 5, 4);   // { dg-warning "writing 4 bytes into a region of size 3" } */
     170  T (a8, b8, S3, 6, 4);   // { dg-warning "writing 4 bytes into a region of size 2" } */
     171  T (a8, b8, S3, 7, 4);   // { dg-warning "writing 4 bytes into a region of size 1" } */
     172  T (a8, b8, S3, 8, 4);   // { dg-warning "writing 4 bytes into a region of size 0" } */
     173  
     174  T (a8, b8, S4, 0, 4);
     175  T (a8, b8, S4, 1, 4);
     176  T (a8, b8, S4, 2, 4);
     177  T (a8, b8, S4, 3, 4);
     178  T (a8, b8, S4, 4, 4);
     179  T (a8, b8, S4, 5, 4);   // { dg-warning "writing 4 bytes into a region of size 3" } */
     180  T (a8, b8, S4, 6, 4);   // { dg-warning "writing 4 bytes into a region of size 2" } */
     181  T (a8, b8, S4, 7, 4);   // { dg-warning "writing 4 bytes into a region of size 1" } */
     182  T (a8, b8, S4, 8, 4);   // { dg-warning "writing 4 bytes into a region of size 0" } */
     183  
     184  T (a8, b8, S4, 0, 5);
     185  T (a8, b8, S4, 1, 5);
     186  T (a8, b8, S4, 2, 5);
     187  T (a8, b8, S4, 3, 5);
     188  T (a8, b8, S4, 4, 5);   // { dg-warning "writing 5 bytes into a region of size 4" } */
     189  T (a8, b8, S4, 5, 5);   // { dg-warning "writing 5 bytes into a region of size 3" } */
     190  T (a8, b8, S4, 6, 5);   // { dg-warning "writing 5 bytes into a region of size 2" } */
     191  T (a8, b8, S4, 7, 5);   // { dg-warning "writing 5 bytes into a region of size 1" } */
     192  T (a8, b8, S4, 8, 5);   // { dg-warning "writing 5 bytes into a region of size 0" } */
     193  
     194  T (a8, b8, S4, 0, 6);
     195  T (a8, b8, S4, 1, 6);
     196  T (a8, b8, S4, 2, 6);
     197  T (a8, b8, S4, 3, 6);   // { dg-warning "writing 6 bytes into a region of size 5" } */
     198  T (a8, b8, S4, 4, 6);   // { dg-warning "writing 6 bytes into a region of size 4" } */
     199  T (a8, b8, S4, 5, 6);   // { dg-warning "writing 6 bytes into a region of size 3" } */
     200  T (a8, b8, S4, 6, 6);   // { dg-warning "writing 6 bytes into a region of size 2" } */
     201  T (a8, b8, S4, 7, 6);   // { dg-warning "writing 6 bytes into a region of size 1" } */
     202  T (a8, b8, S4, 8, 6);   // { dg-warning "writing 6 bytes into a region of size 0" } */
     203  
     204  
     205  #undef T
     206  #define T(dst, init, off, n)				\
     207    NOIPA void CAT (test_on_line_, __LINE__) (char *src)	\
     208    {							\
     209      __builtin_strcpy (src, init);			\
     210      char *d = dst + off;				\
     211      __builtin_memcpy (d, src, n);			\
     212    } typedef void dummy_type
     213  
     214  T (a6, S4, 0, 4);
     215  T (a6, S4, 1, 4);
     216  T (a6, S4, 2, 4);
     217  T (a6, S4, 3, 4);   // { dg-warning "writing 4 bytes into a region of size 3" } */
     218  T (a6, S4, 4, 4);   // { dg-warning "writing 4 bytes into a region of size 2" } */
     219  T (a6, S4, 5, 4);   // { dg-warning "writing 4 bytes into a region of size 1" } */
     220  T (a6, S4, 6, 4);   // { dg-warning "writing 4 bytes into a region of size 0" } */
     221  
     222  T (a7, S4, 0, 4);
     223  T (a7, S4, 1, 4);
     224  T (a7, S4, 2, 4);
     225  T (a7, S4, 3, 4);
     226  T (a7, S4, 4, 4);   // { dg-warning "writing 4 bytes into a region of size 3" } */
     227  T (a7, S4, 5, 4);   // { dg-warning "writing 4 bytes into a region of size 2" } */
     228  T (a7, S4, 6, 4);   // { dg-warning "writing 4 bytes into a region of size 1" } */
     229  T (a7, S4, 7, 4);   // { dg-warning "writing 4 bytes into a region of size 0" } */
     230  
     231  T (a8, S3, 0, 4);
     232  T (a8, S3, 1, 4);
     233  T (a8, S3, 2, 4);
     234  T (a8, S3, 3, 4);
     235  T (a8, S3, 4, 4);
     236  T (a8, S3, 5, 4);   // { dg-warning "writing 4 bytes into a region of size 3" } */
     237  T (a8, S3, 6, 4);   // { dg-warning "writing 4 bytes into a region of size 2" } */
     238  T (a8, S3, 7, 4);   // { dg-warning "writing 4 bytes into a region of size 1" } */
     239  T (a8, S3, 8, 4);   // { dg-warning "writing 4 bytes into a region of size 0" } */