• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()48 int 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