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