1 /* PR c++/80560 - warn on undefined memory operations involving non-trivial
4 { dg-options "-Wclass-memaccess -ftrack-macro-expansion=0" } */
6 typedef __SIZE_TYPE__ size_t;
10 void* memcpy (void*, const void*, size_t);
11 void* memmove (void*, const void*, size_t);
12 void* mempcpy (void*, const void*, size_t);
13 void* memset (void*, int, size_t);
14 void* realloc (void*, size_t);
19 #if __cplusplus >= 201103L
20 enum class byte: unsigned char { };
22 typedef unsigned char byte;
26 #if __cplusplus < 201103L
27 typedef unsigned short char16_t;
30 /* Ordinary bzcopy and bzero aren't recognized as special. */
31 #define bcopy __builtin_bcopy
32 #define bzero __builtin_bzero
36 #define T(fn, arglist) ((fn arglist), sink (p))
38 #if !defined TEST || TEST == TEST_TRIVIAL
40 /* Trivial can be manipulated by raw memory functions. */
43 int i; unsigned bf: 1; char *s; char a[4];
45 // Non-copy assignment doesn't make the class non-trivial or not
46 // trivially assignable.
47 Trivial& operator= (int);
49 // Likewise, template assignment doesn't make the class non-trivial
50 // or not trivially assignable.
52 Trivial& operator= (U);
55 void test (Trivial *p, void *q, int x)
61 T (bzero, (p, sizeof *p));
64 T (bzero, (q, sizeof *p));
68 T (bcopy, (p, q, sizeof *p));
71 T (bcopy, (q, p, sizeof *p));
73 T (memcpy, (p, q, 1));
74 T (memcpy, (p, q, n));
75 T (memcpy, (p, q, sizeof *p));
76 T (memcpy, (q, p, 1));
77 T (memcpy, (q, p, n));
78 T (memcpy, (q, p, sizeof *p));
80 T (memset, (p, 0, 1));
81 T (memset, (p, 0, n));
82 T (memset, (p, 0, sizeof *p));
83 T (memset, (q, 0, 1));
84 T (memset, (q, 0, n));
85 T (memset, (q, 0, sizeof *p));
87 T (memset, (p, 1, 1));
88 T (memset, (p, 1, n));
89 T (memset, (p, 1, sizeof *p));
90 T (memset, (q, 1, 1));
91 T (memset, (q, 1, n));
92 T (memset, (q, 1, sizeof *p));
94 T (memset, (p, x, 1));
95 T (memset, (p, x, n));
96 T (memset, (p, x, sizeof *p));
97 T (memset, (q, x, 1));
98 T (memset, (q, x, n));
99 T (memset, (q, x, sizeof *p));
101 T (memmove, (p, q, 1));
102 T (memmove, (p, q, n));
103 T (memmove, (p, q, sizeof *p));
104 T (memmove, (q, p, 1));
105 T (memmove, (q, p, n));
106 T (memmove, (q, p, sizeof *p));
108 T (q = realloc, (p, 1));
109 T (q = realloc, (p, n));
110 T (q = realloc, (p, sizeof *p));
112 T (q = realloc, (q, 1));
113 T (q = realloc, (q, n));
114 T (q = realloc, (q, sizeof *p));
119 #if !defined TEST || TEST == TEST_TRIVIAL_ACCESS
121 /* TrivialAccess can be manipulated by raw memory functions in contexts
122 that have access to the trivial specia functions. */
125 int i; unsigned bf: 1; char *s; char a[4];
128 TrivialAccess () = default;
129 TrivialAccess (const TrivialAccess&) = default;
131 TrivialAccess& operator= (const TrivialAccess&) = default;
133 void test_member (const TrivialAccess*, int);
135 friend void test_friend (TrivialAccess*, const TrivialAccess*, int);
138 void test (TrivialAccess *p, const TrivialAccess *q, int i)
143 /* Verify that a warning is issued when the copy ctor and copy
144 assignment are inaccessible. */
145 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
146 T (bcopy, (q, p, sizeof *p)); // { dg-warning "bcopy" }
147 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
148 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
149 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
150 T (pv = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
153 void test_friend (TrivialAccess *p, const TrivialAccess *q, int i)
158 /* Verify that no warning is issued when the otherwise inaccessible
159 copy ctor and copy assignment can be accessed within the current
161 T (bzero, (p, sizeof *p));
162 T (bcopy, (q, p, sizeof *p));
163 T (memcpy, (p, q, sizeof *p));
164 T (memset, (p, i, sizeof *p));
165 T (memmove, (p, q, sizeof *p));
166 T (pv = realloc, (p, sizeof *p));
169 void TrivialAccess::test_member (const TrivialAccess *q, int i)
174 TrivialAccess *p = this;
176 /* Verify that no warning is issued when the otherwise inaccessible
177 copy ctor and copy assignment can be accessed within the current
179 T (bzero, (p, sizeof *p));
180 T (bcopy, (q, p, sizeof *p));
181 T (memcpy, (p, q, sizeof *p));
182 T (memset, (p, i, sizeof *p));
183 T (memmove, (p, q, sizeof *p));
184 T (pv = realloc, (p, sizeof *p));
189 #if !defined TEST || TEST == TEST_HAS_DEFAULT
191 /* HasDefault is trivially copyable but should be initialized by
192 the ctor, not bzero or memset. */
193 struct HasDefault { char a[4]; HasDefault (); };
195 void test (HasDefault *p, const HasDefault &x,
196 void *q, const unsigned char *s, const std::byte *b,
197 const signed char *ss, const char16_t *ws,
201 const size_t n = *ia;
203 // HasDefault is neither trivial nor standard-layout. The warning
204 // should mention the former since it's more permissive than the latter
205 // and so more informative.
206 T (bzero, (p, sizeof *p)); // { dg-warning "bzero(\[^\n\r\]*). clearing an object of non-trivial type .struct HasDefault.; use assignment or value-initialization instead" }
208 T (memset, (p, 0, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). clearing an object of non-trivial type .struct HasDefault.; use assignment or value-initialization instead" }
210 T (memset, (p, 1, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). writing to an object of non-trivial type .struct HasDefault.; use assignment instead" }
212 T (memset, (p, i, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). writing to an object of non-trivial type .struct HasDefault.; use assignment instead" }
214 // Copying from another object of the same type is fine.
215 T (bcopy, (&x, p, sizeof *p));
216 T (bcopy, (&x, p, n));
218 T (memcpy, (p, &x, sizeof *p));
219 T (memcpy, (p, &x, n));
221 // Copying from a void* or character buffer is also fine.
222 T (bcopy, (q, p, sizeof *p));
223 T (bcopy, (q, p, n));
224 T (bcopy, (s, p, sizeof *p));
225 T (bcopy, (s, p, n));
226 T (bcopy, (b, p, n));
228 T (memcpy, (p, q, sizeof *p));
229 T (memcpy, (p, q, n));
230 T (memcpy, (p, s, sizeof *p));
231 T (memcpy, (p, s, n));
232 T (memcpy, (p, b, n));
234 T (memmove, (p, q, sizeof *p));
235 T (memmove, (p, q, n));
236 T (memmove, (p, s, sizeof *p));
237 T (memmove, (p, s, n));
238 T (memmove, (p, b, n));
240 T (mempcpy, (p, q, sizeof *p));
241 T (mempcpy, (p, q, n));
242 T (mempcpy, (p, s, sizeof *p));
243 T (mempcpy, (p, s, n));
244 T (mempcpy, (p, b, n));
246 // ...but partial copies are diagnosed.
247 T (memcpy, (p, &x, 1)); // { dg-warning "writing to an object of a non-trivial type .struct HasDefault. leaves 3 bytes unchanged" } */
248 T (memmove, (p, q, 2)); // { dg-warning "writing to an object of a non-trivial type .struct HasDefault. leaves 2 bytes unchanged" } */
249 T (mempcpy, (p, q, 3)); // { dg-warning "writing to an object of a non-trivial type .struct HasDefault. leaves 1 byte unchanged" } */
251 // Otherwise, copying from an object of an unrelated type is diagnosed.
252 T (memcpy, (p, ia, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). copying an object of non-trivial type .struct HasDefault. from an array of .const int." }
254 T (memcpy, (p, ip, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). copying an object of non-trivial type .struct HasDefault. from an array of .long." }
255 T (memcpy, (p, ss, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). copying an object of non-trivial type .struct HasDefault. from an array of .const signed char." }
256 T (memcpy, (p, ws, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). copying an object of non-trivial type .struct HasDefault. from an array of .const \(char16_t\|unsigned short\)." }
258 T (memmove, (p, ia, sizeof *p)); // { dg-warning ".void\\* memmove(\[^\n\r\]*). copying an object of non-trivial type .struct HasDefault. from an array of .const int." }
260 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning ".void\\* mempcpy(\[^\n\r\]*). copying an object of non-trivial type .struct HasDefault. from an array of .const int." }
262 // Reallocating is the same as calling memcpy except that only
263 // shrinking reallocation is diagnosed.
264 T (q = realloc, (p, 1)); // { dg-warning "moving an object of non-trivial type .struct HasDefault. and size 4 into a region of size 1" }
265 T (q = realloc, (p, n));
266 T (q = realloc, (p, sizeof *p));
267 T (q = realloc, (p, sizeof *p + 1));
272 #if !defined TEST || TEST == TEST_HAS_TEMPLATE_DEFAULT
274 /* HasTemplateDefault should be initialized by means of the ctor,
275 not zeroed out by bzero/memset. */
276 struct HasTemplateDefault
279 HasTemplateDefault (U);
282 void test (HasTemplateDefault *p, const HasTemplateDefault &x,
283 const void *q, const unsigned char *s, const std::byte *b,
284 const signed char *ss, const char16_t *ws,
288 const size_t n = *ia;
290 // Zeroing out is diagnosed because value initialization is
291 // invalid (the template ctor makes default ctor unavailable).
292 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
293 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
294 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
295 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
297 // Copying from an object of any type is okay.
298 T (bcopy, (&x, p, sizeof *p));
299 T (bcopy, (q, p, sizeof *p));
300 T (bcopy, (s, p, sizeof *p));
301 T (bcopy, (b, p, sizeof *p));
302 T (bcopy, (ss, p, sizeof *p)); // { dg-warning "bcopy" }
303 T (bcopy, (ws, p, sizeof *p)); // { dg-warning "bcopy" }
304 T (bcopy, (ia, p, sizeof *p)); // { dg-warning "bcopy" }
306 T (memcpy, (p, &x, sizeof *p));
307 T (memcpy, (p, q, sizeof *p));
308 T (memcpy, (p, s, sizeof *p));
309 T (memcpy, (p, b, sizeof *p));
310 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
311 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
312 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
314 T (memmove, (p, &x, sizeof *p));
315 T (memmove, (p, q, sizeof *p));
316 T (memmove, (p, s, sizeof *p));
317 T (memmove, (p, b, sizeof *p));
318 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
319 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
320 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
322 T (mempcpy, (p, &x, sizeof *p));
323 T (mempcpy, (p, q, sizeof *p));
324 T (mempcpy, (p, s, sizeof *p));
325 T (mempcpy, (p, b, sizeof *p));
326 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
327 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
328 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
330 // Reallocating is the same as calling memcpy.
331 T (q = realloc, (p, 1));
332 T (q = realloc, (p, n));
333 T (q = realloc, (p, sizeof *p));
338 #if !defined TEST || TEST == TEST_HAS_COPY
340 /* HasCopy should be copied using the copy ctor or assignment, not
341 by memcpy or memmove. Since it's non-trivial, it should not be zeroed
342 out by bzero/memset either and should instead use assignment and/or
343 value initialization. */
344 struct HasCopy { int i; HasCopy (const HasCopy&); };
346 void test (HasCopy *p, const HasCopy &x,
347 const void *q, const unsigned char *s, const std::byte *b,
348 const signed char *ss, const char16_t *ws,
352 const size_t n = *ia;
354 // Zeroing out is diagnosed because value initialization is invalid
355 // (the copy ctor makes no default ctor unavailable). Since the type
356 // has no default ctor verify that the suggested alternative does not
357 // include value-initialization.
358 T (bzero, (p, sizeof *p)); // { dg-warning "clearing an object of non-trivial type .struct HasCopy.; use assignment instead" }
359 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
360 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
361 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
363 // Copying from an object of any type is diagnosed.
364 T (bcopy, (&x, p, sizeof *p)); // { dg-warning "bcopy" }
365 T (bcopy, (q, p, sizeof *p)); // { dg-warning "bcopy" }
366 T (bcopy, (s, p, sizeof *p)); // { dg-warning "bcopy" }
367 T (bcopy, (b, p, sizeof *p)); // { dg-warning "bcopy" }
368 T (bcopy, (ss, p, sizeof *p)); // { dg-warning "bcopy" }
369 T (bcopy, (ws, p, sizeof *p)); // { dg-warning "bcopy" }
370 T (bcopy, (ia, p, sizeof *p)); // { dg-warning "bcopy" }
372 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
373 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
374 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
375 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
376 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
377 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
378 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
380 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
381 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
382 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
383 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
384 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
385 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
386 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
388 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
389 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
390 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
391 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
392 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
393 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
394 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
396 // Reallocating is the same as calling memcpy.
397 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
398 T (q = realloc, (p, n)); // { dg-warning "realloc" }
399 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
404 #if !defined TEST || TEST == TEST_HAS_DEFAULT_AND_COPY
406 /* HasDefaultAndCopy is like HasCopy above but its default ctor takes
407 a default argument to verify that the suggested alternative offered
408 by the warning includes the default ctor (i.e., the test verifies
409 that the default ctor is recognized as such despite taking an argument. */
411 struct HasDefaultAndCopy
413 HasDefaultAndCopy (int = 0); // default ctor
414 HasDefaultAndCopy (const HasDefaultAndCopy&);
417 void test (HasDefaultAndCopy *p, const HasDefaultAndCopy &x)
419 T (bzero, (p, sizeof *p)); // { dg-warning "clearing an object of non-trivial type .struct HasDefaultAndCopy.; use assignment or value-initialization instead" }
420 T (memset, (p, 0, sizeof *p)); // { dg-warning "clearing an object of non-trivial type .struct HasDefaultAndCopy.; use assignment or value-initialization instead" }
425 #if !defined TEST || TEST == TEST_HAS_PRIVATE_COPY
427 /* HasPrivateCopy cannot be copied using memcpy or memmove. Since it's
428 non-trivial, it it should not be zeroed out by bzero/memset either
429 and should instead use assignment and/or value initialization. */
430 struct HasPrivateCopy {
433 HasPrivateCopy (const HasPrivateCopy&);
436 void test (HasPrivateCopy *p, const HasPrivateCopy &x,
437 const void *q, const unsigned char *s, const std::byte *b,
438 const signed char *ss, const char16_t *ws,
442 const size_t n = *ia;
444 // Zeroing out is diagnosed because value initialization is
445 // invalid (the copy ctor makes no default ctor unavailable).
446 // Verify also that the suggestion offers assignment but not
447 // value initialization (since the lattare is not available).
448 T (bzero, (p, sizeof *p)); // { dg-warning "clearing an object of non-trivial type .struct HasPrivateCopy.; use assignment instead" }
449 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
450 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
451 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
453 // Copying from an object of any type is diagnosed.
454 T (memcpy, (p, &x, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of non-trivially copyable type .struct HasPrivateCopy.; use copy-assignment instead" }
455 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
456 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
457 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
458 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
459 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
460 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
462 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
463 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
464 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
465 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
466 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
467 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
468 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
470 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
471 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
472 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
473 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
474 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
475 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
476 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
478 // Reallocating is the same as calling memcpy.
479 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
480 T (q = realloc, (p, n)); // { dg-warning "realloc" }
481 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
486 #if !defined TEST || TEST == TEST_HAS_DTOR
488 /* HasDtor should be initialized using aggregate or memberwise intialization,
489 not bzero or memset. */
490 struct HasDtor { int i; ~HasDtor (); };
492 void test (HasDtor *p, const HasDtor &x,
493 const void *q, const unsigned char *s, const std::byte *b,
494 const signed char *ss, const char16_t *ws,
498 const size_t n = *ia;
500 // Zeroing out is diagnosed only because it's difficult not to.
501 // Otherwise, a class that's non-trivial only because it has
502 // a non-trivial dtor can be safely zeroed out (that's what
503 // value-initializing it does).
504 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
505 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
506 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
507 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
509 // Copying from an object of any type is diagnosed simply because
510 // a class with a user-defined dtor is not trivially copyable.
511 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
512 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
513 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
514 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
515 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
516 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
517 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
519 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
520 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
521 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
522 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
523 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
524 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
525 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
527 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
528 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
529 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
530 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
531 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
532 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
533 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
535 // Reallocating is the same as calling memcpy.
536 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
537 T (q = realloc, (p, n)); // { dg-warning "realloc" }
538 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
543 #if !defined TEST || TEST == TEST_HAS_DELETED_DTOR
545 // HasDeletedDtor is trivial so clearing and copying it is okay.
546 // Relocation would bypass the deleted dtor and so it's diagnosed.
548 struct HasDeletedDtor
551 ~HasDeletedDtor () = delete;
554 void test (HasDeletedDtor *p, const HasDeletedDtor &x,
555 const void *q, const unsigned char *s, const std::byte *b,
556 const signed char *ss, const char16_t *ws,
560 const size_t n = *ia;
562 T (bzero, (p, sizeof *p));
563 T (memset, (p, 0, sizeof *p));
564 T (memset, (p, 1, sizeof *p));
565 T (memset, (p, i, sizeof *p));
567 T (memcpy, (p, &x, sizeof *p));
568 T (memcpy, (p, q, sizeof *p));
569 T (memcpy, (p, s, sizeof *p));
570 T (memcpy, (p, b, sizeof *p));
571 T (memcpy, (p, ss, sizeof *p));
572 T (memcpy, (p, ws, sizeof *p));
573 T (memcpy, (p, ia, sizeof *p));
575 T (memmove, (p, &x, sizeof *p));
576 T (memmove, (p, q, sizeof *p));
577 T (memmove, (p, s, sizeof *p));
578 T (memmove, (p, b, sizeof *p));
579 T (memmove, (p, ss, sizeof *p));
580 T (memmove, (p, ws, sizeof *p));
581 T (memmove, (p, ia, sizeof *p));
583 T (mempcpy, (p, &x, sizeof *p));
584 T (mempcpy, (p, q, sizeof *p));
585 T (mempcpy, (p, s, sizeof *p));
586 T (mempcpy, (p, b, sizeof *p));
587 T (mempcpy, (p, ss, sizeof *p));
588 T (mempcpy, (p, ws, sizeof *p));
589 T (mempcpy, (p, ia, sizeof *p));
591 // Reallocating is diagnosed.
592 T (q = realloc, (p, 1)); // { dg-warning "moving an object of type .struct HasDeletedDtor. with deleted destructor" }
593 T (q = realloc, (p, n)); // { dg-warning "realloc" }
594 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
599 #if !defined TEST || TEST == TEST_HAS_PRIVATE_DTOR
601 // Unlike HasDeletedDtor, HasPrivateDtor is okay to zero-out and copy
602 // but not relocate because doing so would bypass the deleted dtor..
604 struct HasPrivateDtor
611 void test (HasPrivateDtor *p, const HasPrivateDtor &x,
612 const void *q, const unsigned char *s, const std::byte *b,
613 const signed char *ss, const char16_t *ws,
617 const size_t n = *ia;
619 T (bzero, (p, sizeof *p)); // { dg-warning "clearing an object of non-trivial type .struct HasPrivateDtor.; use assignment or value-initialization instead" }
620 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
621 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
622 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
624 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "writing to an object of non-trivially copyable type .struct HasPrivateDtor.; use copy-assignment or copy-initialization instead" }
625 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
626 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
627 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
628 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
629 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
630 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
632 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
633 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
634 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
635 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
636 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
637 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
638 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
640 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
641 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
642 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
643 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
644 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
645 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
646 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
648 // Reallocating is diagnosed.
649 T (q = realloc, (p, 1)); // { dg-warning "moving an object of non-trivially copyable type .struct HasPrivateDtor." }
650 T (q = realloc, (p, n)); // { dg-warning "realloc" }
651 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
656 #if !defined TEST || TEST == TEST_HAS_COPY_ASSIGN
658 /* HasCopyAssign should be copied using the copy ctor or assignment, not
659 by memcpy or memmove. */
660 struct HasCopyAssign { void operator= (HasCopyAssign&); };
662 void test (HasCopyAssign *p, const HasCopyAssign &x,
663 const void *q, const unsigned char *s, const std::byte *b,
664 const signed char *ss, const char16_t *ws,
668 const size_t n = *ia;
670 // Zeroing out is diagnosed because it when used with an existing
671 // (already constructed) object in lieu of assigning a new value
672 // to it would bypass the user-defined assignment.
673 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
674 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
675 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
676 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
678 // Copying from an object of any type is diagnosed.
679 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
680 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
681 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
682 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
683 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
684 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
685 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
687 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
688 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
689 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
690 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
691 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
692 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
693 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
695 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
696 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
697 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
698 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
699 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
700 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
701 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
703 // Reallocating is the same as calling memcpy.
704 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
705 T (q = realloc, (p, n)); // { dg-warning "realloc" }
706 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
711 #if !defined TEST || TEST == TEST_HAS_MOVE_ASSIGN
713 /* Like HasCopyAssign, HasMoveAssign should be copied using the copy
714 ctor or assignment, not by memcpy or memmove. */
717 #if __cplusplus > 199711L
718 void operator= (HasMoveAssign&&);
720 // C++ 98 has no reference references. Simply repeat the HasCopyAssign
721 // test to avoid having to add a conditional to every dg-warning directive.
722 void operator= (const HasMoveAssign&);
726 void test (HasMoveAssign *p, const HasMoveAssign &x,
727 const void *q, const unsigned char *s, const std::byte *b,
728 const signed char *ss, const char16_t *ws,
732 const size_t n = *ia;
734 // Zeroing out is diagnosed because it when used with an existing
735 // (already constructed) object in lieu of assigning a new value
736 // to it would bypass the user-defined assignment.
737 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
738 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
739 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
740 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
742 // Copying from an object of any type is diagnosed.
743 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
744 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
745 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
746 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
747 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
748 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
749 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
751 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
752 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
753 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
754 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
755 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
756 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
757 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
759 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
760 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
761 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
762 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
763 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
764 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
765 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
767 // Reallocating is the same as calling memcpy.
768 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
769 T (q = realloc, (p, n)); // { dg-warning "realloc" }
770 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
775 #if !defined TEST || TEST == TEST_TRIVIAL_COPY_HAS_MOVE_ASSIGN
777 /* TrivialCopyHasMoveAssign should be copied using the copy ctor
778 or assignment, not by memcpy or memmove. */
779 struct TrivialCopyHasMoveAssign
781 typedef TrivialCopyHasMoveAssign Self;
783 Self& operator= (const Self&) = default;
785 #if __cplusplus > 199711L
786 Self& operator= (Self&&);
788 // C++ 98 has no reference references. Fake the test by adding
789 // a non-const overload of the assignment operator (which should
790 // have the same effect).
791 Self& operator= (Self&);
795 void test (TrivialCopyHasMoveAssign *p, const TrivialCopyHasMoveAssign &x,
796 const void *q, const unsigned char *s, const std::byte *b,
797 const signed char *ss, const char16_t *ws,
801 const size_t n = *ia;
803 // Zeroing out is diagnosed because it when used with an existing
804 // (already constructed) object in lieu of assigning a new value
805 // to it would bypass the user-defined assignment.
806 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
807 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
808 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
809 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
811 // Copying from an object of any type is diagnosed.
812 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
813 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
814 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
815 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
816 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
817 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
818 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
820 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
821 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
822 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
823 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
824 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
825 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
826 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
828 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
829 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
830 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
831 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
832 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
833 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
834 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
836 // Reallocating is the same as calling memcpy.
837 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
838 T (q = realloc, (p, n)); // { dg-warning "realloc" }
839 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
844 #if !defined TEST || TEST == TEST_TRIVIAL_MOVE_HAS_COPY_ASSIGN
846 /* TrivialMoveNontrivialCopyAssign should be copied using the copy ctor
847 or assignment, not by memcpy or memmove. */
848 struct TrivialMoveNontrivialCopyAssign
850 typedef TrivialMoveNontrivialCopyAssign Self;
852 Self& operator= (const Self&);
853 #if __cplusplus > 199711L
854 // C++ 98 has no reference references. Fake the test by simply
855 // not declaring the move assignment.
856 Self& operator= (Self&&) = default;
860 void test (TrivialMoveNontrivialCopyAssign *p,
861 const TrivialMoveNontrivialCopyAssign &x,
862 const void *q, const unsigned char *s, const std::byte *b,
863 const signed char *ss, const char16_t *ws,
867 const size_t n = *ia;
869 // Zeroing out is diagnosed because it when used with an existing
870 // (already constructed) object in lieu of assigning a new value
871 // to it would bypass the user-defined assignment.
872 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
873 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
874 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
875 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
877 // Copying from an object of any type is diagnosed.
878 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
879 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
880 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
881 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
882 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
883 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
884 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
886 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
887 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
888 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
889 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
890 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
891 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
892 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
894 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
895 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
896 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
897 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
898 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
899 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
900 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
902 // Reallocating is the same as calling memcpy.
903 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
904 T (q = realloc, (p, n)); // { dg-warning "realloc" }
905 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
910 #if !defined TEST || TEST == TEST_TRIVIAL_ASSIGN_REF_OVERLOAD
912 /* TrivialAssignRefOverload is a trivial type. */
913 struct TrivialAssignRefOverload {
915 typedef TrivialAssignRefOverload Self;
917 Self& operator= (Self&) = default;
918 Self& operator= (const Self&) = delete;
919 Self& operator= (volatile Self&) = delete;
920 Self& operator= (const volatile Self&) = delete;
923 void test (TrivialAssignRefOverload *p, const TrivialAssignRefOverload &x,
924 const void *q, const unsigned char *s, const std::byte *b,
925 const signed char *ss, const char16_t *ws,
929 const size_t n = *ia;
931 T (bzero, (p, sizeof *p));
932 T (memset, (p, 0, sizeof *p));
933 T (memset, (p, 1, sizeof *p));
934 T (memset, (p, i, sizeof *p));
936 T (memcpy, (p, &x, sizeof *p));
937 T (memcpy, (p, q, sizeof *p));
938 T (memcpy, (p, s, sizeof *p));
939 T (memcpy, (p, b, sizeof *p));
940 T (memcpy, (p, ss, sizeof *p));
941 T (memcpy, (p, ws, sizeof *p));
942 T (memcpy, (p, ia, sizeof *p));
944 T (memmove, (p, &x, sizeof *p));
945 T (memmove, (p, q, sizeof *p));
946 T (memmove, (p, s, sizeof *p));
947 T (memmove, (p, b, sizeof *p));
948 T (memmove, (p, ss, sizeof *p));
949 T (memmove, (p, ws, sizeof *p));
950 T (memmove, (p, ia, sizeof *p));
952 T (mempcpy, (p, &x, sizeof *p));
953 T (mempcpy, (p, q, sizeof *p));
954 T (mempcpy, (p, s, sizeof *p));
955 T (mempcpy, (p, b, sizeof *p));
956 T (mempcpy, (p, ss, sizeof *p));
957 T (mempcpy, (p, ws, sizeof *p));
958 T (mempcpy, (p, ia, sizeof *p));
960 T (q = realloc, (p, 1));
961 T (q = realloc, (p, n));
962 T (q = realloc, (p, sizeof *p));
967 #if !defined TEST || TEST == TEST_TRIVIAL_ASSIGN_CSTREF_OVERLOAD
969 /* TrivialAssignCstOverload is a trivial type. */
970 struct TrivialAssignCstRefOverload {
972 typedef TrivialAssignCstRefOverload Self;
974 Self& operator= (Self&) = delete;
975 Self& operator= (const Self&) = default;
976 Self& operator= (volatile Self&) = delete;
977 Self& operator= (const volatile Self&) = delete;
980 void test (TrivialAssignCstRefOverload *p,
981 const TrivialAssignCstRefOverload &x,
982 const void *q, const unsigned char *s, std::byte *b,
983 const signed char *ss, const char16_t *ws,
987 const size_t n = *ia;
989 T (bzero, (p, sizeof *p));
990 T (memset, (p, 0, sizeof *p));
991 T (memset, (p, 1, sizeof *p));
992 T (memset, (p, i, sizeof *p));
994 T (memcpy, (p, &x, sizeof *p));
995 T (memcpy, (p, q, sizeof *p));
996 T (memcpy, (p, s, sizeof *p));
997 T (memcpy, (p, b, sizeof *p));
998 T (memcpy, (p, ss, sizeof *p));
999 T (memcpy, (p, ws, sizeof *p));
1000 T (memcpy, (p, ia, sizeof *p));
1002 T (memmove, (p, &x, sizeof *p));
1003 T (memmove, (p, q, sizeof *p));
1004 T (memmove, (p, s, sizeof *p));
1005 T (memmove, (p, b, sizeof *p));
1006 T (memmove, (p, ss, sizeof *p));
1007 T (memmove, (p, ws, sizeof *p));
1008 T (memmove, (p, ia, sizeof *p));
1010 T (mempcpy, (p, &x, sizeof *p));
1011 T (mempcpy, (p, q, sizeof *p));
1012 T (mempcpy, (p, s, sizeof *p));
1013 T (mempcpy, (p, b, sizeof *p));
1014 T (mempcpy, (p, ss, sizeof *p));
1015 T (mempcpy, (p, ws, sizeof *p));
1016 T (mempcpy, (p, ia, sizeof *p));
1018 T (q = realloc, (p, 1));
1019 T (q = realloc, (p, n));
1020 T (q = realloc, (p, sizeof *p));
1025 #if !defined TEST || TEST == TEST_TRIVIAL_REF_HAS_VOLREF_ASSIGN
1027 struct TrivialRefHasVolRefAssign
1029 typedef TrivialRefHasVolRefAssign Self;
1031 Self& operator= (Self&) = default;
1032 Self& operator= (volatile Self&);
1035 void test (TrivialRefHasVolRefAssign *p,
1036 const TrivialRefHasVolRefAssign &x,
1037 const void *q, const unsigned char *s, const std::byte *b,
1038 const signed char *ss, const char16_t *ws,
1042 const size_t n = *ia;
1044 // Zeroing out is diagnosed because it when used with an existing
1045 // (already constructed) object in lieu of assigning a new value
1046 // to it would bypass the user-defined assignment.
1047 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
1048 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
1049 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1050 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1052 // Copying from an object of any type is diagnosed.
1053 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
1054 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
1055 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
1056 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
1057 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1058 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1059 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1061 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
1062 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
1063 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
1064 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
1065 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1066 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1067 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1069 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
1070 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
1071 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
1072 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
1073 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1074 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1075 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1077 // Reallocating is the same as calling memcpy.
1078 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
1079 T (q = realloc, (p, n)); // { dg-warning "realloc" }
1080 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
1085 #if !defined TEST || TEST == TEST_HAS_VOLREF_ASSIGN
1087 struct HasVolRefAssign {
1089 typedef HasVolRefAssign Self;
1091 Self& operator= (volatile Self&);
1094 void test (HasVolRefAssign *p, const HasVolRefAssign &x,
1095 const void *q, const unsigned char *s, const std::byte *b,
1096 const signed char *ss, const char16_t *ws,
1100 const size_t n = *ia;
1102 // Zeroing out is diagnosed because it when used with an existing
1103 // (already constructed) object in lieu of assigning a new value
1104 // to it would bypass the user-defined assignment.
1105 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
1106 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
1107 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1108 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1110 // Copying from an object of any type is diagnosed.
1111 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
1112 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
1113 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
1114 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
1115 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1116 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1117 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1119 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
1120 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
1121 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
1122 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
1123 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1124 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1125 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1127 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
1128 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
1129 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
1130 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
1131 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1132 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1133 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1135 // Reallocating is the same as calling memcpy.
1136 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
1137 T (q = realloc, (p, n)); // { dg-warning "realloc" }
1138 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
1143 #if !defined TEST || TEST == TEST_HAS_VIRTUALS
1145 /* HasVirtuals should only be manipulated by the special member functions
1146 and not by bzero, memcpy, or any other raw memory function. Doing
1147 otherwse might corrupt the the vtable pointer. */
1148 struct HasVirtuals { int i; virtual void foo (); };
1150 void test (HasVirtuals *p, const HasVirtuals &x,
1151 const void *q, const unsigned char *s, const std::byte *b,
1152 const signed char *ss, const char16_t *ws,
1156 const size_t n = *ia;
1158 // Zeroing out is diagnosed because it corrupts the vtable.
1159 T (bzero, (p, sizeof *p)); // { dg-warning "bzero" }
1160 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
1161 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1162 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1164 // Copying is diagnosed because when used to initialize an object
1165 // could incorrectly initialize the vtable.
1166 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "memcpy" }
1167 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
1168 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
1169 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
1170 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1171 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1172 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1174 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
1175 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
1176 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
1177 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
1178 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1179 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1180 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1182 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
1183 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
1184 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
1185 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
1186 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1187 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1188 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1190 // Reallocating is the same as calling memcpy.
1191 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
1192 T (q = realloc, (p, n)); // { dg-warning "realloc" }
1193 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
1198 #if !defined TEST || TEST == TEST_HAS_CONST_DATA
1200 /* HasConstData should only be initialized using aggregate initializatoon
1201 and not cleared by bzero, or copied into using memcpy. Since it's not
1202 assignable allowing, raw memory functions to write into it would defeat
1203 const-correctness. */
1204 struct HasConstData { const char a[4]; };
1206 void test (HasConstData *p, const HasConstData &x,
1207 const void *q, const unsigned char *s, const std::byte *b,
1208 const signed char *ss, const char16_t *ws,
1212 const size_t n = *ia;
1214 // The following is ill-formed because HasConstData's cannot
1215 // be assigned (the assignment is implicitly deleted). For
1216 // that reason all raw memory operations are diagnosed.
1219 // Zeroing out is diagnosed because if used with an existing
1220 // (already initialized) object could break const correctness.
1221 // Since the default ctor and copy assignment are both deleted,
1222 // verify that they're not suggested as a possible alternative.
1223 T (bzero, (p, sizeof *p)); // { dg-warning "clearing an object of type .struct HasConstData. with no trivial copy-assignment \\\[" "c++ 11 and later" { target { c++11 } } }
1224 // { dg-warning "clearing an object of type .struct HasConstData. with no trivial copy-assignment" "c++ 98" { target { c++98_only } } .-1 }
1225 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
1226 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1227 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1229 // Copying is also diagnosed.
1230 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "writing to an object of type .struct HasConstData. with no trivial copy-assignment; use copy-initialization instead" "c++ 11 and later" { target { c++11 } } }
1231 // { dg-warning "writing to an object of type .struct HasConstData. with no trivial copy-assignment" "c++ 98" { target { c++98_only } } .-1 }
1232 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
1233 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
1234 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
1235 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1236 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1237 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1239 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
1240 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
1241 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
1242 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
1243 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1244 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1245 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1247 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
1248 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
1249 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
1250 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
1251 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1252 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1253 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1255 // Reallocating is not diagnosed except in C++ 98 due to a bug.
1256 T (q = realloc, (p, 1)); // { dg-warning "moving an object of non-trivially copyable type .struct HasConstData.; use .new. and .delete. instead" "c++98" { target { c++98_only } } }
1257 T (q = realloc, (p, n)); // { dg-warning "realloc" "c++98" { target { c++98_only } } }
1258 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" "c++98" { target { c++98_only } } }
1263 #if !defined TEST || TEST == TEST_HAS_REFERENCE
1265 /* HasReference should only be initialized using aggregate initializatoon
1266 and not cleared by bzero, or copied into using memcpy. Since it's not
1267 assignable, allowing raw memory functions to write into it could
1268 corrupt the reference. */
1269 struct HasReference { int &ci; };
1271 void test (HasReference *p, const HasReference &x,
1272 const void *q, const unsigned char *s, const std::byte *b,
1273 const signed char *ss, const char16_t *ws,
1277 const size_t n = *ia;
1279 // Similarly to HasConstData, the following is ill-formed because
1280 // Hasreference cannot be assigned (the assignment is implicitly
1281 // deleted). For that reason all raw memory operations are diagnosed.
1284 // Zeroing out is diagnosed because if used with an existing
1285 // (already initialized) object would invalidate the reference.
1286 // Since copy-assignment is deleted verify it's not suggested
1287 // as an alternative. (C++ 11 and later only; C++ 98 is broken).
1288 T (bzero, (p, sizeof *p)); // { dg-warning "clearing an object of type .struct HasReference. with no trivial copy-assignment \\\[" "c++ 11 and later" { target { c++11 } } }
1289 // { dg-warning "clearing an object of type .struct HasReference. with no trivial copy-assignment" "c++ 98" { target { c++98_only } } .-1 }
1290 T (bzero, (p, n)); // { dg-warning "bzero" }
1291 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
1292 T (memset, (p, 0, n)); // { dg-warning "memset" }
1293 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1294 T (memset, (p, 1, n)); // { dg-warning "memset" }
1295 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1296 T (memset, (p, i, n)); // { dg-warning "memset" }
1298 // Copying is also diagnosed.
1299 T (memcpy, (p, &x, sizeof *p)); // { dg-warning "writing to an object of type .struct HasReference. with no trivial copy-assignment; use copy-initialization instead" "c++ 11 and later" { target { c++11 } } }
1300 // { dg-warning "writing to an object of type .struct HasReference. with no trivial copy-assignment" "c++ 98" { target { c++98_only } } .-1 }
1301 T (memcpy, (p, &x, n)); // { dg-warning "memcpy" }
1302 T (memcpy, (p, q, sizeof *p)); // { dg-warning "memcpy" }
1303 T (memcpy, (p, q, n)); // { dg-warning "memcpy" }
1304 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
1305 T (memcpy, (p, s, n)); // { dg-warning "memcpy" }
1306 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
1307 T (memcpy, (p, b, n)); // { dg-warning "memcpy" }
1308 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1309 T (memcpy, (p, ss, n)); // { dg-warning "memcpy" }
1310 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1311 T (memcpy, (p, ws, n)); // { dg-warning "memcpy" }
1312 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1313 T (memcpy, (p, ia, n)); // { dg-warning "memcpy" }
1315 T (memmove, (p, &x, sizeof *p)); // { dg-warning "memmove" }
1316 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
1317 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
1318 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
1319 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1320 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1321 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1323 T (mempcpy, (p, &x, sizeof *p)); // { dg-warning "mempcpy" }
1324 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
1325 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
1326 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
1327 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1328 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1329 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1331 // Reallocating is not diagnosed because a type with a reference
1332 // is (perhaps surprisingly) trivially copyable. It is diagnosed
1333 // in C++ 98 because of a bug, but it seems like it should be
1334 // diagnosed in all modes.
1335 T (q = realloc, (p, 1)); // { dg-warning "realloc" "c++ 98" { target { c++98_only } } }
1336 T (q = realloc, (p, n)); // { dg-warning "realloc" "c++ 98" { target { c++98_only } } }
1337 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" "c++ 98" { target { c++98_only } } }
1342 #if !defined TEST || TEST == TEST_HAS_MEM_DATA_PTR
1344 /* HasMemDataPtr should only be initialized using aggregate initializatoon
1345 and not cleared by bzero or written into using memset because its
1346 representation is different from ordinary scalars (a null member data
1347 pointer is all ones). It can be copied into using memcpy from an object
1348 of the same type or from a character buffer. */
1349 struct HasMemDataPtr { int HasMemDataPtr::*p; };
1351 void test (HasMemDataPtr *p, const HasMemDataPtr &x,
1352 const void *q, const unsigned char *s, const std::byte *b,
1353 const signed char *ss, const char16_t *ws,
1357 const size_t n = *ia;
1359 // Zeroing out is diagnosed because a null member data pointer has
1360 // a representation that's all bits set.
1361 T (bzero, (p, sizeof *p)); // { dg-warning "clearing an object of type .struct HasMemDataPtr. containing a pointer-to-member" }
1362 T (bzero, (p, n)); // { dg-warning "bzero" }
1363 T (memset, (p, 0, sizeof *p)); // { dg-warning "memset" }
1364 T (memset, (p, 0, n)); // { dg-warning "memset" }
1365 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1366 T (memset, (p, 1, n)); // { dg-warning "memset" }
1367 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1368 T (memset, (p, i, n)); // { dg-warning "memset" }
1370 // Copying is not diagnosed.
1371 T (memcpy, (p, &x, sizeof *p));
1372 T (memcpy, (p, &x, n));
1373 T (memcpy, (p, q, sizeof *p));
1374 T (memcpy, (p, q, n));
1375 T (memcpy, (p, s, sizeof *p));
1376 T (memcpy, (p, s, n));
1377 T (memcpy, (p, b, sizeof *p));
1378 T (memcpy, (p, b, n));
1379 T (memcpy, (p, ss, sizeof *p));
1380 T (memcpy, (p, ss, n));
1381 T (memcpy, (p, ws, sizeof *p));
1382 T (memcpy, (p, ws, n));
1383 T (memcpy, (p, ia, sizeof *p));
1384 T (memcpy, (p, ia, n));
1386 T (memmove, (p, &x, sizeof *p));
1387 T (memmove, (p, q, sizeof *p));
1388 T (memmove, (p, s, sizeof *p));
1389 T (memmove, (p, b, sizeof *p));
1390 T (memmove, (p, ss, sizeof *p));
1391 T (memmove, (p, ws, sizeof *p));
1392 T (memmove, (p, ia, sizeof *p));
1394 T (mempcpy, (p, &x, sizeof *p));
1395 T (mempcpy, (p, q, sizeof *p));
1396 T (mempcpy, (p, s, sizeof *p));
1397 T (mempcpy, (p, b, sizeof *p));
1398 T (mempcpy, (p, ss, sizeof *p));
1399 T (mempcpy, (p, ws, sizeof *p));
1400 T (mempcpy, (p, ia, sizeof *p));
1402 // Reallocating is the same as calling memcpy.
1403 T (q = realloc, (p, 1));
1404 T (q = realloc, (p, n));
1405 T (q = realloc, (p, sizeof *p));
1406 T (q = realloc, (p, sizeof *p + 1));
1411 #if !defined TEST || TEST == TEST_HAS_SOME_PRIVATE_DATA
1413 /* HasSomePrivateData can be initialized using value initialization
1414 and should not be written to using memset with a non-zero argument.
1415 Doing otherwise would break encapsulation. */
1416 struct HasSomePrivateData { char a[2]; private: char b[2]; };
1418 void test (HasSomePrivateData *p, const HasSomePrivateData &x,
1419 const void *q, const unsigned char *s, const std::byte *b,
1420 const signed char *ss, const char16_t *ws,
1424 const size_t n = *ia;
1426 // Zeroing out is not diagnosed because it's equivalent to value
1428 T (bzero, (p, sizeof *p));
1429 T (memset, (p, 0, sizeof *p));
1430 // Calling memset with a (possibly) non-zero argument is diagnosed
1431 // because it breaks encapsulation.
1432 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1433 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1435 // Calling memcpy to copy from an object of the same type or from
1436 // a character or void buffer is not diagnosed because that's what
1437 // copy construction and copy assignment do.
1438 T (memcpy, (p, &x, sizeof *p));
1439 T (memcpy, (p, &x, n));
1440 T (memcpy, (p, q, sizeof *p));
1441 T (memcpy, (p, s, sizeof *p));
1442 T (memcpy, (p, b, sizeof *p));
1443 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1444 T (memcpy, (p, ss, n)); // { dg-warning "memcpy" }
1445 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1446 T (memcpy, (p, ws, n)); // { dg-warning "memcpy" }
1447 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1448 T (memcpy, (p, ia, n)); // { dg-warning "memcpy" }
1450 // Same as memcpy above.
1451 T (memmove, (p, &x, sizeof *p));
1452 T (memmove, (p, &x, n));
1453 T (memmove, (p, q, sizeof *p));
1454 T (memmove, (p, s, sizeof *p));
1455 T (memmove, (p, b, sizeof *p));
1456 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1457 T (memmove, (p, ss, n)); // { dg-warning "memmove" }
1458 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1459 T (memmove, (p, ws, n)); // { dg-warning "memmove" }
1460 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1461 T (memmove, (p, ia, n)); // { dg-warning "memmove" }
1463 // Same as memcpy above.
1464 T (mempcpy, (p, &x, sizeof *p));
1465 T (mempcpy, (p, &x, n));
1466 T (mempcpy, (p, q, sizeof *p));
1467 T (mempcpy, (p, q, n));
1468 T (mempcpy, (p, s, sizeof *p));
1469 T (mempcpy, (p, s, n));
1470 T (mempcpy, (p, b, sizeof *p));
1471 T (mempcpy, (p, b, n));
1472 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1473 T (mempcpy, (p, ss, n)); // { dg-warning "mempcpy" }
1474 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1475 T (mempcpy, (p, ws, n)); // { dg-warning "mempcpy" }
1476 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1477 T (mempcpy, (p, ia, n)); // { dg-warning "mempcpy" }
1479 // Reallocating is the same as calling memcpy except that partial
1480 // copies are not diagnosed.
1481 T (q = realloc, (p, 1));
1482 T (q = realloc, (p, n));
1483 T (q = realloc, (p, sizeof *p));
1484 T (q = realloc, (p, sizeof *p + 1));
1489 #if !defined TEST || TEST == TEST_HAS_SOME_PROTECTED_DATA
1491 /* Similarly to HasSomePrivateData, HasSomeProtectedData can be
1492 initialized using value initialization and should not be written
1493 to using memset with a non-zero argument. Doing otherwise would
1494 break encapsulation. */
1495 struct HasSomeProtectedData { char a[2]; protected: char b[2]; };
1497 void test (HasSomeProtectedData *p, const HasSomeProtectedData &x,
1498 const void *q, const unsigned char *s, const std::byte *b,
1499 const signed char *ss, const char16_t *ws,
1503 const size_t n = *ia;
1505 // Zeroing out is not diagnosed because it's equivalent to value
1507 T (bzero, (p, sizeof *p));
1508 T (memset, (p, 0, sizeof *p));
1509 // Calling memset with a (possibly) non-zero argument is diagnosed
1510 // because it breaks encapsulation.
1511 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1512 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1514 // Calling memcpy to copy from an object of the same type or from
1515 // a character or void buffer is not diagnosed because that's what
1516 // copy construction and copy assignment do.
1517 T (memcpy, (p, &x, sizeof *p));
1518 T (memcpy, (p, &x, n));
1519 T (memcpy, (p, q, sizeof *p));
1520 T (memcpy, (p, s, sizeof *p));
1521 T (memcpy, (p, b, sizeof *p));
1522 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1523 T (memcpy, (p, ss, n)); // { dg-warning "memcpy" }
1524 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1525 T (memcpy, (p, ws, n)); // { dg-warning "memcpy" }
1526 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1527 T (memcpy, (p, ia, n)); // { dg-warning "memcpy" }
1529 // Same as memcpy above.
1530 T (memmove, (p, &x, sizeof *p));
1531 T (memmove, (p, &x, n));
1532 T (memmove, (p, q, sizeof *p));
1533 T (memmove, (p, s, sizeof *p));
1534 T (memmove, (p, b, sizeof *p));
1535 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1536 T (memmove, (p, ss, n)); // { dg-warning "memmove" }
1537 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1538 T (memmove, (p, ws, n)); // { dg-warning "memmove" }
1539 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1540 T (memmove, (p, ia, n)); // { dg-warning "memmove" }
1542 // Same as memcpy above.
1543 T (mempcpy, (p, &x, sizeof *p));
1544 T (mempcpy, (p, &x, n));
1545 T (mempcpy, (p, q, sizeof *p));
1546 T (mempcpy, (p, q, n));
1547 T (mempcpy, (p, s, sizeof *p));
1548 T (mempcpy, (p, s, n));
1549 T (mempcpy, (p, b, sizeof *p));
1550 T (mempcpy, (p, b, n));
1551 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1552 T (mempcpy, (p, ss, n)); // { dg-warning "mempcpy" }
1553 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1554 T (mempcpy, (p, ws, n)); // { dg-warning "mempcpy" }
1555 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1556 T (mempcpy, (p, ia, n)); // { dg-warning "mempcpy" }
1558 // Reallocating is the same as calling memcpy except that partial
1559 // copies are not diagnosed.
1560 T (q = realloc, (p, 1));
1561 T (q = realloc, (p, n));
1562 T (q = realloc, (p, sizeof *p));
1563 T (q = realloc, (p, sizeof *p + 1));
1568 #if !defined TEST || TEST == TEST_HAS_ALL_PRIVATE_DATA
1570 /* Similarly to HasSomePrivateData, HasAllPrivateData should only be
1571 initialized using value initializatoon and should not be written
1572 to using memset with non-zero argument. They are tested separately
1573 because unlike the former classes, these are standard layout. */
1574 struct HasAllPrivateData { private: char a[4]; };
1576 void test (HasAllPrivateData *p, const HasAllPrivateData &x,
1577 const void *q, const unsigned char *s, const std::byte *b,
1578 const signed char *ss, const char16_t *ws,
1582 const size_t n = *ia;
1584 // Zeroing out is not diagnosed because it's equivalent to value
1586 T (bzero, (p, sizeof *p));
1587 T (memset, (p, 0, sizeof *p));
1588 // Calling memset with a (possibly) non-zero argument is diagnosed
1589 // because it breaks encapsulation.
1590 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1591 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1593 // Calling memcpy to copy from an object of the same type or from
1594 // a character or void buffer is not diagnosed because that's what
1595 // copy construction and copy assignment do.
1596 T (memcpy, (p, &x, sizeof *p));
1597 T (memcpy, (p, &x, n));
1598 T (memcpy, (p, q, sizeof *p));
1599 T (memcpy, (p, s, sizeof *p));
1600 T (memcpy, (p, b, sizeof *p));
1601 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1602 T (memcpy, (p, ss, n)); // { dg-warning "memcpy" }
1603 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1604 T (memcpy, (p, ws, n)); // { dg-warning "memcpy" }
1605 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1606 T (memcpy, (p, ia, n)); // { dg-warning "memcpy" }
1608 // Same as memcpy above.
1609 T (memmove, (p, &x, sizeof *p));
1610 T (memmove, (p, &x, n));
1611 T (memmove, (p, q, sizeof *p));
1612 T (memmove, (p, s, sizeof *p));
1613 T (memmove, (p, b, sizeof *p));
1614 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1615 T (memmove, (p, ss, n)); // { dg-warning "memmove" }
1616 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1617 T (memmove, (p, ws, n)); // { dg-warning "memmove" }
1618 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1619 T (memmove, (p, ia, n)); // { dg-warning "memmove" }
1621 // Same as memcpy above.
1622 T (mempcpy, (p, &x, sizeof *p));
1623 T (mempcpy, (p, &x, n));
1624 T (mempcpy, (p, q, sizeof *p));
1625 T (mempcpy, (p, q, n));
1626 T (mempcpy, (p, s, sizeof *p));
1627 T (mempcpy, (p, s, n));
1628 T (mempcpy, (p, b, sizeof *p));
1629 T (mempcpy, (p, b, n));
1630 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1631 T (mempcpy, (p, ss, n)); // { dg-warning "mempcpy" }
1632 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1633 T (mempcpy, (p, ws, n)); // { dg-warning "mempcpy" }
1634 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1635 T (mempcpy, (p, ia, n)); // { dg-warning "mempcpy" }
1637 // Reallocating is the same as calling memcpy except that partial
1638 // copies are not diagnosed.
1639 T (q = realloc, (p, 1));
1640 T (q = realloc, (p, n));
1641 T (q = realloc, (p, sizeof *p));
1642 T (q = realloc, (p, sizeof *p + 1));
1647 #if !defined TEST || TEST == TEST_HAS_ALL_PROTECTED_DATA
1649 /* Similarly to HasSomeProtectedData, HasAllProtectedData should only
1650 be initialized using value initializatoon and should not be written
1651 to using memset with non-zero argument. They are tested separately
1652 because unlike the former classes, these are standard layout. */
1653 struct HasAllProtectedData { protected: char a[4]; };
1655 void test (HasAllProtectedData *p, const HasAllProtectedData &x,
1656 const void *q, const unsigned char *s, const std::byte *b,
1657 const signed char *ss, const char16_t *ws,
1661 const size_t n = *ia;
1663 // Zeroing out is not diagnosed because it's equivalent to value
1665 T (bzero, (p, sizeof *p));
1666 T (memset, (p, 0, sizeof *p));
1667 // Calling memset with a (possibly) non-zero argument is diagnosed
1668 // because it breaks encapsulation.
1669 T (memset, (p, 1, sizeof *p)); // { dg-warning "memset" }
1670 T (memset, (p, i, sizeof *p)); // { dg-warning "memset" }
1672 // Calling memcpy to copy from an object of the same type or from
1673 // a character or void buffer is not diagnosed because that's what
1674 // copy construction and copy assignment do.
1675 T (memcpy, (p, &x, sizeof *p));
1676 T (memcpy, (p, &x, n));
1677 T (memcpy, (p, q, sizeof *p));
1678 T (memcpy, (p, s, sizeof *p));
1679 T (memcpy, (p, b, sizeof *p));
1680 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "memcpy" }
1681 T (memcpy, (p, ss, n)); // { dg-warning "memcpy" }
1682 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "memcpy" }
1683 T (memcpy, (p, ws, n)); // { dg-warning "memcpy" }
1684 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "memcpy" }
1685 T (memcpy, (p, ia, n)); // { dg-warning "memcpy" }
1687 // Same as memcpy above.
1688 T (memmove, (p, &x, sizeof *p));
1689 T (memmove, (p, &x, n));
1690 T (memmove, (p, q, sizeof *p));
1691 T (memmove, (p, s, sizeof *p));
1692 T (memmove, (p, b, sizeof *p));
1693 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1694 T (memmove, (p, ss, n)); // { dg-warning "memmove" }
1695 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1696 T (memmove, (p, ws, n)); // { dg-warning "memmove" }
1697 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1698 T (memmove, (p, ia, n)); // { dg-warning "memmove" }
1700 // Same as memcpy above.
1701 T (mempcpy, (p, &x, sizeof *p));
1702 T (mempcpy, (p, &x, n));
1703 T (mempcpy, (p, q, sizeof *p));
1704 T (mempcpy, (p, q, n));
1705 T (mempcpy, (p, s, sizeof *p));
1706 T (mempcpy, (p, s, n));
1707 T (mempcpy, (p, b, sizeof *p));
1708 T (mempcpy, (p, b, n));
1709 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1710 T (mempcpy, (p, ss, n)); // { dg-warning "mempcpy" }
1711 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1712 T (mempcpy, (p, ws, n)); // { dg-warning "mempcpy" }
1713 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1714 T (mempcpy, (p, ia, n)); // { dg-warning "mempcpy" }
1716 // Reallocating is the same as calling memcpy except that partial
1717 // copies are not diagnosed.
1718 T (q = realloc, (p, 1));
1719 T (q = realloc, (p, n));
1720 T (q = realloc, (p, sizeof *p));
1721 T (q = realloc, (p, sizeof *p + 1));
1726 #if !defined TEST || TEST == TEST_DEFAULT_CTOR_PRIVATE_ASSIGN
1728 /* Used to verify suggested alternatives. */
1729 struct HasDefaultPrivateAssign
1732 HasDefaultPrivateAssign ();
1734 void operator= (HasDefaultPrivateAssign&);
1737 void test (HasDefaultPrivateAssign *p, const HasDefaultPrivateAssign &x,
1738 const void *q, const unsigned char *s, const std::byte *b,
1739 const signed char *ss, const char16_t *ws,
1743 const size_t n = *ia;
1745 // HasDefaultPrivateAssign isn't trivial or assignable. Verify
1746 // that the alternative suggested in the warning is to use copy or
1747 // default but not assignment.
1748 T (bzero, (p, sizeof *p)); // { dg-warning "bzero(\[^\n\r\]*). clearing an object of type .struct HasDefaultPrivateAssign. with no trivial copy-assignment; use value-initialization instead" "c++ 11 and later" { target { c++11 } } }
1749 // { dg-warning "bzero(\[^\n\r\]*). clearing an object of type .struct HasDefaultPrivateAssign. with no trivial copy-assignment; use value-initialization instead" "c++ 98" { target { c++98_only } } .-1 }
1751 T (memset, (p, 0, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). clearing an object of type .struct HasDefaultPrivateAssign. with (deleted|no trivial) copy-assignment; use value-initialization instead" }
1753 T (memset, (p, 1, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). writing to an object of type .struct HasDefaultPrivateAssign. with (deleted|no trivial) copy-assignment" }
1755 T (memset, (p, i, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). writing to an object of type .struct HasDefaultPrivateAssign. with (deleted|no trivial) copy-assignment" }
1757 // Copying from another object of the same type is diagnosed because
1758 // the copy assignment is inaccessible. Verify that the suggested
1759 // alternative is not copy assignment (C++ 98 is busted).
1760 T (memcpy, (p, &x, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of type .struct HasDefaultPrivateAssign. with no trivial copy-assignment; use copy-initialization instead" "c++11 and later" { target c++11 } }
1761 // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of type .struct HasDefaultPrivateAssign. with no trivial copy-assignment" "c++98" { target c++98_only } .-1 }
1762 T (memcpy, (p, &x, n)); // { dg-warning "memcpy" }
1764 // Similarly for copying from a void* or character buffer.
1765 T (memcpy, (p, q, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of type .struct HasDefaultPrivateAssign. with no trivial copy-assignment; use copy-initialization instead" "c++11 and later" { target c++11 } }
1766 // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of type .struct HasDefaultPrivateAssign. with no trivial copy-assignment" "c++98" { target c++98_only } ,-1 }
1767 T (memcpy, (p, q, n)); // { dg-warning "memcpy" }
1768 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
1769 T (memcpy, (p, s, n)); // { dg-warning "memcpy" }
1770 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
1771 T (memcpy, (p, b, n)); // { dg-warning "memcpy" }
1773 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
1774 T (memmove, (p, q, n)); // { dg-warning "memmove" }
1775 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
1776 T (memmove, (p, s, n)); // { dg-warning "memmove" }
1777 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
1778 T (memmove, (p, b, n)); // { dg-warning "memmove" }
1780 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
1781 T (mempcpy, (p, q, n)); // { dg-warning "mempcpy" }
1782 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
1783 T (mempcpy, (p, s, n)); // { dg-warning "mempcpy" }
1784 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
1785 T (mempcpy, (p, b, n)); // { dg-warning "mempcpy" }
1787 // Same for partial copies are diagnosed.
1788 T (memcpy, (p, &x, 1)); // { dg-warning "writing to an object of type .struct HasDefaultPrivateAssign. with (deleted|no trivial) copy-assignment" } */
1789 T (memmove, (p, q, 2)); // { dg-warning "memmove" } */
1790 T (mempcpy, (p, q, 3)); // { dg-warning "mempcpy" } */
1792 // Otherwise, copying from an object of an unrelated type is diagnosed.
1793 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "writing to an object of type .struct HasDefaultPrivateAssign. with (deleted|no trivial) copy-assignment." }
1794 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "writing to an object of type .struct HasDefaultPrivateAssign. with (deleted|no trivial) copy-assignment." }
1795 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "writing to an object of type .struct HasDefaultPrivateAssign. with (deleted|no trivial) copy-assignment." }
1796 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1797 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1798 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1799 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1800 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1801 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1803 // Reallocating is the same as calling memcpy.
1804 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
1805 T (q = realloc, (p, n)); // { dg-warning "realloc" }
1806 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
1811 #if !defined TEST || TEST == TEST_DEFAULT_CTOR_DELETED_ASSIGN
1813 /* Used to verify suggested alternatives. */
1814 struct HasDefaultDeletedAssign
1817 HasDefaultDeletedAssign ();
1819 void operator= (HasDefaultDeletedAssign&);
1822 void test (HasDefaultDeletedAssign *p, const HasDefaultDeletedAssign &x,
1823 const void *q, const unsigned char *s, const std::byte *b,
1824 const signed char *ss, const char16_t *ws,
1828 const size_t n = *ia;
1830 // HasDefaultDeletedAssign isn't trivial or assignable. Verify
1831 // that the alternative suggested in the warning is to use copy or
1832 // default but not assignment.
1833 T (bzero, (p, sizeof *p)); // { dg-warning "bzero(\[^\n\r\]*). clearing an object of type .struct HasDefaultDeletedAssign. with no trivial copy-assignment; use value-initialization instead" "c++ 11 and later" { target { c++11 } } }
1834 // { dg-warning "bzero(\[^\n\r\]*). clearing an object of type .struct HasDefaultDeletedAssign. with no trivial copy-assignment; use value-initialization instead" "c++ 98" { target { c++98_only } } .-1 }
1836 T (memset, (p, 0, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). clearing an object of type .struct HasDefaultDeletedAssign. with (deleted|no trivial) copy-assignment; use value-initialization instead" }
1838 T (memset, (p, 1, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). writing to an object of type .struct HasDefaultDeletedAssign. with (deleted|no trivial) copy-assignment" }
1840 T (memset, (p, i, sizeof *p)); // { dg-warning ".void\\* memset(\[^\n\r\]*). writing to an object of type .struct HasDefaultDeletedAssign. with (deleted|no trivial) copy-assignment" }
1842 // Copying from another object of the same type is diagnosed because
1843 // the copy assignment is inaccessible. Verify that the suggested
1844 // alternative is not copy assignment (C++ 98 is busted).
1845 T (memcpy, (p, &x, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of type .struct HasDefaultDeletedAssign. with no trivial copy-assignment; use copy-initialization instead" "c++11 and later" { target c++11 } }
1846 // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of type .struct HasDefaultDeletedAssign. with no trivial copy-assignment" "c++98" { target c++98_only } .-1 }
1847 T (memcpy, (p, &x, n)); // { dg-warning "memcpy" }
1849 // Similarly for copying from a void* or character buffer.
1850 T (memcpy, (p, q, sizeof *p)); // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of type .struct HasDefaultDeletedAssign. with no trivial copy-assignment; use copy-initialization instead" "c++11 and later" { target c++11 } }
1851 // { dg-warning ".void\\* memcpy(\[^\n\r\]*). writing to an object of type .struct HasDefaultDeletedAssign. with no trivial copy-assignment" "c++98" { target c++98_only } ,-1 }
1852 T (memcpy, (p, q, n)); // { dg-warning "memcpy" }
1853 T (memcpy, (p, s, sizeof *p)); // { dg-warning "memcpy" }
1854 T (memcpy, (p, s, n)); // { dg-warning "memcpy" }
1855 T (memcpy, (p, b, sizeof *p)); // { dg-warning "memcpy" }
1856 T (memcpy, (p, b, n)); // { dg-warning "memcpy" }
1858 T (memmove, (p, q, sizeof *p)); // { dg-warning "memmove" }
1859 T (memmove, (p, q, n)); // { dg-warning "memmove" }
1860 T (memmove, (p, s, sizeof *p)); // { dg-warning "memmove" }
1861 T (memmove, (p, s, n)); // { dg-warning "memmove" }
1862 T (memmove, (p, b, sizeof *p)); // { dg-warning "memmove" }
1863 T (memmove, (p, b, n)); // { dg-warning "memmove" }
1865 T (mempcpy, (p, q, sizeof *p)); // { dg-warning "mempcpy" }
1866 T (mempcpy, (p, q, n)); // { dg-warning "mempcpy" }
1867 T (mempcpy, (p, s, sizeof *p)); // { dg-warning "mempcpy" }
1868 T (mempcpy, (p, s, n)); // { dg-warning "mempcpy" }
1869 T (mempcpy, (p, b, sizeof *p)); // { dg-warning "mempcpy" }
1870 T (mempcpy, (p, b, n)); // { dg-warning "mempcpy" }
1872 // Same for partial copies are diagnosed.
1873 T (memcpy, (p, &x, 1)); // { dg-warning "writing to an object of type .struct HasDefaultDeletedAssign. with (deleted|no trivial) copy-assignment" } */
1874 T (memmove, (p, q, 2)); // { dg-warning "memmove" } */
1875 T (mempcpy, (p, q, 3)); // { dg-warning "mempcpy" } */
1877 // Otherwise, copying from an object of an unrelated type is diagnosed.
1878 T (memcpy, (p, ss, sizeof *p)); // { dg-warning "writing to an object of type .struct HasDefaultDeletedAssign. with (deleted|no trivial) copy-assignment." }
1879 T (memcpy, (p, ws, sizeof *p)); // { dg-warning "writing to an object of type .struct HasDefaultDeletedAssign. with (deleted|no trivial) copy-assignment." }
1880 T (memcpy, (p, ia, sizeof *p)); // { dg-warning "writing to an object of type .struct HasDefaultDeletedAssign. with (deleted|no trivial) copy-assignment." }
1881 T (memmove, (p, ss, sizeof *p)); // { dg-warning "memmove" }
1882 T (memmove, (p, ws, sizeof *p)); // { dg-warning "memmove" }
1883 T (memmove, (p, ia, sizeof *p)); // { dg-warning "memmove" }
1884 T (mempcpy, (p, ss, sizeof *p)); // { dg-warning "mempcpy" }
1885 T (mempcpy, (p, ws, sizeof *p)); // { dg-warning "mempcpy" }
1886 T (mempcpy, (p, ia, sizeof *p)); // { dg-warning "mempcpy" }
1888 // Reallocating is the same as calling memcpy.
1889 T (q = realloc, (p, 1)); // { dg-warning "realloc" }
1890 T (q = realloc, (p, n)); // { dg-warning "realloc" }
1891 T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" }
1896 #if !defined TEST || TEST == TEST_EXPRESSION
1898 void test_expr (int i)
1900 struct TestClass { TestClass () { } };
1905 T (bzero, (i < 0 ? &a : &b, 1)); // { dg-warning "bzero" }
1910 #if !defined TEST || TEST == TEST_CTOR
1915 #define T(fn, arglist) (fn arglist, sink (this))
1923 /* A ctor of a base class with no virtual function can do whatever
1925 T (bzero, (this, sizeof *this));
1926 T (memset, (this, 0, sizeof *this));
1927 T (memcpy, (this, p, sizeof *this));
1928 T (memmove, (this, p, sizeof *this));
1929 T (mempcpy, (this, p, sizeof *this));
1934 /* A dtor of a base class with no virtual function can do whatever
1936 T (bzero, (this, sizeof *this));
1937 T (memset, (this, 0, sizeof *this));
1938 T (memcpy, (this, p, sizeof *this));
1939 T (memmove, (this, p, sizeof *this));
1940 T (mempcpy, (this, p, sizeof *this));
1944 struct TestBaseVtable
1948 /* A ctor of a base class with virtual function is treated
1949 as an ordinary function. */
1950 T (bzero, (this, sizeof *this)); // { dg-warning "bzero" }
1951 T (memset, (this, 0, sizeof *this)); // { dg-warning "memset" }
1952 T (memcpy, (this, p, sizeof *this)); // { dg-warning "memcpy" }
1953 T (memmove, (this, p, sizeof *this)); // { dg-warning "memmove" }
1954 T (mempcpy, (this, p, sizeof *this)); // { dg-warning "mempcpy" }
1959 /* A dtor of a base class with virtual function is treated
1960 as an ordinary function. */
1961 T (bzero, (this, sizeof *this)); // { dg-warning "bzero" }
1962 T (memset, (this, 0, sizeof *this)); // { dg-warning "memset" }
1963 T (memcpy, (this, p, sizeof *this)); // { dg-warning "memcpy" }
1964 T (memmove, (this, p, sizeof *this)); // { dg-warning "memmove" }
1965 T (mempcpy, (this, p, sizeof *this)); // { dg-warning "mempcpy" }
1968 virtual void foo ();
1971 struct TestDerived: HasDefault
1975 /* A derived class ctor is treated as an ordinary function. */
1976 T (bzero, (this, sizeof *this)); // { dg-warning "bzero" }
1977 T (memset, (this, 0, sizeof *this)); // { dg-warning "memset" }
1978 T (memcpy, (this, p, sizeof *this));
1979 T (memmove, (this, p, sizeof *this));
1980 T (mempcpy, (this, p, sizeof *this));
1984 struct TestDerivedDtor: HasDefault
1988 /* A derived class dtor is treated as an ordinary function though
1989 it probably shouldn't be unless the base dtor is trivial. But
1990 it doesn't seem worth the trouble. */
1991 T (bzero, (this, sizeof *this)); // { dg-warning "bzero" }
1992 T (memset, (this, 0, sizeof *this)); // { dg-warning "memset" }
1993 T (memcpy, (this, p, sizeof *this)); // { dg-warning "memcpy" }
1994 T (memmove, (this, p, sizeof *this)); // { dg-warning "memmove" }
1995 T (mempcpy, (this, p, sizeof *this)); // { dg-warning "mempcpy" }
2002 // { dg-prune-output "defaulted and deleted functions" }