blob: 7a7459acee1d3ca2317daf8df8610cb11a158e7b [file] [log] [blame]
Chandler Carruth929f0132011-06-03 06:23:57 +00001// RUN: %clang_cc1 -fsyntax-only -Wdynamic-class-memaccess -verify %s
Chandler Carruth7ccc95b2011-04-27 07:05:31 +00002
Douglas Gregore452c782011-05-03 18:11:37 +00003extern "C" void *memset(void *, int, unsigned);
Douglas Gregor06bc9eb2011-05-03 20:37:33 +00004extern "C" void *memmove(void *s1, const void *s2, unsigned n);
5extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
Matt Beaumont-Gay5c5218e2011-08-19 20:40:18 +00006extern "C" void *memcmp(void *s1, const void *s2, unsigned n);
Chandler Carruth7ccc95b2011-04-27 07:05:31 +00007
Rafael Espindola9f0c6922012-12-30 17:23:09 +00008
9// Redeclare without the extern "C" to test that we still figure out that this
10// is the "real" memset.
11void *memset(void *, int, unsigned);
12
Chandler Carruth929f0132011-06-03 06:23:57 +000013// Several types that should not warn.
Chandler Carruth7ccc95b2011-04-27 07:05:31 +000014struct S1 {} s1;
15struct S2 { int x; } s2;
16struct S3 { float x, y; S1 s[4]; void (*f)(S1**); } s3;
17
Chandler Carruth43fa33b2011-04-29 09:46:08 +000018class C1 {
19 int x, y, z;
20public:
21 void foo() {}
22} c1;
23
Chandler Carruth929f0132011-06-03 06:23:57 +000024struct X1 { virtual void f(); } x1;
25struct X2 : virtual S1 {} x2;
Chandler Carruth7ccc95b2011-04-27 07:05:31 +000026
27void test_warn() {
28 memset(&x1, 0, sizeof x1); // \
Douglas Gregor06bc9eb2011-05-03 20:37:33 +000029 // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
Chandler Carruth7ccc95b2011-04-27 07:05:31 +000030 // expected-note {{explicitly cast the pointer to silence this warning}}
Chandler Carruth929f0132011-06-03 06:23:57 +000031 memset(&x2, 0, sizeof x2); // \
Douglas Gregor06bc9eb2011-05-03 20:37:33 +000032 // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
33 // expected-note {{explicitly cast the pointer to silence this warning}}
34
35 memmove(&x1, 0, sizeof x1); // \
Matt Beaumont-Gay5c5218e2011-08-19 20:40:18 +000036 // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
Douglas Gregor06bc9eb2011-05-03 20:37:33 +000037 // expected-note {{explicitly cast the pointer to silence this warning}}
38 memmove(0, &x1, sizeof x1); // \
Matt Beaumont-Gay5c5218e2011-08-19 20:40:18 +000039 // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be moved}} \
Douglas Gregor06bc9eb2011-05-03 20:37:33 +000040 // expected-note {{explicitly cast the pointer to silence this warning}}
41 memcpy(&x1, 0, sizeof x1); // \
Matt Beaumont-Gay5c5218e2011-08-19 20:40:18 +000042 // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
Douglas Gregor06bc9eb2011-05-03 20:37:33 +000043 // expected-note {{explicitly cast the pointer to silence this warning}}
44 memcpy(0, &x1, sizeof x1); // \
Matt Beaumont-Gay5c5218e2011-08-19 20:40:18 +000045 // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be copied}} \
46 // expected-note {{explicitly cast the pointer to silence this warning}}
47 memcmp(&x1, 0, sizeof x1); // \
48 // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
49 // expected-note {{explicitly cast the pointer to silence this warning}}
50 memcmp(0, &x1, sizeof x1); // \
51 // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
Chandler Carruth7ccc95b2011-04-27 07:05:31 +000052 // expected-note {{explicitly cast the pointer to silence this warning}}
Douglas Gregor707a23e2011-06-16 17:56:04 +000053
54 __builtin_memset(&x1, 0, sizeof x1); // \
55 // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
56 // expected-note {{explicitly cast the pointer to silence this warning}}
57 __builtin_memset(&x2, 0, sizeof x2); // \
58 // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
59 // expected-note {{explicitly cast the pointer to silence this warning}}
60
61 __builtin_memmove(&x1, 0, sizeof x1); // \
62 // expected-warning{{destination for this '__builtin_memmove' call is a pointer to dynamic class}} \
63 // expected-note {{explicitly cast the pointer to silence this warning}}
64 __builtin_memmove(0, &x1, sizeof x1); // \
65 // expected-warning{{source of this '__builtin_memmove' call is a pointer to dynamic class}} \
66 // expected-note {{explicitly cast the pointer to silence this warning}}
67 __builtin_memcpy(&x1, 0, sizeof x1); // \
68 // expected-warning{{destination for this '__builtin_memcpy' call is a pointer to dynamic class}} \
69 // expected-note {{explicitly cast the pointer to silence this warning}}
70 __builtin_memcpy(0, &x1, sizeof x1); // \
71 // expected-warning{{source of this '__builtin_memcpy' call is a pointer to dynamic class}} \
72 // expected-note {{explicitly cast the pointer to silence this warning}}
73
74 __builtin___memset_chk(&x1, 0, sizeof x1, sizeof x1); // \
75 // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
76 // expected-note {{explicitly cast the pointer to silence this warning}}
77 __builtin___memset_chk(&x2, 0, sizeof x2, sizeof x2); // \
78 // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
79 // expected-note {{explicitly cast the pointer to silence this warning}}
80
81 __builtin___memmove_chk(&x1, 0, sizeof x1, sizeof x1); // \
82 // expected-warning{{destination for this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
83 // expected-note {{explicitly cast the pointer to silence this warning}}
84 __builtin___memmove_chk(0, &x1, sizeof x1, sizeof x1); // \
85 // expected-warning{{source of this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
86 // expected-note {{explicitly cast the pointer to silence this warning}}
87 __builtin___memcpy_chk(&x1, 0, sizeof x1, sizeof x1); // \
88 // expected-warning{{destination for this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
89 // expected-note {{explicitly cast the pointer to silence this warning}}
90 __builtin___memcpy_chk(0, &x1, sizeof x1, sizeof x1); // \
91 // expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
92 // expected-note {{explicitly cast the pointer to silence this warning}}
Chandler Carruth7ccc95b2011-04-27 07:05:31 +000093}
94
Chandler Carruth134cb442011-04-27 18:48:59 +000095void test_nowarn(void *void_ptr) {
96 int i, *iptr;
97 float y;
98 char c;
99
100 memset(&i, 0, sizeof i);
101 memset(&iptr, 0, sizeof iptr);
102 memset(&y, 0, sizeof y);
103 memset(&c, 0, sizeof c);
104 memset(void_ptr, 0, 42);
Chandler Carruth7ccc95b2011-04-27 07:05:31 +0000105 memset(&s1, 0, sizeof s1);
106 memset(&s2, 0, sizeof s2);
107 memset(&s3, 0, sizeof s3);
Chandler Carruth43fa33b2011-04-29 09:46:08 +0000108 memset(&c1, 0, sizeof c1);
Chandler Carruth7ccc95b2011-04-27 07:05:31 +0000109
110 // Unevaluated code shouldn't warn.
111 (void)sizeof memset(&x1, 0, sizeof x1);
112
113 // Dead code shouldn't warn.
114 if (false) memset(&x1, 0, sizeof x1);
115}
Douglas Gregore452c782011-05-03 18:11:37 +0000116
117namespace N {
118 void *memset(void *, int, unsigned);
119 void test_nowarn() {
120 N::memset(&x1, 0, sizeof x1);
121 }
122}