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