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