1 //===---------------------- catch_class_03.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. 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 : 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 : 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), id_(id) {count++;} 61 A(const A& a) : C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;} 62 ~A() {count--;} 63 }; 64 65 int A::count = 0; 66 67 void f1() 68 { 69 assert(A::count == 0); 70 assert(C1::count == 0); 71 assert(C2::count == 0); 72 assert(B::count == 0); 73 A a(5); 74 assert(A::count == 1); 75 assert(C1::count == 1); 76 assert(C2::count == 1); 77 assert(B::count == 2); 78 79 assert(a.id_ == 5); 80 assert(static_cast<C1&>(a).id_ == 4); 81 assert(static_cast<C2&>(a).id_ == 3); 82 assert(static_cast<B&>(static_cast<C1&>(a)).id_ == 2); 83 assert(static_cast<B&>(static_cast<C2&>(a)).id_ == 1); 84 throw a; 85 assert(false); 86 } 87 88 void f2() 89 { 90 try 91 { 92 assert(A::count == 0); 93 assert(C1::count == 0); 94 assert(C2::count == 0); 95 assert(B::count == 0); 96 f1(); 97 assert(false); 98 } 99 catch (const A& a) // can catch A 100 { 101 assert(a.id_ == 5); 102 assert(static_cast<const C1&>(a).id_ == 4); 103 assert(static_cast<const C2&>(a).id_ == 3); 104 assert(static_cast<const B&>(static_cast<const C1&>(a)).id_ == 2); 105 assert(static_cast<const B&>(static_cast<const C2&>(a)).id_ == 1); 106 throw; 107 } 108 catch (const C1&) 109 { 110 assert(false); 111 } 112 catch (const C2&) 113 { 114 assert(false); 115 } 116 catch (const B&) 117 { 118 assert(false); 119 } 120 } 121 122 void f3() 123 { 124 try 125 { 126 assert(A::count == 0); 127 assert(C1::count == 0); 128 assert(C2::count == 0); 129 assert(B::count == 0); 130 f2(); 131 assert(false); 132 } 133 catch (const B& a) // can not catch B (ambiguous base) 134 { 135 assert(false); 136 } 137 catch (const C1& c1) // can catch C1 138 { 139 assert(c1.id_ == 4); 140 assert(static_cast<const B&>(c1).id_ == 2); 141 throw; 142 } 143 catch (const C2&) 144 { 145 assert(false); 146 } 147 } 148 149 void f4() 150 { 151 try 152 { 153 assert(A::count == 0); 154 assert(C1::count == 0); 155 assert(C2::count == 0); 156 assert(B::count == 0); 157 f3(); 158 assert(false); 159 } 160 catch (const B& a) // can not catch B (ambiguous base) 161 { 162 assert(false); 163 } 164 catch (const C2& c2) // can catch C2 165 { 166 assert(c2.id_ == 3); 167 assert(static_cast<const B&>(c2).id_ == 1); 168 throw; 169 } 170 catch (const C1&) 171 { 172 assert(false); 173 } 174 } 175 176 int main() 177 { 178 try 179 { 180 f4(); 181 assert(false); 182 } 183 catch (...) 184 { 185 } 186 assert(A::count == 0); 187 assert(C1::count == 0); 188 assert(C2::count == 0); 189 assert(B::count == 0); 190 } 191