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