1 // RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 2 3 // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 4 5 // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t 6 7 #include <sanitizer/msan_interface.h> 8 #include <assert.h> 9 10 // TODO: remove empty dtors when msan use-after-dtor poisons 11 // for trivial classes with undeclared dtors 12 13 // 24 bytes total 14 struct Packed { 15 // Packed into 4 bytes 16 unsigned int a : 1; 17 unsigned int b : 1; 18 // Force alignment to next 4 bytes 19 unsigned int : 0; 20 unsigned int c : 1; 21 // Force alignment, 8 more bytes 22 double d = 5.0; 23 // 4 bytes 24 unsigned int e : 1; ~PackedPacked25 ~Packed() {} 26 }; 27 28 // 1 byte total 29 struct Empty { 30 unsigned int : 0; ~EmptyEmpty31 ~Empty() {} 32 }; 33 34 // 4 byte total 35 struct Simple { 36 unsigned int a : 1; ~SimpleSimple37 ~Simple() {} 38 }; 39 40 struct Anon { 41 unsigned int a : 1; 42 unsigned int b : 2; 43 unsigned int : 0; 44 unsigned int c : 1; ~AnonAnon45 ~Anon() {} 46 }; 47 main()48int main() { 49 Packed *p = new Packed(); 50 p->~Packed(); 51 for (int i = 0; i < 4; i++) 52 assert(__msan_test_shadow(((char*)p) + i, sizeof(char)) != -1); 53 assert(__msan_test_shadow(&p->d, sizeof(double)) != -1); 54 assert(__msan_test_shadow(((char*)(&p->d)) + sizeof(double), sizeof(char)) != 55 -1); 56 57 Empty *e = new Empty(); 58 e->~Empty(); 59 assert(__msan_test_shadow(e, sizeof(*e)) != -1); 60 61 Simple *s = new Simple(); 62 s->~Simple(); 63 assert(__msan_test_shadow(s, sizeof(*s)) != -1); 64 65 Anon *a = new Anon(); 66 a->~Anon(); 67 assert(__msan_test_shadow(a, sizeof(*a)) != -1); 68 69 return 0; 70 } 71