brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.3 KiB · 2b32475 Raw
164 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -Wdynamic-class-memaccess -verify %s2 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);6extern "C" int memcmp(void *s1, const void *s2, unsigned n);7extern "C" int bcmp(void *s1, const void *s2, unsigned n);8 9 10// Redeclare without the extern "C" to test that we still figure out that this11// is the "real" memset.12void *memset(void *, int, unsigned);13 14// Several types that should not warn.15struct S1 {} s1;16struct S2 { int x; } s2;17struct S3 { float x, y; S1 s[4]; void (*f)(S1**); } s3;18 19class C1 {20  int x, y, z;21public:22  void foo() {}23} c1;24 25struct X1 { virtual void f(); } x1, x1arr[2];26struct X2 : virtual S1 {} x2;27 28struct ContainsDynamic { X1 dynamic; } contains_dynamic;29struct DeepContainsDynamic { ContainsDynamic m; } deep_contains_dynamic;30struct ContainsArrayDynamic { X1 dynamic[1]; } contains_array_dynamic;31struct ContainsPointerDynamic { X1 *dynamic; } contains_pointer_dynamic;32 33void test_warn() {34  memset(&x1, 0, sizeof x1); // \35      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \36      // expected-note {{explicitly cast the pointer to silence this warning}}37  memset(x1arr, 0, sizeof x1arr); // \38      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \39      // expected-note {{explicitly cast the pointer to silence this warning}}40  memset((void*)x1arr, 0, sizeof x1arr);41  memset(&x2, 0, sizeof x2); // \42      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \43      // expected-note {{explicitly cast the pointer to silence this warning}}44 45  memmove(&x1, 0, sizeof x1); // \46      // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \47      // expected-note {{explicitly cast the pointer to silence this warning}}48  memmove(0, &x1, sizeof x1); // \49      // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be moved}} \50      // expected-note {{explicitly cast the pointer to silence this warning}}51  memcpy(&x1, 0, sizeof x1); // \52      // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \53      // expected-note {{explicitly cast the pointer to silence this warning}}54  memcpy(0, &x1, sizeof x1); // \55      // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be copied}} \56      // expected-note {{explicitly cast the pointer to silence this warning}}57  memcmp(&x1, 0, sizeof x1); // \58      // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \59      // expected-note {{explicitly cast the pointer to silence this warning}}60  memcmp(0, &x1, sizeof x1); // \61      // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \62      // expected-note {{explicitly cast the pointer to silence this warning}}63  bcmp(&x1, 0, sizeof x1); // \64      // expected-warning{{first operand of this 'bcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \65      // expected-note {{explicitly cast the pointer to silence this warning}}66  bcmp(0, &x1, sizeof x1); // \67      // expected-warning{{second operand of this 'bcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \68      // expected-note {{explicitly cast the pointer to silence this warning}}69 70  __builtin_memset(&x1, 0, sizeof x1); // \71      // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \72      // expected-note {{explicitly cast the pointer to silence this warning}}73  __builtin_memset(&x2, 0, sizeof x2); // \74      // expected-warning {{destination for this '__builtin_memset' call is a pointer to dynamic class}} \75      // expected-note {{explicitly cast the pointer to silence this warning}}76 77  __builtin_memmove(&x1, 0, sizeof x1); // \78      // expected-warning{{destination for this '__builtin_memmove' call is a pointer to dynamic class}} \79      // expected-note {{explicitly cast the pointer to silence this warning}}80  __builtin_memmove(0, &x1, sizeof x1); // \81      // expected-warning{{source of this '__builtin_memmove' call is a pointer to dynamic class}} \82      // expected-note {{explicitly cast the pointer to silence this warning}}83  __builtin_memcpy(&x1, 0, sizeof x1); // \84      // expected-warning{{destination for this '__builtin_memcpy' call is a pointer to dynamic class}} \85      // expected-note {{explicitly cast the pointer to silence this warning}}86  __builtin_memcpy(0, &x1, sizeof x1); // \87      // expected-warning{{source of this '__builtin_memcpy' call is a pointer to dynamic class}} \88      // expected-note {{explicitly cast the pointer to silence this warning}}89 90  __builtin___memset_chk(&x1, 0, sizeof x1, sizeof x1); //                    \91      // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \92      // expected-note {{explicitly cast the pointer to silence this warning}}93  __builtin___memset_chk(&x2, 0, sizeof x2, sizeof x2); //                    \94      // expected-warning {{destination for this '__builtin___memset_chk' call is a pointer to dynamic class}} \95      // expected-note {{explicitly cast the pointer to silence this warning}}96 97  __builtin___memmove_chk(&x1, 0, sizeof x1, sizeof x1); //                   \98      // expected-warning{{destination for this '__builtin___memmove_chk' call is a pointer to dynamic class}} \99      // expected-note {{explicitly cast the pointer to silence this warning}}100  __builtin___memmove_chk(0, &x1, sizeof x1, sizeof x1); //                   \101      // expected-warning{{source of this '__builtin___memmove_chk' call is a pointer to dynamic class}} \102      // expected-note {{explicitly cast the pointer to silence this warning}}103  __builtin___memcpy_chk(&x1, 0, sizeof x1, sizeof x1); //                    \104      // expected-warning{{destination for this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \105      // expected-note {{explicitly cast the pointer to silence this warning}}106  __builtin___memcpy_chk(0, &x1, sizeof x1, sizeof x1); //                    \107      // expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \108      // expected-note {{explicitly cast the pointer to silence this warning}}109 110  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}111  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}112  memset(&contains_dynamic, 0, sizeof(contains_dynamic));113  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}114  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}115  memset(&deep_contains_dynamic, 0, sizeof(deep_contains_dynamic));116  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}117  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}118  memset(&contains_array_dynamic, 0, sizeof(contains_array_dynamic));119}120 121void test_nowarn(void *void_ptr) {122  int i, *iptr;123  float y;124  char c;125 126  memset(&i, 0, sizeof i);127  memset(&iptr, 0, sizeof iptr);128  memset(&y, 0, sizeof y);129  memset(&c, 0, sizeof c);130  memset(void_ptr, 0, 42);131  memset(&s1, 0, sizeof s1);132  memset(&s2, 0, sizeof s2);133  memset(&s3, 0, sizeof s3);134  memset(&c1, 0, sizeof c1);135 136  memset(&contains_pointer_dynamic, 0, sizeof(contains_pointer_dynamic));137 138  // Unevaluated code shouldn't warn.139  (void)sizeof memset(&x1, 0, sizeof x1);140 141  // Dead code shouldn't warn.142  if (false) memset(&x1, 0, sizeof x1);143}144 145namespace N {146  void *memset(void *, int, unsigned);147  void test_nowarn() {148    N::memset(&x1, 0, sizeof x1);149  }150}151 152namespace recursive_class {153struct S {154  S v;155  // expected-error@-1{{field has incomplete type 'S'}}156  // expected-note@-3{{definition of 'recursive_class::S' is not complete until the closing '}'}}157} a;158 159int main() {160  __builtin_memset(&a, 0, sizeof a);161  return 0;162}163}164