1 // RUN: %clang_cc1 -fsyntax-only -Wdynamic-class-memaccess -verify %s
3 extern "C" void *memset(void *, int, unsigned);
4 extern "C" void *memmove(void *s1
, const void *s2
, unsigned n
);
5 extern "C" void *memcpy(void *s1
, const void *s2
, unsigned n
);
6 extern "C" int memcmp(void *s1
, const void *s2
, unsigned n
);
7 extern "C" int bcmp(void *s1
, const void *s2
, unsigned n
);
10 // Redeclare without the extern "C" to test that we still figure out that this
11 // is the "real" memset.
12 void *memset(void *, int, unsigned);
14 // Several types that should not warn.
16 struct S2
{ int x
; } s2
;
17 struct S3
{ float x
, y
; S1 s
[4]; void (*f
)(S1
**); } s3
;
25 struct X1
{ virtual void f(); } x1
, x1arr
[2];
26 struct X2
: virtual S1
{} x2
;
28 struct ContainsDynamic
{ X1 dynamic
; } contains_dynamic
;
29 struct DeepContainsDynamic
{ ContainsDynamic m
; } deep_contains_dynamic
;
30 struct ContainsArrayDynamic
{ X1 dynamic
[1]; } contains_array_dynamic
;
31 struct ContainsPointerDynamic
{ X1
*dynamic
; } contains_pointer_dynamic
;
34 memset(&x1
, 0, sizeof x1
); // \
35 // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
36 // expected-note {{explicitly cast the pointer to silence this warning}}
37 memset(x1arr
, 0, sizeof x1arr
); // \
38 // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
39 // expected-note {{explicitly cast the pointer to silence this warning}}
40 memset((void*)x1arr
, 0, sizeof x1arr
);
41 memset(&x2
, 0, sizeof x2
); // \
42 // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
43 // expected-note {{explicitly cast the pointer to silence this warning}}
45 memmove(&x1
, 0, sizeof x1
); // \
46 // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \
47 // expected-note {{explicitly cast the pointer to silence this warning}}
48 memmove(0, &x1
, sizeof x1
); // \
49 // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be moved}} \
50 // expected-note {{explicitly cast the pointer to silence this warning}}
51 memcpy(&x1
, 0, sizeof x1
); // \
52 // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \
53 // expected-note {{explicitly cast the pointer to silence this warning}}
54 memcpy(0, &x1
, sizeof x1
); // \
55 // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be copied}} \
56 // expected-note {{explicitly cast the pointer to silence this warning}}
57 memcmp(&x1
, 0, sizeof x1
); // \
58 // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
59 // expected-note {{explicitly cast the pointer to silence this warning}}
60 memcmp(0, &x1
, sizeof x1
); // \
61 // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
62 // expected-note {{explicitly cast the pointer to silence this warning}}
63 bcmp(&x1
, 0, sizeof x1
); // \
64 // expected-warning{{first operand of this 'bcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
65 // expected-note {{explicitly cast the pointer to silence this warning}}
66 bcmp(0, &x1
, sizeof x1
); // \
67 // expected-warning{{second operand of this 'bcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
68 // expected-note {{explicitly cast the pointer to silence this warning}}
70 __builtin_memset(&x1
, 0, sizeof x1
); // \
71 // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
72 // expected-note {{explicitly cast the pointer to silence this warning}}
73 __builtin_memset(&x2
, 0, sizeof x2
); // \
74 // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
75 // expected-note {{explicitly cast the pointer to silence this warning}}
77 __builtin_memmove(&x1
, 0, sizeof x1
); // \
78 // expected-warning{{destination for this '__builtin_memmove' call is a pointer to dynamic class}} \
79 // expected-note {{explicitly cast the pointer to silence this warning}}
80 __builtin_memmove(0, &x1
, sizeof x1
); // \
81 // expected-warning{{source of this '__builtin_memmove' call is a pointer to dynamic class}} \
82 // expected-note {{explicitly cast the pointer to silence this warning}}
83 __builtin_memcpy(&x1
, 0, sizeof x1
); // \
84 // expected-warning{{destination for this '__builtin_memcpy' call is a pointer to dynamic class}} \
85 // expected-note {{explicitly cast the pointer to silence this warning}}
86 __builtin_memcpy(0, &x1
, sizeof x1
); // \
87 // expected-warning{{source of this '__builtin_memcpy' call is a pointer to dynamic class}} \
88 // expected-note {{explicitly cast the pointer to silence this warning}}
90 __builtin___memset_chk(&x1
, 0, sizeof x1
, sizeof x1
); // \
91 // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
92 // expected-note {{explicitly cast the pointer to silence this warning}}
93 __builtin___memset_chk(&x2
, 0, sizeof x2
, sizeof x2
); // \
94 // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
95 // expected-note {{explicitly cast the pointer to silence this warning}}
97 __builtin___memmove_chk(&x1
, 0, sizeof x1
, sizeof x1
); // \
98 // expected-warning{{destination for this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
99 // expected-note {{explicitly cast the pointer to silence this warning}}
100 __builtin___memmove_chk(0, &x1
, sizeof x1
, sizeof x1
); // \
101 // expected-warning{{source of this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
102 // expected-note {{explicitly cast the pointer to silence this warning}}
103 __builtin___memcpy_chk(&x1
, 0, sizeof x1
, sizeof x1
); // \
104 // expected-warning{{destination for this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
105 // expected-note {{explicitly cast the pointer to silence this warning}}
106 __builtin___memcpy_chk(0, &x1
, sizeof x1
, sizeof x1
); // \
107 // expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
108 // expected-note {{explicitly cast the pointer to silence this warning}}
110 // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
111 // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
112 memset(&contains_dynamic
, 0, sizeof(contains_dynamic
));
113 // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
114 // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
115 memset(&deep_contains_dynamic
, 0, sizeof(deep_contains_dynamic
));
116 // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
117 // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
118 memset(&contains_array_dynamic
, 0, sizeof(contains_array_dynamic
));
121 void test_nowarn(void *void_ptr
) {
126 memset(&i
, 0, sizeof i
);
127 memset(&iptr
, 0, sizeof iptr
);
128 memset(&y
, 0, sizeof y
);
129 memset(&c
, 0, sizeof c
);
130 memset(void_ptr
, 0, 42);
131 memset(&s1
, 0, sizeof s1
);
132 memset(&s2
, 0, sizeof s2
);
133 memset(&s3
, 0, sizeof s3
);
134 memset(&c1
, 0, sizeof c1
);
136 memset(&contains_pointer_dynamic
, 0, sizeof(contains_pointer_dynamic
));
138 // Unevaluated code shouldn't warn.
139 (void)sizeof memset(&x1
, 0, sizeof x1
);
141 // Dead code shouldn't warn.
142 if (false) memset(&x1
, 0, sizeof x1
);
146 void *memset(void *, int, unsigned);
148 N::memset(&x1
, 0, sizeof x1
);
152 namespace recursive_class
{
155 // expected-error@-1{{field has incomplete type 'S'}}
156 // expected-note@-3{{definition of 'recursive_class::S' is not complete until the closing '}'}}
160 __builtin_memset(&a
, 0, sizeof a
);