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 #include <exception> 17 #include <stdlib.h> 18 #include <assert.h> 19 20 struct B 21 { 22 static int count; 23 int id_; 24 explicit B(int id) : id_(id) {count++;} 25 B(const B& a) : id_(a.id_) {count++;} 26 ~B() {count--;} 27 }; 28 29 int B::count = 0; 30 31 struct C1 32 : virtual B 33 { 34 static int count; 35 int id_; 36 explicit C1(int id) : B(id-2), id_(id) {count++;} 37 C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;} 38 ~C1() {count--;} 39 }; 40 41 int C1::count = 0; 42 43 struct C2 44 : virtual private B 45 { 46 static int count; 47 int id_; 48 explicit C2(int id) : B(id-2), id_(id) {count++;} 49 C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;} 50 ~C2() {count--;} 51 }; 52 53 int C2::count = 0; 54 55 struct A 56 : C1, C2 57 { 58 static int count; 59 int id_; 60 explicit A(int id) : C1(id-1), C2(id-2), B(id+3), id_(id) {count++;} 61 A(const A& a) : C1(a.id_-1), C2(a.id_-2), B(a.id_+3), id_(a.id_) {count++;} 62 ~A() {count--;} 63 }; 64 65 int A::count = 0; 66 67 A a(5); 68 69 void f1() 70 { 71 throw &a; 72 assert(false); 73 } 74 75 void f2() 76 { 77 try 78 { 79 f1(); 80 assert(false); 81 } 82 catch (const A* a) // can catch A 83 { 84 assert(a->id_ == 5); 85 assert(static_cast<const C1*>(a)->id_ == 4); 86 assert(static_cast<const C2*>(a)->id_ == 3); 87 assert(static_cast<const B*>(a)->id_ == 8); 88 throw; 89 } 90 catch (const C1*) 91 { 92 assert(false); 93 } 94 catch (const C2*) 95 { 96 assert(false); 97 } 98 catch (const B*) 99 { 100 assert(false); 101 } 102 } 103 104 void f3() 105 { 106 try 107 { 108 f2(); 109 assert(false); 110 } 111 catch (const B* a) // can catch B 112 { 113 assert(static_cast<const B*>(a)->id_ == 8); 114 throw; 115 } 116 catch (const C1* c1) 117 { 118 assert(false); 119 } 120 catch (const C2*) 121 { 122 assert(false); 123 } 124 } 125 126 void f4() 127 { 128 try 129 { 130 f3(); 131 assert(false); 132 } 133 catch (const C2* c2) // can catch C2 134 { 135 assert(c2->id_ == 3); 136 throw; 137 } 138 catch (const B* a) 139 { 140 assert(false); 141 } 142 catch (const C1*) 143 { 144 assert(false); 145 } 146 } 147 148 void f5() 149 { 150 try 151 { 152 f4(); 153 assert(false); 154 } 155 catch (const C1* c1) // can catch C1 156 { 157 assert(c1->id_ == 4); 158 assert(static_cast<const B*>(c1)->id_ == 8); 159 throw; 160 } 161 catch (const B* a) 162 { 163 assert(false); 164 } 165 catch (const C2*) 166 { 167 assert(false); 168 } 169 } 170 171 int main() 172 { 173 try 174 { 175 f5(); 176 assert(false); 177 } 178 catch (...) 179 { 180 } 181 } 182