xref: /minix3/external/bsd/llvm/dist/clang/test/SemaCXX/warn-bad-memaccess.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -Wdynamic-class-memaccess -verify %s
2*f4a2713aSLionel Sambuc 
3*f4a2713aSLionel Sambuc extern "C" void *memset(void *, int, unsigned);
4*f4a2713aSLionel Sambuc extern "C" void *memmove(void *s1, const void *s2, unsigned n);
5*f4a2713aSLionel Sambuc extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
6*f4a2713aSLionel Sambuc extern "C" void *memcmp(void *s1, const void *s2, unsigned n);
7*f4a2713aSLionel Sambuc 
8*f4a2713aSLionel Sambuc 
9*f4a2713aSLionel Sambuc // Redeclare without the extern "C" to test that we still figure out that this
10*f4a2713aSLionel Sambuc // is the "real" memset.
11*f4a2713aSLionel Sambuc void *memset(void *, int, unsigned);
12*f4a2713aSLionel Sambuc 
13*f4a2713aSLionel Sambuc // Several types that should not warn.
14*f4a2713aSLionel Sambuc struct S1 {} s1;
15*f4a2713aSLionel Sambuc struct S2 { int x; } s2;
16*f4a2713aSLionel Sambuc struct S3 { float x, y; S1 s[4]; void (*f)(S1**); } s3;
17*f4a2713aSLionel Sambuc 
18*f4a2713aSLionel Sambuc class C1 {
19*f4a2713aSLionel Sambuc   int x, y, z;
20*f4a2713aSLionel Sambuc public:
21*f4a2713aSLionel Sambuc   void foo() {}
22*f4a2713aSLionel Sambuc } c1;
23*f4a2713aSLionel Sambuc 
24*f4a2713aSLionel Sambuc struct X1 { virtual void f(); } x1;
25*f4a2713aSLionel Sambuc struct X2 : virtual S1 {} x2;
26*f4a2713aSLionel Sambuc 
27*f4a2713aSLionel Sambuc void test_warn() {
28*f4a2713aSLionel Sambuc   memset(&x1, 0, sizeof x1); // \
29*f4a2713aSLionel Sambuc       // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
30*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
31*f4a2713aSLionel Sambuc   memset(&x2, 0, sizeof x2); // \
32*f4a2713aSLionel Sambuc       // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
33*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
34*f4a2713aSLionel Sambuc 
35*f4a2713aSLionel Sambuc   memmove(&x1, 0, sizeof x1); // \
36*f4a2713aSLionel Sambuc       // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
37*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
38*f4a2713aSLionel Sambuc   memmove(0, &x1, sizeof x1); // \
39*f4a2713aSLionel Sambuc       // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be moved}} \
40*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
41*f4a2713aSLionel Sambuc   memcpy(&x1, 0, sizeof x1); // \
42*f4a2713aSLionel Sambuc       // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
43*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
44*f4a2713aSLionel Sambuc   memcpy(0, &x1, sizeof x1); // \
45*f4a2713aSLionel Sambuc       // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be copied}} \
46*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
47*f4a2713aSLionel Sambuc   memcmp(&x1, 0, sizeof x1); // \
48*f4a2713aSLionel Sambuc       // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
49*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
50*f4a2713aSLionel Sambuc   memcmp(0, &x1, sizeof x1); // \
51*f4a2713aSLionel Sambuc       // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
52*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
53*f4a2713aSLionel Sambuc 
54*f4a2713aSLionel Sambuc   __builtin_memset(&x1, 0, sizeof x1); // \
55*f4a2713aSLionel Sambuc       // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
56*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
57*f4a2713aSLionel Sambuc   __builtin_memset(&x2, 0, sizeof x2); // \
58*f4a2713aSLionel Sambuc       // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
59*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
60*f4a2713aSLionel Sambuc 
61*f4a2713aSLionel Sambuc   __builtin_memmove(&x1, 0, sizeof x1); // \
62*f4a2713aSLionel Sambuc       // expected-warning{{destination for this '__builtin_memmove' call is a pointer to dynamic class}} \
63*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
64*f4a2713aSLionel Sambuc   __builtin_memmove(0, &x1, sizeof x1); // \
65*f4a2713aSLionel Sambuc       // expected-warning{{source of this '__builtin_memmove' call is a pointer to dynamic class}} \
66*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
67*f4a2713aSLionel Sambuc   __builtin_memcpy(&x1, 0, sizeof x1); // \
68*f4a2713aSLionel Sambuc       // expected-warning{{destination for this '__builtin_memcpy' call is a pointer to dynamic class}} \
69*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
70*f4a2713aSLionel Sambuc   __builtin_memcpy(0, &x1, sizeof x1); // \
71*f4a2713aSLionel Sambuc       // expected-warning{{source of this '__builtin_memcpy' call is a pointer to dynamic class}} \
72*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
73*f4a2713aSLionel Sambuc 
74*f4a2713aSLionel Sambuc   __builtin___memset_chk(&x1, 0, sizeof x1, sizeof x1); //                    \
75*f4a2713aSLionel Sambuc       // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
76*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
77*f4a2713aSLionel Sambuc   __builtin___memset_chk(&x2, 0, sizeof x2, sizeof x2); //                    \
78*f4a2713aSLionel Sambuc       // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
79*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
80*f4a2713aSLionel Sambuc 
81*f4a2713aSLionel Sambuc   __builtin___memmove_chk(&x1, 0, sizeof x1, sizeof x1); //                   \
82*f4a2713aSLionel Sambuc       // expected-warning{{destination for this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
83*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
84*f4a2713aSLionel Sambuc   __builtin___memmove_chk(0, &x1, sizeof x1, sizeof x1); //                   \
85*f4a2713aSLionel Sambuc       // expected-warning{{source of this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
86*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
87*f4a2713aSLionel Sambuc   __builtin___memcpy_chk(&x1, 0, sizeof x1, sizeof x1); //                    \
88*f4a2713aSLionel Sambuc       // expected-warning{{destination for this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
89*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
90*f4a2713aSLionel Sambuc   __builtin___memcpy_chk(0, &x1, sizeof x1, sizeof x1); //                    \
91*f4a2713aSLionel Sambuc       // expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
92*f4a2713aSLionel Sambuc       // expected-note {{explicitly cast the pointer to silence this warning}}
93*f4a2713aSLionel Sambuc }
94*f4a2713aSLionel Sambuc 
95*f4a2713aSLionel Sambuc void test_nowarn(void *void_ptr) {
96*f4a2713aSLionel Sambuc   int i, *iptr;
97*f4a2713aSLionel Sambuc   float y;
98*f4a2713aSLionel Sambuc   char c;
99*f4a2713aSLionel Sambuc 
100*f4a2713aSLionel Sambuc   memset(&i, 0, sizeof i);
101*f4a2713aSLionel Sambuc   memset(&iptr, 0, sizeof iptr);
102*f4a2713aSLionel Sambuc   memset(&y, 0, sizeof y);
103*f4a2713aSLionel Sambuc   memset(&c, 0, sizeof c);
104*f4a2713aSLionel Sambuc   memset(void_ptr, 0, 42);
105*f4a2713aSLionel Sambuc   memset(&s1, 0, sizeof s1);
106*f4a2713aSLionel Sambuc   memset(&s2, 0, sizeof s2);
107*f4a2713aSLionel Sambuc   memset(&s3, 0, sizeof s3);
108*f4a2713aSLionel Sambuc   memset(&c1, 0, sizeof c1);
109*f4a2713aSLionel Sambuc 
110*f4a2713aSLionel Sambuc   // Unevaluated code shouldn't warn.
111*f4a2713aSLionel Sambuc   (void)sizeof memset(&x1, 0, sizeof x1);
112*f4a2713aSLionel Sambuc 
113*f4a2713aSLionel Sambuc   // Dead code shouldn't warn.
114*f4a2713aSLionel Sambuc   if (false) memset(&x1, 0, sizeof x1);
115*f4a2713aSLionel Sambuc }
116*f4a2713aSLionel Sambuc 
117*f4a2713aSLionel Sambuc namespace N {
118*f4a2713aSLionel Sambuc   void *memset(void *, int, unsigned);
119*f4a2713aSLionel Sambuc   void test_nowarn() {
120*f4a2713aSLionel Sambuc     N::memset(&x1, 0, sizeof x1);
121*f4a2713aSLionel Sambuc   }
122*f4a2713aSLionel Sambuc }
123