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
f1(void * x)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
f2(void * x)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
f3(void * x,char * y,int z,X w)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
f4(char * x,char ** y,int z,char w[64])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\]*" } */
489