(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
Wsizeof-pointer-memaccess2.c
       1  /* Test -Wsizeof-pointer-memaccess warnings.  */
       2  /* { dg-do compile } */
       3  /* { dg-options "-Wall -O2 -Wno-array-bounds -Wno-sizeof-array-argument -Wno-stringop-truncation -ftrack-macro-expansion=0" } */
       4  /* { dg-options "-Wall -O2 -Wno-array-bounds -Wno-sizeof-array-argument -Wno-stringop-truncation -Wno-c++-compat -ftrack-macro-expansion=0" {target c} } */
       5  /* { dg-require-effective-target alloca } */
       6  
       7  #define bos(ptr) __builtin_object_size (ptr, 1)
       8  #define bos0(ptr) __builtin_object_size (ptr, 0)
       9  
      10  #define memset(dst, val, sz) __builtin___memset_chk (dst, val, sz, bos (dst))
      11  #define memcpy(dst, src, sz) __builtin___memcpy_chk (dst, src, sz, bos (dst))
      12  #define memmove(dst, src, sz) __builtin___memmove_chk (dst, src, sz, bos (dst))
      13  #define strncpy(dst, src, sz) __builtin___strncpy_chk (dst, src, sz, bos (dst))
      14  #define strncat(dst, src, sz) __builtin___strncat_chk (dst, src, sz, bos (dst))
      15  #define stpncpy(dst, src, sz) __builtin___stpncpy_chk (dst, src, sz, bos (dst))
      16  
      17  struct A { short a, b; int c, d; long e, f; };
      18  typedef struct A TA;
      19  typedef struct A *PA;
      20  typedef TA *PTA;
      21  struct B {};
      22  typedef struct B TB;
      23  typedef struct B *PB;
      24  typedef TB *PTB;
      25  typedef int X[3][3][3];
      26  
      27  void
      28  f1 (void *x)
      29  {
      30    struct A a, *pa1 = &a;
      31    TA *pa2 = &a;
      32    PA pa3 = &a;
      33    PTA pa4 = &a;
      34    memset (&a, 0, sizeof (&a));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
      35    memset (pa1, 0, sizeof (pa1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      36    memset (pa2, 0, sizeof pa2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      37    memset (pa3, 0, sizeof (pa3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      38    memset (pa4, 0, sizeof pa4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      39    memset (pa1, 0, sizeof (struct A *));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      40    memset (pa2, 0, sizeof (PTA));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      41    memset (pa3, 0, sizeof (PA));		    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      42    memset (pa4, 0, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      43  
      44    memcpy (&a, x, sizeof (&a));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
      45    memcpy (pa1, x, sizeof (pa1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      46    memcpy (pa2, x, sizeof pa2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      47    memcpy (pa3, x, sizeof (pa3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      48    memcpy (pa4, x, sizeof pa4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      49    memcpy (pa1, x, sizeof (struct A *));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      50    memcpy (pa2, x, sizeof (PTA));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      51    memcpy (pa3, x, sizeof (PA));		    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      52    memcpy (pa4, x, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      53  
      54    memcpy (x, &a, sizeof (&a));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
      55    memcpy (x, pa1, sizeof (pa1));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      56    memcpy (x, pa2, sizeof pa2);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      57    memcpy (x, pa3, sizeof (pa3));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      58    memcpy (x, pa4, sizeof pa4);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      59    memcpy (x, pa1, sizeof (struct A *));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      60    memcpy (x, pa2, sizeof (PTA));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      61    memcpy (x, pa3, sizeof (PA));		    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      62    memcpy (x, pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      63  
      64    memmove (&a, x, sizeof (&a));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
      65    memmove (pa1, x, sizeof (pa1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      66    memmove (pa2, x, sizeof pa2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      67    memmove (pa3, x, sizeof (pa3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      68    memmove (pa4, x, sizeof pa4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      69    memmove (pa1, x, sizeof (struct A *));    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      70    memmove (pa2, x, sizeof (PTA));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      71    memmove (pa3, x, sizeof (PA));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      72    memmove (pa4, x, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
      73  
      74    memmove (x, &a, sizeof (&a));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
      75    memmove (x, pa1, sizeof (pa1));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      76    memmove (x, pa2, sizeof pa2);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      77    memmove (x, pa3, sizeof (pa3));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      78    memmove (x, pa4, sizeof pa4);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      79    memmove (x, pa1, sizeof (struct A *));    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      80    memmove (x, pa2, sizeof (PTA));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      81    memmove (x, pa3, sizeof (PA));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      82    memmove (x, pa4, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      83  
      84    /* These are correct, no warning.  */
      85    memset (&a, 0, sizeof a);
      86    memset (&a, 0, sizeof (a));
      87    memset (&a, 0, sizeof (struct A));
      88    memset (&a, 0, sizeof (const struct A));
      89    memset (&a, 0, sizeof (volatile struct A));
      90    memset (&a, 0, sizeof (volatile const struct A));
      91    memset (&a, 0, sizeof (TA));
      92    memset (&a, 0, sizeof (__typeof (*&a)));
      93    memset (pa1, 0, sizeof (*pa1));
      94    memset (pa2, 0, sizeof (*pa3));
      95    memset (pa3, 0, sizeof (__typeof (*pa3)));
      96    /* These are probably broken, but obfuscated, no warning.  */
      97    memset ((void *) &a, 0, sizeof (&a));
      98    memset ((char *) &a, 0, sizeof (&a));
      99    memset (&a, 0, sizeof (&a) + 0);
     100    memset (&a, 0, 0 + sizeof (&a));
     101  
     102    /* These are correct, no warning.  */
     103    memcpy (&a, x, sizeof a);
     104    memcpy (&a, x, sizeof (a));
     105    memcpy (&a, x, sizeof (struct A));
     106    memcpy (&a, x, sizeof (const struct A));
     107    memcpy (&a, x, sizeof (volatile struct A));
     108    memcpy (&a, x, sizeof (volatile const struct A));
     109    memcpy (&a, x, sizeof (TA));
     110    memcpy (&a, x, sizeof (__typeof (*&a)));
     111    memcpy (pa1, x, sizeof (*pa1));
     112    memcpy (pa2, x, sizeof (*pa3));
     113    memcpy (pa3, x, sizeof (__typeof (*pa3)));
     114    /* These are probably broken, but obfuscated, no warning.  */
     115    memcpy ((void *) &a, x, sizeof (&a));
     116    memcpy ((char *) &a, x, sizeof (&a));
     117    memcpy (&a, x, sizeof (&a) + 0);
     118    memcpy (&a, x, 0 + sizeof (&a));
     119  
     120    /* These are correct, no warning.  */
     121    memcpy (x, &a, sizeof a);
     122    memcpy (x, &a, sizeof (a));
     123    memcpy (x, &a, sizeof (struct A));
     124    memcpy (x, &a, sizeof (const struct A));
     125    memcpy (x, &a, sizeof (volatile struct A));
     126    memcpy (x, &a, sizeof (volatile const struct A));
     127    memcpy (x, &a, sizeof (TA));
     128    memcpy (x, &a, sizeof (__typeof (*&a)));
     129    memcpy (x, pa1, sizeof (*pa1));
     130    memcpy (x, pa2, sizeof (*pa3));
     131    memcpy (x, pa3, sizeof (__typeof (*pa3)));
     132    /* These are probably broken, but obfuscated, no warning.  */
     133    memcpy (x, (void *) &a, sizeof (&a));
     134    memcpy (x, (char *) &a, sizeof (&a));
     135    memcpy (x, &a, sizeof (&a) + 0);
     136    memcpy (x, &a, 0 + sizeof (&a));
     137  
     138    /* These are correct, no warning.  */
     139    memmove (&a, x, sizeof a);
     140    memmove (&a, x, sizeof (a));
     141    memmove (&a, x, sizeof (struct A));
     142    memmove (&a, x, sizeof (const struct A));
     143    memmove (&a, x, sizeof (volatile struct A));
     144    memmove (&a, x, sizeof (volatile const struct A));
     145    memmove (&a, x, sizeof (TA));
     146    memmove (&a, x, sizeof (__typeof (*&a)));
     147    memmove (pa1, x, sizeof (*pa1));
     148    memmove (pa2, x, sizeof (*pa3));
     149    memmove (pa3, x, sizeof (__typeof (*pa3)));
     150    /* These are probably broken, but obfuscated, no warning.  */
     151    memmove ((void *) &a, x, sizeof (&a));
     152    memmove ((char *) &a, x, sizeof (&a));
     153    memmove (&a, x, sizeof (&a) + 0);
     154    memmove (&a, x, 0 + sizeof (&a));
     155  
     156    /* These are correct, no warning.  */
     157    memmove (x, &a, sizeof a);
     158    memmove (x, &a, sizeof (a));
     159    memmove (x, &a, sizeof (struct A));
     160    memmove (x, &a, sizeof (const struct A));
     161    memmove (x, &a, sizeof (volatile struct A));
     162    memmove (x, &a, sizeof (volatile const struct A));
     163    memmove (x, &a, sizeof (TA));
     164    memmove (x, &a, sizeof (__typeof (*&a)));
     165    memmove (x, pa1, sizeof (*pa1));
     166    memmove (x, pa2, sizeof (*pa3));
     167    memmove (x, pa3, sizeof (__typeof (*pa3)));
     168    /* These are probably broken, but obfuscated, no warning.  */
     169    memmove (x, (void *) &a, sizeof (&a));
     170    memmove (x, (char *) &a, sizeof (&a));
     171    memmove (x, &a, sizeof (&a) + 0);
     172    memmove (x, &a, 0 + sizeof (&a));
     173  }
     174  
     175  void
     176  f2 (void *x)
     177  {
     178    struct B b, *pb1 = &b;
     179    TB *pb2 = &b;
     180    PB pb3 = &b;
     181    PTB pb4 = &b;
     182    memset (&b, 0, sizeof (&b));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     183    memset (pb1, 0, sizeof (pb1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     184    memset (pb2, 0, sizeof pb2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     185    memset (pb3, 0, sizeof (pb3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     186    memset (pb4, 0, sizeof pb4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     187    memset (pb1, 0, sizeof (struct B *));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     188    memset (pb2, 0, sizeof (PTB));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     189    memset (pb3, 0, sizeof (PB));		    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     190    memset (pb4, 0, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     191  
     192    memcpy (&b, x, sizeof (&b));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     193    memcpy (pb1, x, sizeof (pb1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     194    memcpy (pb2, x, sizeof pb2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     195    memcpy (pb3, x, sizeof (pb3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     196    memcpy (pb4, x, sizeof pb4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     197    memcpy (pb1, x, sizeof (struct B *));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     198    memcpy (pb2, x, sizeof (PTB));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     199    memcpy (pb3, x, sizeof (PB));		    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     200    memcpy (pb4, x, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     201  
     202    memcpy (x, &b, sizeof (&b));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     203    memcpy (x, pb1, sizeof (pb1));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     204    memcpy (x, pb2, sizeof pb2);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     205    memcpy (x, pb3, sizeof (pb3));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     206    memcpy (x, pb4, sizeof pb4);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     207    memcpy (x, pb1, sizeof (struct B *));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
     208    memcpy (x, pb2, sizeof (PTB));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
     209    memcpy (x, pb3, sizeof (PB));		    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
     210    memcpy (x, pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
     211  
     212    memmove (&b, x, sizeof (&b));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     213    memmove (pb1, x, sizeof (pb1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     214    memmove (pb2, x, sizeof pb2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     215    memmove (pb3, x, sizeof (pb3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     216    memmove (pb4, x, sizeof pb4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     217    memmove (pb1, x, sizeof (struct B *));    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     218    memmove (pb2, x, sizeof (PTB));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     219    memmove (pb3, x, sizeof (PB));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     220    memmove (pb4, x, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
     221  
     222    memmove (x, &b, sizeof (&b));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     223    memmove (x, pb1, sizeof (pb1));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     224    memmove (x, pb2, sizeof pb2);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     225    memmove (x, pb3, sizeof (pb3));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     226    memmove (x, pb4, sizeof pb4);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     227    memmove (x, pb1, sizeof (struct B *));    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
     228    memmove (x, pb2, sizeof (PTB));    	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
     229    memmove (x, pb3, sizeof (PB));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
     230    memmove (x, pb4, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
     231  
     232    /* These are correct, no warning.  */
     233    memset (&b, 0, sizeof b);
     234    memset (&b, 0, sizeof (b));
     235    memset (&b, 0, sizeof (struct B));
     236    memset (&b, 0, sizeof (const struct B));
     237    memset (&b, 0, sizeof (volatile struct B));
     238    memset (&b, 0, sizeof (volatile const struct B));
     239    memset (&b, 0, sizeof (TB));
     240    memset (&b, 0, sizeof (__typeof (*&b)));
     241    memset (pb1, 0, sizeof (*pb1));
     242    memset (pb2, 0, sizeof (*pb3));
     243    memset (pb3, 0, sizeof (__typeof (*pb3)));
     244    /* These are probably broken, but obfuscated, no warning.  */
     245    memset ((void *) &b, 0, sizeof (&b));
     246    memset ((char *) &b, 0, sizeof (&b));
     247    memset (&b, 0, sizeof (&b) + 0);
     248    memset (&b, 0, 0 + sizeof (&b));
     249  
     250    /* These are correct, no warning.  */
     251    memcpy (&b, x, sizeof b);
     252    memcpy (&b, x, sizeof (b));
     253    memcpy (&b, x, sizeof (struct B));
     254    memcpy (&b, x, sizeof (const struct B));
     255    memcpy (&b, x, sizeof (volatile struct B));
     256    memcpy (&b, x, sizeof (volatile const struct B));
     257    memcpy (&b, x, sizeof (TB));
     258    memcpy (&b, x, sizeof (__typeof (*&b)));
     259    memcpy (pb1, x, sizeof (*pb1));
     260    memcpy (pb2, x, sizeof (*pb3));
     261    memcpy (pb3, x, sizeof (__typeof (*pb3)));
     262    /* These are probably broken, but obfuscated, no warning.  */
     263    memcpy ((void *) &b, x, sizeof (&b));
     264    memcpy ((char *) &b, x, sizeof (&b));
     265    memcpy (&b, x, sizeof (&b) + 0);
     266    memcpy (&b, x, 0 + sizeof (&b));
     267  
     268    /* These are correct, no warning.  */
     269    memcpy (x, &b, sizeof b);
     270    memcpy (x, &b, sizeof (b));
     271    memcpy (x, &b, sizeof (struct B));
     272    memcpy (x, &b, sizeof (const struct B));
     273    memcpy (x, &b, sizeof (volatile struct B));
     274    memcpy (x, &b, sizeof (volatile const struct B));
     275    memcpy (x, &b, sizeof (TB));
     276    memcpy (x, &b, sizeof (__typeof (*&b)));
     277    memcpy (x, pb1, sizeof (*pb1));
     278    memcpy (x, pb2, sizeof (*pb3));
     279    memcpy (x, pb3, sizeof (__typeof (*pb3)));
     280    /* These are probably broken, but obfuscated, no warning.  */
     281    memcpy (x, (void *) &b, sizeof (&b));
     282    memcpy (x, (char *) &b, sizeof (&b));
     283    memcpy (x, &b, sizeof (&b) + 0);
     284    memcpy (x, &b, 0 + sizeof (&b));
     285  
     286    /* These are correct, no warning.  */
     287    memmove (&b, x, sizeof b);
     288    memmove (&b, x, sizeof (b));
     289    memmove (&b, x, sizeof (struct B));
     290    memmove (&b, x, sizeof (const struct B));
     291    memmove (&b, x, sizeof (volatile struct B));
     292    memmove (&b, x, sizeof (volatile const struct B));
     293    memmove (&b, x, sizeof (TB));
     294    memmove (&b, x, sizeof (__typeof (*&b)));
     295    memmove (pb1, x, sizeof (*pb1));
     296    memmove (pb2, x, sizeof (*pb3));
     297    memmove (pb3, x, sizeof (__typeof (*pb3)));
     298    /* These are probably broken, but obfuscated, no warning.  */
     299    memmove ((void *) &b, x, sizeof (&b));
     300    memmove ((char *) &b, x, sizeof (&b));
     301    memmove (&b, x, sizeof (&b) + 0);
     302    memmove (&b, x, 0 + sizeof (&b));
     303  
     304    /* These are correct, no warning.  */
     305    memmove (x, &b, sizeof b);
     306    memmove (x, &b, sizeof (b));
     307    memmove (x, &b, sizeof (struct B));
     308    memmove (x, &b, sizeof (const struct B));
     309    memmove (x, &b, sizeof (volatile struct B));
     310    memmove (x, &b, sizeof (volatile const struct B));
     311    memmove (x, &b, sizeof (TB));
     312    memmove (x, &b, sizeof (__typeof (*&b)));
     313    memmove (x, pb1, sizeof (*pb1));
     314    memmove (x, pb2, sizeof (*pb3));
     315    memmove (x, pb3, sizeof (__typeof (*pb3)));
     316    /* These are probably broken, but obfuscated, no warning.  */
     317    memmove (x, (void *) &b, sizeof (&b));
     318    memmove (x, (char *) &b, sizeof (&b));
     319    memmove (x, &b, sizeof (&b) + 0);
     320    memmove (x, &b, 0 + sizeof (&b));
     321  }
     322  
     323  void
     324  f3 (void *x, char *y, int z, X w)
     325  {
     326    unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
     327    char buf1[7];
     328    signed char buf2[z + 32];
     329    long buf3[17];
     330    int *buf4[9];
     331    signed char *y2 = buf2;
     332    char c;
     333    char *y3;
     334    memset (y, 0, sizeof (y));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     335    memset (y1, 0, sizeof (y1));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     336    memset (y2, 0, sizeof (y2));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     337    memset (&c, 0, sizeof (&c));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     338    memset (w, 0, sizeof w);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     339  
     340    memcpy (y, x, sizeof (y));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     341    memcpy (y1, x, sizeof (y1));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     342    memcpy (y2, x, sizeof (y2));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     343    memcpy (&c, x, sizeof (&c));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     344    memcpy (w, x, sizeof w);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     345  
     346    memcpy (x, y, sizeof (y));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     347    memcpy (x, y1, sizeof (y1));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     348    memcpy (x, y2, sizeof (y2));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     349    memcpy (x, &c, sizeof (&c));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     350    memcpy (x, w, sizeof w);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     351  
     352    memmove (y, x, sizeof (y));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     353    memmove (y1, x, sizeof (y1));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     354    memmove (y2, x, sizeof (y2));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     355    memmove (&c, x, sizeof (&c));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     356    memmove (w, x, sizeof w);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     357  
     358    memmove (x, y, sizeof (y));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     359    memmove (x, y1, sizeof (y1));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     360    memmove (x, y2, sizeof (y2));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     361    memmove (x, &c, sizeof (&c));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     362    memmove (x, w, sizeof w);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     363  
     364    /* These are correct, no warning.  */
     365    memset (y, 0, sizeof (*y));
     366    memset (y1, 0, sizeof (*y2));
     367    memset (buf1, 0, sizeof buf1);
     368    memset (buf3, 0, sizeof (buf3));
     369    memset (&buf3[0], 0, sizeof (buf3));
     370    memset (&buf4[0], 0, sizeof (buf4));
     371    memset (w, 0, sizeof (X));
     372    /* These are probably broken, but obfuscated, no warning.  */
     373    memset ((void *) y, 0, sizeof (y));
     374    memset ((char *) y1, 0, sizeof (y2));
     375    memset (y, 0, sizeof (y) + 0);
     376    memset (y1, 0, 0 + sizeof (y2));
     377    memset ((void *) &c, 0, sizeof (&c));
     378    memset ((signed char *) &c, 0, sizeof (&c));
     379    memset (&c, 0, sizeof (&c) + 0);
     380    memset (&c, 0, 0 + sizeof (&c));
     381  
     382    /* These are correct, no warning.  */
     383    memcpy (y, x, sizeof (*y));
     384    memcpy (y1, x, sizeof (*y2));
     385    memcpy (buf1, x, sizeof buf1);
     386    memcpy (buf3, x, sizeof (buf3));
     387    memcpy (&buf3[0], x, sizeof (buf3));
     388    memcpy (&buf4[0], x, sizeof (buf4));
     389    memcpy (&y3, y, sizeof (y3));
     390    memcpy ((char *) &y3, y, sizeof (y3));
     391    memcpy (w, x, sizeof (X));
     392    /* These are probably broken, but obfuscated, no warning.  */
     393    memcpy ((void *) y, x, sizeof (y));
     394    memcpy ((char *) y1, x, sizeof (y2));
     395    memcpy (y, x, sizeof (y) + 0);
     396    memcpy (y1, x, 0 + sizeof (y2));
     397    memcpy ((void *) &c, x, sizeof (&c));
     398    memcpy ((signed char *) &c, x, sizeof (&c));
     399    memcpy (&c, x, sizeof (&c) + 0);
     400    memcpy (&c, x, 0 + sizeof (&c));
     401  
     402    /* These are correct, no warning.  */
     403    memcpy (x, y, sizeof (*y));
     404    memcpy (x, y1, sizeof (*y2));
     405    memcpy (x, buf1, sizeof buf1);
     406    memcpy (x, buf3, sizeof (buf3));
     407    memcpy (x, &buf3[0], sizeof (buf3));
     408    memcpy (x, &buf4[0], sizeof (buf4));
     409    memcpy (y, &y3, sizeof (y3));
     410    memcpy (y, (char *) &y3, sizeof (y3));
     411    memcpy (x, w, sizeof (X));
     412    /* These are probably broken, but obfuscated, no warning.  */
     413    memcpy (x, (void *) y, sizeof (y));
     414    memcpy (x, (char *) y1, sizeof (y2));
     415    memcpy (x, y, sizeof (y) + 0);
     416    memcpy (x, y1, 0 + sizeof (y2));
     417    memcpy (x, (void *) &c, sizeof (&c));
     418    memcpy (x, (signed char *) &c, sizeof (&c));
     419    memcpy (x, &c, sizeof (&c) + 0);
     420    memcpy (x, &c, 0 + sizeof (&c));
     421  
     422    /* These are correct, no warning.  */
     423    memmove (y, x, sizeof (*y));
     424    memmove (y1, x, sizeof (*y2));
     425    memmove (buf1, x, sizeof buf1);
     426    memmove (buf3, x, sizeof (buf3));
     427    memmove (&buf3[0], x, sizeof (buf3));
     428    memmove (&buf4[0], x, sizeof (buf4));
     429    memmove (&y3, y, sizeof (y3));
     430    memmove ((char *) &y3, y, sizeof (y3));
     431    memmove (w, x, sizeof (X));
     432    /* These are probably broken, but obfuscated, no warning.  */
     433    memmove ((void *) y, x, sizeof (y));
     434    memmove ((char *) y1, x, sizeof (y2));
     435    memmove (y, x, sizeof (y) + 0);
     436    memmove (y1, x, 0 + sizeof (y2));
     437    memmove ((void *) &c, x, sizeof (&c));
     438    memmove ((signed char *) &c, x, sizeof (&c));
     439    memmove (&c, x, sizeof (&c) + 0);
     440    memmove (&c, x, 0 + sizeof (&c));
     441  
     442    /* These are correct, no warning.  */
     443    memmove (x, y, sizeof (*y));
     444    memmove (x, y1, sizeof (*y2));
     445    memmove (x, buf1, sizeof buf1);
     446    memmove (x, buf3, sizeof (buf3));
     447    memmove (x, &buf3[0], sizeof (buf3));
     448    memmove (x, &buf4[0], sizeof (buf4));
     449    memmove (y, &y3, sizeof (y3));
     450    memmove (y, (char *) &y3, sizeof (y3));
     451    memmove (x, w, sizeof (X));
     452    /* These are probably broken, but obfuscated, no warning.  */
     453    memmove (x, (void *) y, sizeof (y));
     454    memmove (x, (char *) y1, sizeof (y2));
     455    memmove (x, y, sizeof (y) + 0);
     456    memmove (x, y1, 0 + sizeof (y2));
     457    memmove (x, (void *) &c, sizeof (&c));
     458    memmove (x, (signed char *) &c, sizeof (&c));
     459    memmove (x, &c, sizeof (&c) + 0);
     460    memmove (x, &c, 0 + sizeof (&c));
     461  }
     462  
     463  void
     464  f4 (char *x, char **y, int z, char w[64])
     465  {
     466    const char *s1 = "foobarbaz";
     467    const char *s2 = "abcde12345678";
     468    strncpy (x, s1, sizeof (s1));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     469    strncat (x, s2, sizeof (s2));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     470    stpncpy (x, s1, sizeof (s1));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     471  
     472    strncpy (w, s1, sizeof (w));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     473    strncat (w, s2, sizeof (w));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     474    stpncpy (w, s1, sizeof (w));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     475  
     476    /* These are pointless when the destination is large enough, and
     477       cause overflow otherwise.  If the copies are guaranteed to be
     478       safe the calls might as well be replaced by strcat(), strcpy(),
     479       or memcpy().  */
     480    const char s3[] = "foobarbaz";
     481    const char s4[] = "abcde12345678";
     482    strncpy (x, s3, sizeof (s3));             /* { dg-warning "call is the same expression as the source; did you mean to use the size of the destination?" } */
     483    strncat (x, s4, sizeof (s4));             /* { dg-warning "call is the same expression as the source; did you mean to use the size of the destination?" } */
     484    stpncpy (x, s3, sizeof (s3));             /* { dg-warning "call is the same expression as the source; did you mean to use the size of the destination?" } */
     485  }
     486  
     487  /* { dg-prune-output "\[\n\r\]*writing\[\n\r\]*" } */
     488  /* { dg-prune-output "\[\n\r\]*reading\[\n\r\]*" } */