Home | History | Annotate | Download | only in msan
      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;
     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 
     25   VirtualBase() {
     26     virtual_v.size = 1;
     27     virtual_a = 9;
     28   }
     29   void set_ptr(int *intermediate_a) {
     30     this->intermediate_a_ptr = intermediate_a;
     31   }
     32   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 
     45   Intermediate() { intermediate_a = 5; }
     46   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 
     68   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   }
     79   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 
     99   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   }
    107   ~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 
    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