warn-bad-memaccess.cpp revision 9f0c692c4db9012248c65fab6cb703f2ce444dfe
1929f0135ab60166202f52e0dd19835c0490d792aChandler Carruth// RUN: %clang_cc1 -fsyntax-only -Wdynamic-class-memaccess -verify %s
27ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth
3e452c78072156c14cd9998733e3b4b28b6fc7fd7Douglas Gregorextern "C" void *memset(void *, int, unsigned);
406bc9eb9908e42696775b395b290827bde468c8bDouglas Gregorextern "C" void *memmove(void *s1, const void *s2, unsigned n);
506bc9eb9908e42696775b395b290827bde468c8bDouglas Gregorextern "C" void *memcpy(void *s1, const void *s2, unsigned n);
65c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gayextern "C" void *memcmp(void *s1, const void *s2, unsigned n);
77ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth
89f0c692c4db9012248c65fab6cb703f2ce444dfeRafael Espindola
99f0c692c4db9012248c65fab6cb703f2ce444dfeRafael Espindola// Redeclare without the extern "C" to test that we still figure out that this
109f0c692c4db9012248c65fab6cb703f2ce444dfeRafael Espindola// is the "real" memset.
119f0c692c4db9012248c65fab6cb703f2ce444dfeRafael Espindolavoid *memset(void *, int, unsigned);
129f0c692c4db9012248c65fab6cb703f2ce444dfeRafael Espindola
13929f0135ab60166202f52e0dd19835c0490d792aChandler Carruth// Several types that should not warn.
147ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruthstruct S1 {} s1;
157ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruthstruct S2 { int x; } s2;
167ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruthstruct S3 { float x, y; S1 s[4]; void (*f)(S1**); } s3;
177ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth
1843fa33b4bedc28d2faa17d678ad1f40eb42817a1Chandler Carruthclass C1 {
1943fa33b4bedc28d2faa17d678ad1f40eb42817a1Chandler Carruth  int x, y, z;
2043fa33b4bedc28d2faa17d678ad1f40eb42817a1Chandler Carruthpublic:
2143fa33b4bedc28d2faa17d678ad1f40eb42817a1Chandler Carruth  void foo() {}
2243fa33b4bedc28d2faa17d678ad1f40eb42817a1Chandler Carruth} c1;
2343fa33b4bedc28d2faa17d678ad1f40eb42817a1Chandler Carruth
24929f0135ab60166202f52e0dd19835c0490d792aChandler Carruthstruct X1 { virtual void f(); } x1;
25929f0135ab60166202f52e0dd19835c0490d792aChandler Carruthstruct X2 : virtual S1 {} x2;
267ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth
277ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruthvoid test_warn() {
287ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth  memset(&x1, 0, sizeof x1); // \
2906bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
307ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth      // expected-note {{explicitly cast the pointer to silence this warning}}
31929f0135ab60166202f52e0dd19835c0490d792aChandler Carruth  memset(&x2, 0, sizeof x2); // \
3206bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
3306bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
3406bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor
3506bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor  memmove(&x1, 0, sizeof x1); // \
365c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay      // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
3706bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
3806bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor  memmove(0, &x1, sizeof x1); // \
395c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay      // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be moved}} \
4006bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
4106bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor  memcpy(&x1, 0, sizeof x1); // \
425c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay      // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
4306bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
4406bc9eb9908e42696775b395b290827bde468c8bDouglas Gregor  memcpy(0, &x1, sizeof x1); // \
455c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay      // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be copied}} \
465c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay      // expected-note {{explicitly cast the pointer to silence this warning}}
475c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay  memcmp(&x1, 0, sizeof x1); // \
485c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay      // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
495c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay      // expected-note {{explicitly cast the pointer to silence this warning}}
505c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay  memcmp(0, &x1, sizeof x1); // \
515c5218e188b39b2e93b541156a69ef061e11aab8Matt Beaumont-Gay      // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
527ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth      // expected-note {{explicitly cast the pointer to silence this warning}}
53707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor
54707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin_memset(&x1, 0, sizeof x1); // \
55707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
56707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
57707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin_memset(&x2, 0, sizeof x2); // \
58707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \
59707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
60707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor
61707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin_memmove(&x1, 0, sizeof x1); // \
62707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning{{destination for this '__builtin_memmove' call is a pointer to dynamic class}} \
63707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
64707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin_memmove(0, &x1, sizeof x1); // \
65707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning{{source of this '__builtin_memmove' call is a pointer to dynamic class}} \
66707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
67707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin_memcpy(&x1, 0, sizeof x1); // \
68707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning{{destination for this '__builtin_memcpy' call is a pointer to dynamic class}} \
69707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
70707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin_memcpy(0, &x1, sizeof x1); // \
71707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning{{source of this '__builtin_memcpy' call is a pointer to dynamic class}} \
72707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
73707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor
74707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin___memset_chk(&x1, 0, sizeof x1, sizeof x1); //                    \
75707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
76707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
77707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin___memset_chk(&x2, 0, sizeof x2, sizeof x2); //                    \
78707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \
79707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
80707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor
81707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin___memmove_chk(&x1, 0, sizeof x1, sizeof x1); //                   \
82707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning{{destination for this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
83707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
84707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin___memmove_chk(0, &x1, sizeof x1, sizeof x1); //                   \
85707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning{{source of this '__builtin___memmove_chk' call is a pointer to dynamic class}} \
86707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
87707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin___memcpy_chk(&x1, 0, sizeof x1, sizeof x1); //                    \
88707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning{{destination for this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
89707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
90707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor  __builtin___memcpy_chk(0, &x1, sizeof x1, sizeof x1); //                    \
91707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
92707a23e8b87410332b55bb4534fa1c799edef38aDouglas Gregor      // expected-note {{explicitly cast the pointer to silence this warning}}
937ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth}
947ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth
95134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruthvoid test_nowarn(void *void_ptr) {
96134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth  int i, *iptr;
97134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth  float y;
98134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth  char c;
99134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth
100134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth  memset(&i, 0, sizeof i);
101134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth  memset(&iptr, 0, sizeof iptr);
102134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth  memset(&y, 0, sizeof y);
103134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth  memset(&c, 0, sizeof c);
104134cb4442d6205e0226944ead4c7ede425fba206Chandler Carruth  memset(void_ptr, 0, 42);
1057ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth  memset(&s1, 0, sizeof s1);
1067ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth  memset(&s2, 0, sizeof s2);
1077ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth  memset(&s3, 0, sizeof s3);
10843fa33b4bedc28d2faa17d678ad1f40eb42817a1Chandler Carruth  memset(&c1, 0, sizeof c1);
1097ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth
1107ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth  // Unevaluated code shouldn't warn.
1117ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth  (void)sizeof memset(&x1, 0, sizeof x1);
1127ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth
1137ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth  // Dead code shouldn't warn.
1147ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth  if (false) memset(&x1, 0, sizeof x1);
1157ccc95bceebb2d1c8fbe277c9e33bde7dc1ccbb1Chandler Carruth}
116e452c78072156c14cd9998733e3b4b28b6fc7fd7Douglas Gregor
117e452c78072156c14cd9998733e3b4b28b6fc7fd7Douglas Gregornamespace N {
118e452c78072156c14cd9998733e3b4b28b6fc7fd7Douglas Gregor  void *memset(void *, int, unsigned);
119e452c78072156c14cd9998733e3b4b28b6fc7fd7Douglas Gregor  void test_nowarn() {
120e452c78072156c14cd9998733e3b4b28b6fc7fd7Douglas Gregor    N::memset(&x1, 0, sizeof x1);
121e452c78072156c14cd9998733e3b4b28b6fc7fd7Douglas Gregor  }
122e452c78072156c14cd9998733e3b4b28b6fc7fd7Douglas Gregor}
123