1  /* Test -Wsizeof-pointer-memaccess warnings.  */
       2  /* { dg-do compile } */
       3  /* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument -Wno-stringop-overflow -Wno-stringop-overread -Wno-stringop-truncation" } */
       4  /* Test just twice, once with -O0 non-fortified, once with -O2 fortified.  */
       5  /* { dg-skip-if "" { *-*-* }  { "*" } { "-O0" "-O2" } } */
       6  /* { dg-skip-if "" { *-*-* }  { "-flto" } { "" } } */
       7  /* { dg-require-effective-target alloca } */
       8  
       9  typedef __SIZE_TYPE__ size_t;
      10  extern void *memset (void *, int, size_t);
      11  extern void *memcpy (void *__restrict, const void *__restrict, size_t);
      12  extern void *memmove (void *__restrict, const void *__restrict, size_t);
      13  extern int memcmp (const void *, const void *, size_t);
      14  extern char *strncpy (char *__restrict, const char *__restrict, size_t);
      15  extern char *strncat (char *__restrict, const char *__restrict, size_t);
      16  extern char *stpncpy (char *__restrict, const char *__restrict, size_t);
      17  extern char *strndup (const char *, size_t);
      18  extern int strncmp (const char *, const char *, size_t);
      19  extern int strncasecmp (const char *, const char *, size_t);
      20  
      21  #ifdef __OPTIMIZE__
      22  # define bos(ptr) __builtin_object_size (ptr, 1)
      23  # define bos0(ptr) __builtin_object_size (ptr, 0)
      24  
      25  __attribute__((__always_inline__, __gnu_inline__, __artificial__))
      26  extern inline void *
      27  memset (void *dest, int c, size_t len)
      28  {
      29    return __builtin___memset_chk (dest, c, len, bos0 (dest));
      30  }
      31  
      32  __attribute__((__always_inline__, __gnu_inline__, __artificial__))
      33  extern inline void *
      34  memcpy (void *__restrict dest, const void *__restrict src, size_t len)
      35  {
      36    return __builtin___memcpy_chk (dest, src, len, bos0 (dest));
      37  }
      38  
      39  __attribute__((__always_inline__, __gnu_inline__, __artificial__))
      40  extern inline void *
      41  memmove (void *dest, const void *src, size_t len)
      42  {
      43    return __builtin___memmove_chk (dest, src, len, bos0 (dest));
      44  }
      45  
      46  __attribute__((__always_inline__, __gnu_inline__, __artificial__))
      47  extern inline char *
      48  strncpy (char *__restrict dest, const char *__restrict src, size_t len)
      49  {
      50    return __builtin___strncpy_chk (dest, src, len, bos (dest));
      51  }
      52  
      53  __attribute__((__always_inline__, __gnu_inline__, __artificial__))
      54  extern inline char *
      55  strncat (char *dest, const char *src, size_t len)
      56  {
      57    return __builtin___strncat_chk (dest, src, len, bos (dest));
      58  }
      59  
      60  __attribute__((__always_inline__, __gnu_inline__, __artificial__))
      61  extern inline char *
      62  stpncpy (char *__restrict dest, const char *__restrict src, size_t len)
      63  {
      64    return __builtin___stpncpy_chk (dest, src, len, bos (dest));
      65  }
      66  #endif
      67  
      68  struct A { short a, b; int c, d; long e, f; };
      69  typedef struct A TA;
      70  typedef struct A *PA;
      71  typedef TA *PTA;
      72  struct B {};
      73  typedef struct B TB;
      74  typedef struct B *PB;
      75  typedef TB *PTB;
      76  typedef int X[3][3][3];
      77  
      78  int
      79  f1 (void *x, int z)
      80  {
      81    struct A a, *pa1 = &a;
      82    TA *pa2 = &a;
      83    PA pa3 = &a;
      84    PTA pa4 = &a;
      85    memset (&a, 0, sizeof (&a));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
      86    memset (pa1, 0, sizeof (pa1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      87    memset (pa2, 0, sizeof pa2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      88    memset (pa3, 0, sizeof (pa3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      89    memset (pa4, 0, sizeof pa4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      90    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" } */
      91    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" } */
      92    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" } */
      93    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" } */
      94  
      95    memcpy (&a, x, sizeof (&a));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
      96    memcpy (pa1, x, sizeof (pa1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      97    memcpy (pa2, x, sizeof pa2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      98    memcpy (pa3, x, sizeof (pa3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
      99    memcpy (pa4, x, sizeof pa4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     100    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" } */
     101    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" } */
     102    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" } */
     103    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" } */
     104  
     105    memcpy (x, &a, sizeof (&a));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     106    memcpy (x, pa1, sizeof (pa1));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     107    memcpy (x, pa2, sizeof pa2);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     108    memcpy (x, pa3, sizeof (pa3));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     109    memcpy (x, pa4, sizeof pa4);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     110    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" } */
     111    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" } */
     112    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" } */
     113    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" } */
     114  
     115    memmove (&a, x, sizeof (&a));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     116    memmove (pa1, x, sizeof (pa1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     117    memmove (pa2, x, sizeof pa2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     118    memmove (pa3, x, sizeof (pa3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     119    memmove (pa4, x, sizeof pa4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     120    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" } */
     121    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" } */
     122    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" } */
     123    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" } */
     124  
     125    memmove (x, &a, sizeof (&a));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     126    memmove (x, pa1, sizeof (pa1));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     127    memmove (x, pa2, sizeof pa2);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     128    memmove (x, pa3, sizeof (pa3));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     129    memmove (x, pa4, sizeof pa4);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     130    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" } */
     131    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" } */
     132    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" } */
     133    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" } */
     134  
     135    z += memcmp (&a, x, sizeof (&a));	    /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
     136    z += memcmp (pa1, x, sizeof (pa1));	    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     137    z += memcmp (pa2, x, sizeof pa2);	    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     138    z += memcmp (pa3, x, sizeof (pa3));	    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     139    z += memcmp (pa4, x, sizeof pa4);	    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     140    z += memcmp (pa1, x, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
     141    z += memcmp (pa2, x, sizeof (PTA));       /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
     142    z += memcmp (pa3, x, sizeof (PA));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
     143  
     144    z += memcmp (x, &a, sizeof (&a));	    /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
     145    z += memcmp (x, pa1, sizeof (pa1));	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     146    z += memcmp (x, pa2, sizeof pa2);	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     147    z += memcmp (x, pa3, sizeof (pa3));	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     148    z += memcmp (x, pa4, sizeof pa4);	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     149    z += memcmp (x, pa1, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     150    z += memcmp (x, pa2, sizeof (PTA));       /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     151    z += memcmp (x, pa3, sizeof (PA));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     152  
     153    z += memcmp (x, (&a), (sizeof (&a)));	    /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
     154    z += memcmp (x, (pa1), (sizeof (pa1)));   /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     155    z += memcmp (x, (pa2), (sizeof pa2));	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     156    z += memcmp (x, (pa3), (sizeof (pa3)));   /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     157    z += memcmp (x, (pa4), (sizeof pa4));	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     158    z += memcmp (x, (pa1), (sizeof (struct A *)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     159    z += memcmp (x, (pa2), (sizeof (PTA)));   /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     160    z += memcmp (x, (pa3), (sizeof (PA)));    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     161  
     162    /* These are correct, no warning.  */
     163    memset (&a, 0, sizeof a);
     164    memset (&a, 0, sizeof (a));
     165    memset (&a, 0, sizeof (struct A));
     166    memset (&a, 0, sizeof (const struct A));
     167    memset (&a, 0, sizeof (volatile struct A));
     168    memset (&a, 0, sizeof (volatile const struct A));
     169    memset (&a, 0, sizeof (TA));
     170    memset (&a, 0, sizeof (__typeof (*&a)));
     171    memset (pa1, 0, sizeof (*pa1));
     172    memset (pa2, 0, sizeof (*pa3));
     173    memset (pa3, 0, sizeof (__typeof (*pa3)));
     174    /* These are probably broken, but obfuscated, no warning.  */
     175    memset ((void *) &a, 0, sizeof (&a));
     176    memset ((char *) &a, 0, sizeof (&a));
     177    memset (&a, 0, sizeof (&a) + 0);
     178    memset (&a, 0, 0 + sizeof (&a));
     179  
     180    /* These are correct, no warning.  */
     181    memcpy (&a, x, sizeof a);
     182    memcpy (&a, x, sizeof (a));
     183    memcpy (&a, x, sizeof (struct A));
     184    memcpy (&a, x, sizeof (const struct A));
     185    memcpy (&a, x, sizeof (volatile struct A));
     186    memcpy (&a, x, sizeof (volatile const struct A));
     187    memcpy (&a, x, sizeof (TA));
     188    memcpy (&a, x, sizeof (__typeof (*&a)));
     189    memcpy (pa1, x, sizeof (*pa1));
     190    memcpy (pa2, x, sizeof (*pa3));
     191    memcpy (pa3, x, sizeof (__typeof (*pa3)));
     192    /* These are probably broken, but obfuscated, no warning.  */
     193    memcpy ((void *) &a, x, sizeof (&a));
     194    memcpy ((char *) &a, x, sizeof (&a));
     195    memcpy (&a, x, sizeof (&a) + 0);
     196    memcpy (&a, x, 0 + sizeof (&a));
     197  
     198    /* These are correct, no warning.  */
     199    memcpy (x, &a, sizeof a);
     200    memcpy (x, &a, sizeof (a));
     201    memcpy (x, &a, sizeof (struct A));
     202    memcpy (x, &a, sizeof (const struct A));
     203    memcpy (x, &a, sizeof (volatile struct A));
     204    memcpy (x, &a, sizeof (volatile const struct A));
     205    memcpy (x, &a, sizeof (TA));
     206    memcpy (x, &a, sizeof (__typeof (*&a)));
     207    memcpy (x, pa1, sizeof (*pa1));
     208    memcpy (x, pa2, sizeof (*pa3));
     209    memcpy (x, pa3, sizeof (__typeof (*pa3)));
     210    /* These are probably broken, but obfuscated, no warning.  */
     211    memcpy (x, (void *) &a, sizeof (&a));
     212    memcpy (x, (char *) &a, sizeof (&a));
     213    memcpy (x, &a, sizeof (&a) + 0);
     214    memcpy (x, &a, 0 + sizeof (&a));
     215  
     216    /* These are correct, no warning.  */
     217    memmove (&a, x, sizeof a);
     218    memmove (&a, x, sizeof (a));
     219    memmove (&a, x, sizeof (struct A));
     220    memmove (&a, x, sizeof (const struct A));
     221    memmove (&a, x, sizeof (volatile struct A));
     222    memmove (&a, x, sizeof (volatile const struct A));
     223    memmove (&a, x, sizeof (TA));
     224    memmove (&a, x, sizeof (__typeof (*&a)));
     225    memmove (pa1, x, sizeof (*pa1));
     226    memmove (pa2, x, sizeof (*pa3));
     227    memmove (pa3, x, sizeof (__typeof (*pa3)));
     228    /* These are probably broken, but obfuscated, no warning.  */
     229    memmove ((void *) &a, x, sizeof (&a));
     230    memmove ((char *) &a, x, sizeof (&a));
     231    memmove (&a, x, sizeof (&a) + 0);
     232    memmove (&a, x, 0 + sizeof (&a));
     233  
     234    /* These are correct, no warning.  */
     235    memmove (x, &a, sizeof a);
     236    memmove (x, &a, sizeof (a));
     237    memmove (x, &a, sizeof (struct A));
     238    memmove (x, &a, sizeof (const struct A));
     239    memmove (x, &a, sizeof (volatile struct A));
     240    memmove (x, &a, sizeof (volatile const struct A));
     241    memmove (x, &a, sizeof (TA));
     242    memmove (x, &a, sizeof (__typeof (*&a)));
     243    memmove (x, pa1, sizeof (*pa1));
     244    memmove (x, pa2, sizeof (*pa3));
     245    memmove (x, pa3, sizeof (__typeof (*pa3)));
     246    /* These are probably broken, but obfuscated, no warning.  */
     247    memmove (x, (void *) &a, sizeof (&a));
     248    memmove (x, (char *) &a, sizeof (&a));
     249    memmove (x, &a, sizeof (&a) + 0);
     250    memmove (x, &a, 0 + sizeof (&a));
     251  
     252    /* These are correct, no warning.  */
     253    z += memcmp (&a, x, sizeof a);
     254    z += memcmp (&a, x, sizeof (a));
     255    z += memcmp (&a, x, sizeof (struct A));
     256    z += memcmp (&a, x, sizeof (const struct A));
     257    z += memcmp (&a, x, sizeof (volatile struct A));
     258    z += memcmp (&a, x, sizeof (volatile const struct A));
     259    z += memcmp (&a, x, sizeof (TA));
     260    z += memcmp (&a, x, sizeof (__typeof (*&a)));
     261    z += memcmp (pa1, x, sizeof (*pa1));
     262    z += memcmp (pa2, x, sizeof (*pa3));
     263    z += memcmp (pa3, x, sizeof (__typeof (*pa3)));
     264    /* These are probably broken, but obfuscated, no warning.  */
     265    z += memcmp ((void *) &a, x, sizeof (&a));
     266    z += memcmp ((char *) &a, x, sizeof (&a));
     267    z += memcmp (&a, x, sizeof (&a) + 0);
     268    z += memcmp (&a, x, 0 + sizeof (&a));
     269  
     270    /* These are correct, no warning.  */
     271    z += memcmp (x, &a, sizeof a);
     272    z += memcmp (x, &a, sizeof (a));
     273    z += memcmp (x, &a, sizeof (struct A));
     274    z += memcmp (x, &a, sizeof (const struct A));
     275    z += memcmp (x, &a, sizeof (volatile struct A));
     276    z += memcmp (x, &a, sizeof (volatile const struct A));
     277    z += memcmp (x, &a, sizeof (TA));
     278    z += memcmp (x, &a, sizeof (__typeof (*&a)));
     279    z += memcmp (x, pa1, sizeof (*pa1));
     280    z += memcmp (x, pa2, sizeof (*pa3));
     281    z += memcmp (x, pa3, sizeof (__typeof (*pa3)));
     282    /* These are probably broken, but obfuscated, no warning.  */
     283    z += memcmp (x, (void *) &a, sizeof (&a));
     284    z += memcmp (x, (char *) &a, sizeof (&a));
     285    z += memcmp (x, &a, sizeof (&a) + 0);
     286    z += memcmp (x, &a, 0 + sizeof (&a));
     287  
     288    return z;
     289  }
     290  
     291  int
     292  f2 (void *x, int z)
     293  {
     294    struct B b, *pb1 = &b;
     295    TB *pb2 = &b;
     296    PB pb3 = &b;
     297    PTB pb4 = &b;
     298    memset (&b, 0, sizeof (&b));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     299    memset (pb1, 0, sizeof (pb1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     300    memset (pb2, 0, sizeof pb2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     301    memset (pb3, 0, sizeof (pb3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     302    memset (pb4, 0, sizeof pb4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     303    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" } */
     304    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" } */
     305    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" } */
     306    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" } */
     307  
     308    memcpy (&b, x, sizeof (&b));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     309    memcpy (pb1, x, sizeof (pb1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     310    memcpy (pb2, x, sizeof pb2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     311    memcpy (pb3, x, sizeof (pb3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     312    memcpy (pb4, x, sizeof pb4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     313    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" } */
     314    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" } */
     315    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" } */
     316    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" } */
     317  
     318    memcpy (x, &b, sizeof (&b));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     319    memcpy (x, pb1, sizeof (pb1));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     320    memcpy (x, pb2, sizeof pb2);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     321    memcpy (x, pb3, sizeof (pb3));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     322    memcpy (x, pb4, sizeof pb4);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     323    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" } */
     324    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" } */
     325    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" } */
     326    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" } */
     327  
     328    memmove (&b, x, sizeof (&b));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     329    memmove (pb1, x, sizeof (pb1));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     330    memmove (pb2, x, sizeof pb2);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     331    memmove (pb3, x, sizeof (pb3));	    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     332    memmove (pb4, x, sizeof pb4);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     333    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" } */
     334    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" } */
     335    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" } */
     336    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" } */
     337  
     338    memmove (x, &b, sizeof (&b));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     339    memmove (x, pb1, sizeof (pb1));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     340    memmove (x, pb2, sizeof pb2);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     341    memmove (x, pb3, sizeof (pb3));	    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     342    memmove (x, pb4, sizeof pb4);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     343    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" } */
     344    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" } */
     345    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" } */
     346    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" } */
     347  
     348    z += memcmp (&b, x, sizeof (&b));	    /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
     349    z += memcmp (pb1, x, sizeof (pb1));	    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     350    z += memcmp (pb2, x, sizeof pb2);	    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     351    z += memcmp (pb3, x, sizeof (pb3));	    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     352    z += memcmp (pb4, x, sizeof pb4);	    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     353    z += memcmp (pb1, x, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
     354    z += memcmp (pb2, x, sizeof (PTB));       /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
     355    z += memcmp (pb3, x, sizeof (PB));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
     356  
     357    z += memcmp (x, &b, sizeof (&b));	    /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
     358    z += memcmp (x, pb1, sizeof (pb1));	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     359    z += memcmp (x, pb2, sizeof pb2);	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     360    z += memcmp (x, pb3, sizeof (pb3));	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     361    z += memcmp (x, pb4, sizeof pb4);	    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     362    z += memcmp (x, pb1, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     363    z += memcmp (x, pb2, sizeof (PTB));       /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     364    z += memcmp (x, pb3, sizeof (PB));	    /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
     365  
     366    /* These are correct, no warning.  */
     367    memset (&b, 0, sizeof b);
     368    memset (&b, 0, sizeof (b));
     369    memset (&b, 0, sizeof (struct B));
     370    memset (&b, 0, sizeof (const struct B));
     371    memset (&b, 0, sizeof (volatile struct B));
     372    memset (&b, 0, sizeof (volatile const struct B));
     373    memset (&b, 0, sizeof (TB));
     374    memset (&b, 0, sizeof (__typeof (*&b)));
     375    memset (pb1, 0, sizeof (*pb1));
     376    memset (pb2, 0, sizeof (*pb3));
     377    memset (pb3, 0, sizeof (__typeof (*pb3)));
     378    /* These are probably broken, but obfuscated, no warning.  */
     379    memset ((void *) &b, 0, sizeof (&b));
     380    memset ((char *) &b, 0, sizeof (&b));
     381    memset (&b, 0, sizeof (&b) + 0);
     382    memset (&b, 0, 0 + sizeof (&b));
     383  
     384    /* These are correct, no warning.  */
     385    memcpy (&b, x, sizeof b);
     386    memcpy (&b, x, sizeof (b));
     387    memcpy (&b, x, sizeof (struct B));
     388    memcpy (&b, x, sizeof (const struct B));
     389    memcpy (&b, x, sizeof (volatile struct B));
     390    memcpy (&b, x, sizeof (volatile const struct B));
     391    memcpy (&b, x, sizeof (TB));
     392    memcpy (&b, x, sizeof (__typeof (*&b)));
     393    memcpy (pb1, x, sizeof (*pb1));
     394    memcpy (pb2, x, sizeof (*pb3));
     395    memcpy (pb3, x, sizeof (__typeof (*pb3)));
     396    /* These are probably broken, but obfuscated, no warning.  */
     397    memcpy ((void *) &b, x, sizeof (&b));
     398    memcpy ((char *) &b, x, sizeof (&b));
     399    memcpy (&b, x, sizeof (&b) + 0);
     400    memcpy (&b, x, 0 + sizeof (&b));
     401  
     402    /* These are correct, no warning.  */
     403    memcpy (x, &b, sizeof b);
     404    memcpy (x, &b, sizeof (b));
     405    memcpy (x, &b, sizeof (struct B));
     406    memcpy (x, &b, sizeof (const struct B));
     407    memcpy (x, &b, sizeof (volatile struct B));
     408    memcpy (x, &b, sizeof (volatile const struct B));
     409    memcpy (x, &b, sizeof (TB));
     410    memcpy (x, &b, sizeof (__typeof (*&b)));
     411    memcpy (x, pb1, sizeof (*pb1));
     412    memcpy (x, pb2, sizeof (*pb3));
     413    memcpy (x, pb3, sizeof (__typeof (*pb3)));
     414    /* These are probably broken, but obfuscated, no warning.  */
     415    memcpy (x, (void *) &b, sizeof (&b));
     416    memcpy (x, (char *) &b, sizeof (&b));
     417    memcpy (x, &b, sizeof (&b) + 0);
     418    memcpy (x, &b, 0 + sizeof (&b));
     419  
     420    /* These are correct, no warning.  */
     421    memmove (&b, x, sizeof b);
     422    memmove (&b, x, sizeof (b));
     423    memmove (&b, x, sizeof (struct B));
     424    memmove (&b, x, sizeof (const struct B));
     425    memmove (&b, x, sizeof (volatile struct B));
     426    memmove (&b, x, sizeof (volatile const struct B));
     427    memmove (&b, x, sizeof (TB));
     428    memmove (&b, x, sizeof (__typeof (*&b)));
     429    memmove (pb1, x, sizeof (*pb1));
     430    memmove (pb2, x, sizeof (*pb3));
     431    memmove (pb3, x, sizeof (__typeof (*pb3)));
     432    /* These are probably broken, but obfuscated, no warning.  */
     433    memmove ((void *) &b, x, sizeof (&b));
     434    memmove ((char *) &b, x, sizeof (&b));
     435    memmove (&b, x, sizeof (&b) + 0);
     436    memmove (&b, x, 0 + sizeof (&b));
     437  
     438    /* These are correct, no warning.  */
     439    memmove (x, &b, sizeof b);
     440    memmove (x, &b, sizeof (b));
     441    memmove (x, &b, sizeof (struct B));
     442    memmove (x, &b, sizeof (const struct B));
     443    memmove (x, &b, sizeof (volatile struct B));
     444    memmove (x, &b, sizeof (volatile const struct B));
     445    memmove (x, &b, sizeof (TB));
     446    memmove (x, &b, sizeof (__typeof (*&b)));
     447    memmove (x, pb1, sizeof (*pb1));
     448    memmove (x, pb2, sizeof (*pb3));
     449    memmove (x, pb3, sizeof (__typeof (*pb3)));
     450    /* These are probably broken, but obfuscated, no warning.  */
     451    memmove (x, (void *) &b, sizeof (&b));
     452    memmove (x, (char *) &b, sizeof (&b));
     453    memmove (x, &b, sizeof (&b) + 0);
     454    memmove (x, &b, 0 + sizeof (&b));
     455  
     456    /* These are correct, no warning.  */
     457    z += memcmp (&b, x, sizeof b);
     458    z += memcmp (&b, x, sizeof (b));
     459    z += memcmp (&b, x, sizeof (struct B));
     460    z += memcmp (&b, x, sizeof (const struct B));
     461    z += memcmp (&b, x, sizeof (volatile struct B));
     462    z += memcmp (&b, x, sizeof (volatile const struct B));
     463    z += memcmp (&b, x, sizeof (TB));
     464    z += memcmp (&b, x, sizeof (__typeof (*&b)));
     465    z += memcmp (pb1, x, sizeof (*pb1));
     466    z += memcmp (pb2, x, sizeof (*pb3));
     467    z += memcmp (pb3, x, sizeof (__typeof (*pb3)));
     468    /* These are probably broken, but obfuscated, no warning.  */
     469    z += memcmp ((void *) &b, x, sizeof (&b));
     470    z += memcmp ((char *) &b, x, sizeof (&b));
     471    z += memcmp (&b, x, sizeof (&b) + 0);
     472    z += memcmp (&b, x, 0 + sizeof (&b));
     473  
     474    /* These are correct, no warning.  */
     475    z += memcmp (x, &b, sizeof b);
     476    z += memcmp (x, &b, sizeof (b));
     477    z += memcmp (x, &b, sizeof (struct B));
     478    z += memcmp (x, &b, sizeof (const struct B));
     479    z += memcmp (x, &b, sizeof (volatile struct B));
     480    z += memcmp (x, &b, sizeof (volatile const struct B));
     481    z += memcmp (x, &b, sizeof (TB));
     482    z += memcmp (x, &b, sizeof (__typeof (*&b)));
     483    z += memcmp (x, pb1, sizeof (*pb1));
     484    z += memcmp (x, pb2, sizeof (*pb3));
     485    z += memcmp (x, pb3, sizeof (__typeof (*pb3)));
     486    /* These are probably broken, but obfuscated, no warning.  */
     487    z += memcmp (x, (void *) &b, sizeof (&b));
     488    z += memcmp (x, (char *) &b, sizeof (&b));
     489    z += memcmp (x, &b, sizeof (&b) + 0);
     490    z += memcmp (x, &b, 0 + sizeof (&b));
     491  
     492    return z;
     493  }
     494  
     495  int
     496  f3 (void *x, char *y, int z, X w)
     497  {
     498    unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
     499    char buf1[7];
     500    signed char buf2[z + 32];
     501    long buf3[17];
     502    int *buf4[9];
     503    signed char *y2 = buf2;
     504    char c;
     505    char *y3;
     506    memset (y, 0, sizeof (y));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     507    memset (y1, 0, sizeof (y1));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     508    memset (y2, 0, sizeof (y2));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     509    memset (&c, 0, sizeof (&c));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     510    memset (w, 0, sizeof w);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     511  
     512    memcpy (y, x, sizeof (y));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     513    memcpy (y1, x, sizeof (y1));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     514    memcpy (y2, x, sizeof (y2));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     515    memcpy (&c, x, sizeof (&c));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     516    memcpy (w, x, sizeof w);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     517  
     518    memcpy (x, y, sizeof (y));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     519    memcpy (x, y1, sizeof (y1));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     520    memcpy (x, y2, sizeof (y2));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     521    memcpy (x, &c, sizeof (&c));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     522    memcpy (x, w, sizeof w);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     523  
     524    memmove (y, x, sizeof (y));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     525    memmove (y1, x, sizeof (y1));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     526    memmove (y2, x, sizeof (y2));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     527    memmove (&c, x, sizeof (&c));		    /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
     528    memmove (w, x, sizeof w);		    /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
     529  
     530    memmove (x, y, sizeof (y));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     531    memmove (x, y1, sizeof (y1));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     532    memmove (x, y2, sizeof (y2));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     533    memmove (x, &c, sizeof (&c));		    /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     534    memmove (x, w, sizeof w);		    /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     535  
     536    z += memcmp (y, x, sizeof (y));	    /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
     537    z += memcmp (y1, x, sizeof (y1));	    /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
     538    z += memcmp (y2, x, sizeof (y2));	    /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
     539    z += memcmp (&c, x, sizeof (&c));	    /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
     540    z += memcmp (w, x, sizeof w);		    /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
     541  
     542    z += memcmp (x, y, sizeof (y));	    /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
     543    z += memcmp (x, y1, sizeof (y1));	    /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
     544    z += memcmp (x, y2, sizeof (y2));	    /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
     545    z += memcmp (x, &c, sizeof (&c));	    /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
     546    z += memcmp (x, w, sizeof w);		    /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
     547  
     548    /* These are correct, no warning.  */
     549    memset (y, 0, sizeof (*y));
     550    memset (y1, 0, sizeof (*y2));
     551    memset (buf1, 0, sizeof buf1);
     552    memset (buf3, 0, sizeof (buf3));
     553    memset (&buf3[0], 0, sizeof (buf3));
     554    memset (&buf4[0], 0, sizeof (buf4));
     555    memset (w, 0, sizeof (X));
     556    /* These are probably broken, but obfuscated, no warning.  */
     557    memset ((void *) y, 0, sizeof (y));
     558    memset ((char *) y1, 0, sizeof (y2));
     559    memset (y, 0, sizeof (y) + 0);
     560    memset (y1, 0, 0 + sizeof (y2));
     561    memset ((void *) &c, 0, sizeof (&c));
     562    memset ((signed char *) &c, 0, sizeof (&c));
     563    memset (&c, 0, sizeof (&c) + 0);
     564    memset (&c, 0, 0 + sizeof (&c));
     565  
     566    /* These are correct, no warning.  */
     567    memcpy (y, x, sizeof (*y));
     568    memcpy (y1, x, sizeof (*y2));
     569    memcpy (buf1, x, sizeof buf1);
     570    memcpy (buf3, x, sizeof (buf3));
     571    memcpy (&buf3[0], x, sizeof (buf3));
     572    memcpy (&buf4[0], x, sizeof (buf4));
     573    memcpy (&y3, y, sizeof (y3));
     574    memcpy ((char *) &y3, y, sizeof (y3));
     575    memcpy (w, x, sizeof (X));
     576    /* These are probably broken, but obfuscated, no warning.  */
     577    memcpy ((void *) y, x, sizeof (y));
     578    memcpy ((char *) y1, x, sizeof (y2));
     579    memcpy (y, x, sizeof (y) + 0);
     580    memcpy (y1, x, 0 + sizeof (y2));
     581    memcpy ((void *) &c, x, sizeof (&c));
     582    memcpy ((signed char *) &c, x, sizeof (&c));
     583    memcpy (&c, x, sizeof (&c) + 0);
     584    memcpy (&c, x, 0 + sizeof (&c));
     585  
     586    /* These are correct, no warning.  */
     587    memcpy (x, y, sizeof (*y));
     588    memcpy (x, y1, sizeof (*y2));
     589    memcpy (x, buf1, sizeof buf1);
     590    memcpy (x, buf3, sizeof (buf3));
     591    memcpy (x, &buf3[0], sizeof (buf3));
     592    memcpy (x, &buf4[0], sizeof (buf4));
     593    memcpy (y, &y3, sizeof (y3));
     594    memcpy (y, (char *) &y3, sizeof (y3));
     595    memcpy (x, w, sizeof (X));
     596    /* These are probably broken, but obfuscated, no warning.  */
     597    memcpy (x, (void *) y, sizeof (y));
     598    memcpy (x, (char *) y1, sizeof (y2));
     599    memcpy (x, y, sizeof (y) + 0);
     600    memcpy (x, y1, 0 + sizeof (y2));
     601    memcpy (x, (void *) &c, sizeof (&c));
     602    memcpy (x, (signed char *) &c, sizeof (&c));
     603    memcpy (x, &c, sizeof (&c) + 0);
     604    memcpy (x, &c, 0 + sizeof (&c));
     605  
     606    /* These are correct, no warning.  */
     607    memmove (y, x, sizeof (*y));
     608    memmove (y1, x, sizeof (*y2));
     609    memmove (buf1, x, sizeof buf1);
     610    memmove (buf3, x, sizeof (buf3));
     611    memmove (&buf3[0], x, sizeof (buf3));
     612    memmove (&buf4[0], x, sizeof (buf4));
     613    memmove (&y3, y, sizeof (y3));
     614    memmove ((char *) &y3, y, sizeof (y3));
     615    memmove (w, x, sizeof (X));
     616    /* These are probably broken, but obfuscated, no warning.  */
     617    memmove ((void *) y, x, sizeof (y));
     618    memmove ((char *) y1, x, sizeof (y2));
     619    memmove (y, x, sizeof (y) + 0);
     620    memmove (y1, x, 0 + sizeof (y2));
     621    memmove ((void *) &c, x, sizeof (&c));
     622    memmove ((signed char *) &c, x, sizeof (&c));
     623    memmove (&c, x, sizeof (&c) + 0);
     624    memmove (&c, x, 0 + sizeof (&c));
     625  
     626    /* These are correct, no warning.  */
     627    memmove (x, y, sizeof (*y));
     628    memmove (x, y1, sizeof (*y2));
     629    memmove (x, buf1, sizeof buf1);
     630    memmove (x, buf3, sizeof (buf3));
     631    memmove (x, &buf3[0], sizeof (buf3));
     632    memmove (x, &buf4[0], sizeof (buf4));
     633    memmove (y, &y3, sizeof (y3));
     634    memmove (y, (char *) &y3, sizeof (y3));
     635    memmove (x, w, sizeof (X));
     636    /* These are probably broken, but obfuscated, no warning.  */
     637    memmove (x, (void *) y, sizeof (y));
     638    memmove (x, (char *) y1, sizeof (y2));
     639    memmove (x, y, sizeof (y) + 0);
     640    memmove (x, y1, 0 + sizeof (y2));
     641    memmove (x, (void *) &c, sizeof (&c));
     642    memmove (x, (signed char *) &c, sizeof (&c));
     643    memmove (x, &c, sizeof (&c) + 0);
     644    memmove (x, &c, 0 + sizeof (&c));
     645  
     646    /* These are correct, no warning.  */
     647    z += memcmp (y, x, sizeof (*y));
     648    z += memcmp (y1, x, sizeof (*y2));
     649    z += memcmp (buf1, x, sizeof buf1);
     650    z += memcmp (buf3, x, sizeof (buf3));
     651    z += memcmp (&buf3[0], x, sizeof (buf3));
     652    z += memcmp (&buf4[0], x, sizeof (buf4));
     653    z += memcmp (&y3, y, sizeof (y3));
     654    z += memcmp ((char *) &y3, y, sizeof (y3));
     655    z += memcmp (w, x, sizeof (X));
     656    /* These are probably broken, but obfuscated, no warning.  */
     657    z += memcmp ((void *) y, x, sizeof (y));
     658    z += memcmp ((char *) y1, x, sizeof (y2));
     659    z += memcmp (y, x, sizeof (y) + 0);
     660    z += memcmp (y1, x, 0 + sizeof (y2));
     661    z += memcmp ((void *) &c, x, sizeof (&c));
     662    z += memcmp ((signed char *) &c, x, sizeof (&c));
     663    z += memcmp (&c, x, sizeof (&c) + 0);
     664    z += memcmp (&c, x, 0 + sizeof (&c));
     665  
     666    /* These are correct, no warning.  */
     667    z += memcmp (x, y, sizeof (*y));
     668    z += memcmp (x, y1, sizeof (*y2));
     669    z += memcmp (x, buf1, sizeof buf1);
     670    z += memcmp (x, buf3, sizeof (buf3));
     671    z += memcmp (x, &buf3[0], sizeof (buf3));
     672    z += memcmp (x, &buf4[0], sizeof (buf4));
     673    z += memcmp (y, &y3, sizeof (y3));
     674    z += memcmp (y, (char *) &y3, sizeof (y3));
     675    z += memcmp (x, w, sizeof (X));
     676    /* These are probably broken, but obfuscated, no warning.  */
     677    z += memcmp (x, (void *) y, sizeof (y));
     678    z += memcmp (x, (char *) y1, sizeof (y2));
     679    z += memcmp (x, y, sizeof (y) + 0);
     680    z += memcmp (x, y1, 0 + sizeof (y2));
     681    z += memcmp (x, (void *) &c, sizeof (&c));
     682    z += memcmp (x, (signed char *) &c, sizeof (&c));
     683    z += memcmp (x, &c, sizeof (&c) + 0);
     684    z += memcmp (x, &c, 0 + sizeof (&c));
     685  
     686    return z;
     687  }
     688  
     689  int
     690  f4 (char *x, char **y, int z, char w[64])
     691  {
     692    const char *s1 = "foobarbaz";
     693    const char *s2 = "abcde12345678";
     694    strncpy (x, s1, sizeof (s1));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     695    strncat (x, s2, sizeof (s2));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     696    stpncpy (x, s1, sizeof (s1));		    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     697    y[0] = strndup (s1, sizeof (s1));	    /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     698    z += strncmp (s1, s2, sizeof (s1));	    /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
     699    z += strncmp (s1, s2, sizeof (s2));	    /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
     700    z += strncasecmp (s1, s2, sizeof (s1));   /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
     701    z += strncasecmp (s1, s2, sizeof (s2));   /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
     702  
     703    strncpy (w, s1, sizeof (w));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     704    strncat (w, s2, sizeof (w));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     705    stpncpy (w, s1, sizeof (w));		    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     706  
     707    /* These are pointless when the destination is large enough, and
     708       cause overflow otherwise.  If the copies are guaranteed to be
     709       safe the calls might as well be replaced by strcat(), strcpy(),
     710       or memcpy().  */
     711    const char s3[] = "foobarbaz";
     712    const char s4[] = "abcde12345678";
     713    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?" } */
     714    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?" } */
     715    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?" } */
     716  
     717    /* These are correct, no warning.  */
     718    y[1] = strndup (s3, sizeof (s3));
     719    z += strncmp (s3, s4, sizeof (s3));
     720    z += strncmp (s3, s4, sizeof (s4));
     721    z += strncasecmp (s3, s4, sizeof (s3));
     722    z += strncasecmp (s3, s4, sizeof (s4));
     723  
     724    return z;
     725  }
     726  
     727  /* { dg-prune-output "\[\n\r\]*writing\[\n\r\]*" } */