• 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 >%t.out 2>&1
2 
3 // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
4 
5 // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
6 
7 #include <sanitizer/msan_interface.h>
8 #include <assert.h>
9 
10 template <class T> class Vector {
11 public:
12   int size;
~Vector()13   ~Vector() {
14     assert(__msan_test_shadow(&this->size, sizeof(this->size)) == -1);
15   }
16 };
17 
18 struct VirtualBase {
19 public:
20   Vector<int> virtual_v;
21   int virtual_a;
22   // Pointer to subclass member
23   int *intermediate_a_ptr;
24 
VirtualBaseVirtualBase25   VirtualBase() {
26     virtual_v.size = 1;
27     virtual_a = 9;
28   }
set_ptrVirtualBase29   void set_ptr(int *intermediate_a) {
30     this->intermediate_a_ptr = intermediate_a;
31   }
~VirtualBaseVirtualBase32   virtual ~VirtualBase() {
33     assert(__msan_test_shadow(&virtual_v, sizeof(virtual_v)) == -1);
34     assert(__msan_test_shadow(&virtual_a, sizeof(virtual_a)) == -1);
35     // Derived class member is poisoned
36     assert(__msan_test_shadow(intermediate_a_ptr,
37                               sizeof(*intermediate_a_ptr)) != -1);
38   }
39 };
40 
41 struct Intermediate : virtual public VirtualBase {
42 public:
43   int intermediate_a;
44 
IntermediateIntermediate45   Intermediate() { intermediate_a = 5; }
~IntermediateIntermediate46   virtual ~Intermediate() {
47     assert(__msan_test_shadow(&this->intermediate_a,
48                               sizeof(this->intermediate_a)) == -1);
49     // Members inherited from VirtualBase unpoisoned
50     assert(__msan_test_shadow(&virtual_v, sizeof(virtual_v)) == -1);
51     assert(__msan_test_shadow(&virtual_a, sizeof(virtual_a)) == -1);
52     assert(__msan_test_shadow(intermediate_a_ptr,
53                               sizeof(*intermediate_a_ptr)) == -1);
54   }
55 };
56 
57 struct Base {
58   int base_a;
59   Vector<int> base_v;
60   double base_b;
61   // Pointers to subclass members
62   int *derived_a_ptr;
63   Vector<int> *derived_v1_ptr;
64   Vector<int> *derived_v2_ptr;
65   double *derived_b_ptr;
66   double *derived_c_ptr;
67 
BaseBase68   Base(int *derived_a, Vector<int> *derived_v1, Vector<int> *derived_v2,
69        double *derived_b, double *derived_c) {
70     base_a = 2;
71     base_v.size = 1;
72     base_b = 13.2324;
73     derived_a_ptr = derived_a;
74     derived_v1_ptr = derived_v1;
75     derived_v2_ptr = derived_v2;
76     derived_b_ptr = derived_b;
77     derived_c_ptr = derived_c;
78   }
~BaseBase79   virtual ~Base() {
80     assert(__msan_test_shadow(&base_a, sizeof(base_a)) == -1);
81     assert(__msan_test_shadow(&base_v, sizeof(base_v)) == -1);
82     assert(__msan_test_shadow(&base_b, sizeof(base_b)) == -1);
83     // Derived class members are poisoned
84     assert(__msan_test_shadow(derived_a_ptr, sizeof(*derived_a_ptr)) != -1);
85     assert(__msan_test_shadow(derived_v1_ptr, sizeof(*derived_v1_ptr)) != -1);
86     assert(__msan_test_shadow(derived_v2_ptr, sizeof(*derived_v2_ptr)) != -1);
87     assert(__msan_test_shadow(derived_b_ptr, sizeof(*derived_b_ptr)) != -1);
88     assert(__msan_test_shadow(derived_c_ptr, sizeof(*derived_c_ptr)) != -1);
89   }
90 };
91 
92 struct Derived : public Base, public Intermediate {
93   int derived_a;
94   Vector<int> derived_v1;
95   Vector<int> derived_v2;
96   double derived_b;
97   double derived_c;
98 
DerivedDerived99   Derived()
100       : Base(&derived_a, &derived_v1, &derived_v2, &derived_b, &derived_c) {
101     derived_a = 5;
102     derived_v1.size = 1;
103     derived_v2.size = 1;
104     derived_b = 7;
105     derived_c = 10;
106   }
~DerivedDerived107   ~Derived() {
108     assert(__msan_test_shadow(&derived_a, sizeof(derived_a)) == -1);
109     assert(__msan_test_shadow(&derived_v1, sizeof(derived_v1)) == -1);
110     assert(__msan_test_shadow(&derived_v2, sizeof(derived_v2)) == -1);
111     assert(__msan_test_shadow(&derived_b, sizeof(derived_b)) == -1);
112     assert(__msan_test_shadow(&derived_c, sizeof(derived_c)) == -1);
113   }
114 };
115 
main()116 int main() {
117   Derived *d = new Derived();
118   d->set_ptr(&d->intermediate_a);
119 
120   // Keep track of members of VirtualBase, since the virtual base table
121   // is inaccessible after destruction
122   Vector<int> *temp_virtual_v = &d->virtual_v;
123   int *temp_virtual_a = &d->virtual_a;
124   int **temp_intermediate_a_ptr = &d->intermediate_a_ptr;
125 
126   d->~Derived();
127   assert(__msan_test_shadow(&d->derived_a, sizeof(d->derived_a)) != -1);
128   assert(__msan_test_shadow(&d->derived_v1, sizeof(d->derived_v1)) != -1);
129   assert(__msan_test_shadow(&d->derived_v2, sizeof(d->derived_v2)) != -1);
130   assert(__msan_test_shadow(&d->derived_b, sizeof(d->derived_b)) != -1);
131   assert(__msan_test_shadow(&d->derived_c, sizeof(d->derived_c)) != -1);
132 
133   // Inherited from base
134   assert(__msan_test_shadow(&d->base_a, sizeof(d->base_a)) != -1);
135   assert(__msan_test_shadow(&d->base_v, sizeof(d->base_v)) != -1);
136   assert(__msan_test_shadow(&d->base_b, sizeof(d->base_b)) != -1);
137   assert(__msan_test_shadow(&d->derived_a_ptr, sizeof(d->derived_a_ptr)) != -1);
138   assert(__msan_test_shadow(&d->derived_v1_ptr, sizeof(d->derived_v1_ptr)) !=
139          -1);
140   assert(__msan_test_shadow(&d->derived_v2_ptr, sizeof(d->derived_v2_ptr)) !=
141          -1);
142   assert(__msan_test_shadow(&d->derived_b_ptr, sizeof(d->derived_b_ptr)) != -1);
143   assert(__msan_test_shadow(&d->derived_c_ptr, sizeof(d->derived_c_ptr)) != -1);
144 
145   // Inherited from intermediate
146   assert(__msan_test_shadow(temp_virtual_v, sizeof(*temp_virtual_v)) != -1);
147   assert(__msan_test_shadow(temp_virtual_a, sizeof(*temp_virtual_a)) != -1);
148   assert(__msan_test_shadow(temp_intermediate_a_ptr,
149                             sizeof(*temp_intermediate_a_ptr)) != -1);
150 
151   return 0;
152 }
153