add alignment to enable store merging in strict-alignment targets
[official-gcc.git] / gcc / testsuite / g++.dg / Wclass-memaccess.C
blob1dc23dfab7e61fa766f87efa460bc190772106f7
1 /* PR c++/80560 - warn on undefined memory operations involving non-trivial
2    types
3    { dg-do compile }
4    { dg-options "-Wclass-memaccess -ftrack-macro-expansion=0" } */
6 typedef __SIZE_TYPE__ size_t;
8 extern "C"
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);
17 namespace std {
19 #if __cplusplus >= 201103L
20 enum class byte: unsigned char { };
21 #else
22 typedef unsigned char byte;
23 #endif
26 #if __cplusplus < 201103L
27 typedef unsigned short char16_t;
28 #endif
30 /* Ordinary bzcopy and bzero aren't recognized as special.  */
31 #define bcopy __builtin_bcopy
32 #define bzero __builtin_bzero
34 void sink (void*);
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.  */
41 struct Trivial
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.
51   template <class U>
52   Trivial& operator= (U);
55 void test (Trivial *p, void *q, int x)
57   const size_t n = x;
59   T (bzero, (p, 1));
60   T (bzero, (p, n));
61   T (bzero, (p, sizeof *p));
62   T (bzero, (q, 1));
63   T (bzero, (q, n));
64   T (bzero, (q, sizeof *p));
66   T (bcopy, (p, q, 1));
67   T (bcopy, (p, q, n));
68   T (bcopy, (p, q, sizeof *p));
69   T (bcopy, (q, p, 1));
70   T (bcopy, (q, p, n));
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));
117 #endif
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.  */
123 struct TrivialAccess
125   int i; unsigned bf: 1; char *s; char a[4];
127 private:
128   TrivialAccess () = default;
129   TrivialAccess (const TrivialAccess&) = default;
130 protected:
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)
140   void *pv;
141   (void)&pv;
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)
155   void *pv;
156   (void)&pv;
158   /* Verify that no warning is issued when the otherwise inaccessible
159      copy ctor and copy assignment can be accessed within the current
160      context.  */
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)
171   void *pv;
172   (void)&pv;
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
178      context.  */
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));
187 #endif
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,
198            const int ia[])
200   const int i = *ia;
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." }
253   extern long *ip;
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));
270 #endif
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
278   template <class U>
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,
285            const int ia[])
287   const int i = *ia;
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));
336 #endif
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,
349            const int ia[])
351   const int i = *ia;
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" }
402 #endif
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" }
423 #endif
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 {
431   int i;
432 private:
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,
439            const int ia[])
441   const int i = *ia;
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" }
484 #endif
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,
495            const int ia[])
497   const int i = *ia;
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" }
541 #endif
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
550   int i;
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,
557            const int ia[])
559   const int i = *ia;
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" }
597 #endif
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
606   int i;
607 private:
608   ~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,
614            const int ia[])
616   const int i = *ia;
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" }
654 #endif
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,
665            const int ia[])
667   const int i = *ia;
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" }
709 #endif
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.  */
715 struct HasMoveAssign
717 #if __cplusplus > 199711L
718   void operator= (HasMoveAssign&&);
719 #else
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&);
723 #endif
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,
729            const int ia[])
731   const int i = *ia;
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" }
773 #endif
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&&);
787 #else
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&);
792 #endif
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,
798            const int ia[])
800   const int i = *ia;
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" }
842 #endif
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;
857 #endif
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,
864            const int ia[])
866   const int i = *ia;
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" }
908 #endif
910 #if !defined TEST || TEST == TEST_TRIVIAL_ASSIGN_REF_OVERLOAD
912 /* TrivialAssignRefOverload is a trivial type.  */
913 struct TrivialAssignRefOverload {
914   int i;
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,
926            const int ia[])
928   const int i = *ia;
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));
965 #endif
967 #if !defined TEST || TEST == TEST_TRIVIAL_ASSIGN_CSTREF_OVERLOAD
969 /* TrivialAssignCstOverload is a trivial type.  */
970 struct TrivialAssignCstRefOverload {
971   int i;
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,
984            const int ia[])
986   const int i = *ia;
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));
1023 #endif
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,
1039            const int ia[])
1041   const int i = *ia;
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" }
1083 #endif
1085 #if !defined TEST || TEST == TEST_HAS_VOLREF_ASSIGN
1087 struct HasVolRefAssign {
1088   int i;
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,
1097            const int ia[])
1099   const int i = *ia;
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" }
1141 #endif
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,
1153            const int ia[])
1155   const int i = *ia;
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" }
1196 #endif
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,
1209            const int ia[])
1211   const int i = *ia;
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.
1217   // *p = x;
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 } } }
1261 #endif
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,
1274            const int ia[])
1276   const int i = *ia;
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.
1282   // *p = x;
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 } } }
1340 #endif
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,
1354            const int ia[])
1356   const int i = *ia;
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));
1409 #endif
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,
1421            const int ia[])
1423   const int i = *ia;
1424   const size_t n = *ia;
1426   // Zeroing out is not diagnosed because it's equivalent to value
1427   // initialization.
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));
1487 #endif
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,
1500            const int ia[])
1502   const int i = *ia;
1503   const size_t n = *ia;
1505   // Zeroing out is not diagnosed because it's equivalent to value
1506   // initialization.
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));
1566 #endif
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,
1579            const int ia[])
1581   const int i = *ia;
1582   const size_t n = *ia;
1584   // Zeroing out is not diagnosed because it's equivalent to value
1585   // initialization.
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));
1645 #endif
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,
1658            const int ia[])
1660   const int i = *ia;
1661   const size_t n = *ia;
1663   // Zeroing out is not diagnosed because it's equivalent to value
1664   // initialization.
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));
1724 #endif
1726 #if !defined TEST || TEST == TEST_DEFAULT_CTOR_PRIVATE_ASSIGN
1728 /* Used to verify suggested alternatives.  */
1729 struct HasDefaultPrivateAssign
1731   char a[4];
1732   HasDefaultPrivateAssign ();
1733 private:
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,
1740            const int ia[])
1742   const int i = *ia;
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" }
1809 #endif
1811 #if !defined TEST || TEST == TEST_DEFAULT_CTOR_DELETED_ASSIGN
1813 /* Used to verify suggested alternatives.  */
1814 struct HasDefaultDeletedAssign
1816   char a[4];
1817   HasDefaultDeletedAssign ();
1818 private:
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,
1825            const int ia[])
1827   const int i = *ia;
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" }
1894 #endif
1896 #if !defined TEST || TEST == TEST_EXPRESSION
1898 void test_expr (int i)
1900   struct TestClass { TestClass () { } };
1901   TestClass a, b;
1903   static void *p;
1905   T (bzero, (i < 0 ? &a : &b, 1));  // { dg-warning "bzero" }
1908 #endif
1910 #if !defined TEST || TEST == TEST_CTOR
1912 void test_ctor ()
1914 #undef T
1915 #define T(fn, arglist) (fn arglist, sink (this))
1917   static void *p;
1919   struct TestBase
1920   {
1921     TestBase ()
1922     {
1923       /* A ctor of a base class with no virtual function can do whatever
1924          it wants.  */
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));
1930     }
1932     ~TestBase ()
1933     {
1934       /* A dtor of a base class with no virtual function can do whatever
1935          it wants.  */
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));
1941     }
1942   };
1944   struct TestBaseVtable
1945   {
1946     TestBaseVtable ()
1947     {
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" }
1955     }
1957     ~TestBaseVtable ()
1958     {
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" }
1966     }
1968     virtual void foo ();
1969   };
1971   struct TestDerived: HasDefault
1972   {
1973     TestDerived ()
1974     {
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));
1981     }
1982   };
1984   struct TestDerivedDtor: HasDefault
1985   {
1986     ~TestDerivedDtor ()
1987     {
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" }
1996     }
1997   };
2000 #endif
2002 // { dg-prune-output "defaulted and deleted functions" }