153 lines · cpp
1// RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&12 3// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&14 5// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && %run %t >%t.out 2>&16 7#include <sanitizer/msan_interface.h>8#include <assert.h>9 10template <class T> class Vector {11public:12 int size;13 ~Vector() {14 assert(__msan_test_shadow(&this->size, sizeof(this->size)) == -1);15 }16};17 18struct VirtualBase {19public:20 Vector<int> virtual_v;21 int virtual_a;22 // Pointer to subclass member23 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 poisoned36 assert(__msan_test_shadow(intermediate_a_ptr,37 sizeof(*intermediate_a_ptr)) != -1);38 }39};40 41struct Intermediate : virtual public VirtualBase {42public: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 unpoisoned50 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 57struct Base {58 int base_a;59 Vector<int> base_v;60 double base_b;61 // Pointers to subclass members62 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 poisoned84 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 92struct 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 116int 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 table121 // is inaccessible after destruction122 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 base134 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 intermediate146 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