1 //===---------------------- catch_class_04.cpp ----------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 /* 11 This test checks that adjustedPtr is correct as there exist offsets in this 12 object for the various subobjects, all of which have a unique id_ to 13 check against. It also checks that virtual bases work properly 14 */ 15 16 // UNSUPPORTED: libcxxabi-no-exceptions 17 18 #include <exception> 19 #include <stdlib.h> 20 #include <assert.h> 21 22 struct B 23 { 24 static int count; 25 int id_; 26 explicit B(int id) : id_(id) {count++;} 27 B(const B& a) : id_(a.id_) {count++;} 28 ~B() {count--;} 29 }; 30 31 int B::count = 0; 32 33 struct C1 34 : virtual B 35 { 36 static int count; 37 int id_; 38 explicit C1(int id) : B(id-2), id_(id) {count++;} 39 C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;} 40 ~C1() {count--;} 41 }; 42 43 int C1::count = 0; 44 45 struct C2 46 : virtual private B 47 { 48 static int count; 49 int id_; 50 explicit C2(int id) : B(id-2), id_(id) {count++;} 51 C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;} 52 ~C2() {count--;} 53 }; 54 55 int C2::count = 0; 56 57 struct A 58 : C1, C2 59 { 60 static int count; 61 int id_; 62 explicit A(int id) : C1(id-1), C2(id-2), B(id+3), id_(id) {count++;} 63 A(const A& a) : C1(a.id_-1), C2(a.id_-2), B(a.id_+3), id_(a.id_) {count++;} 64 ~A() {count--;} 65 }; 66 67 int A::count = 0; 68 69 A a(5); 70 71 void f1() 72 { 73 throw &a; 74 assert(false); 75 } 76 77 void f2() 78 { 79 try 80 { 81 f1(); 82 assert(false); 83 } 84 catch (const A* a) // can catch A 85 { 86 assert(a->id_ == 5); 87 assert(static_cast<const C1*>(a)->id_ == 4); 88 assert(static_cast<const C2*>(a)->id_ == 3); 89 assert(static_cast<const B*>(a)->id_ == 8); 90 throw; 91 } 92 catch (const C1*) 93 { 94 assert(false); 95 } 96 catch (const C2*) 97 { 98 assert(false); 99 } 100 catch (const B*) 101 { 102 assert(false); 103 } 104 } 105 106 void f3() 107 { 108 try 109 { 110 f2(); 111 assert(false); 112 } 113 catch (const B* a) // can catch B 114 { 115 assert(static_cast<const B*>(a)->id_ == 8); 116 throw; 117 } 118 catch (const C1* c1) 119 { 120 assert(false); 121 } 122 catch (const C2*) 123 { 124 assert(false); 125 } 126 } 127 128 void f4() 129 { 130 try 131 { 132 f3(); 133 assert(false); 134 } 135 catch (const C2* c2) // can catch C2 136 { 137 assert(c2->id_ == 3); 138 throw; 139 } 140 catch (const B* a) 141 { 142 assert(false); 143 } 144 catch (const C1*) 145 { 146 assert(false); 147 } 148 } 149 150 void f5() 151 { 152 try 153 { 154 f4(); 155 assert(false); 156 } 157 catch (const C1* c1) // can catch C1 158 { 159 assert(c1->id_ == 4); 160 assert(static_cast<const B*>(c1)->id_ == 8); 161 throw; 162 } 163 catch (const B* a) 164 { 165 assert(false); 166 } 167 catch (const C2*) 168 { 169 assert(false); 170 } 171 } 172 173 int main() 174 { 175 try 176 { 177 f5(); 178 assert(false); 179 } 180 catch (...) 181 { 182 } 183 } 184