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