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 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 == 1); 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&>(a).id_ == 8); 83 throw a; 84 assert(false); 85 } 86 87 void f2() 88 { 89 try 90 { 91 assert(A::count == 0); 92 assert(C1::count == 0); 93 assert(C2::count == 0); 94 assert(B::count == 0); 95 f1(); 96 assert(false); 97 } 98 catch (const A& a) // can catch A 99 { 100 assert(a.id_ == 5); 101 assert(static_cast<const C1&>(a).id_ == 4); 102 assert(static_cast<const C2&>(a).id_ == 3); 103 assert(static_cast<const B&>(a).id_ == 8); 104 throw; 105 } 106 catch (const C1&) 107 { 108 assert(false); 109 } 110 catch (const C2&) 111 { 112 assert(false); 113 } 114 catch (const B&) 115 { 116 assert(false); 117 } 118 } 119 120 void f3() 121 { 122 try 123 { 124 assert(A::count == 0); 125 assert(C1::count == 0); 126 assert(C2::count == 0); 127 assert(B::count == 0); 128 f2(); 129 assert(false); 130 } 131 catch (const B& a) // can catch B 132 { 133 assert(static_cast<const B&>(a).id_ == 8); 134 throw; 135 } 136 catch (const C1& c1) 137 { 138 assert(false); 139 } 140 catch (const C2&) 141 { 142 assert(false); 143 } 144 } 145 146 void f4() 147 { 148 try 149 { 150 assert(A::count == 0); 151 assert(C1::count == 0); 152 assert(C2::count == 0); 153 assert(B::count == 0); 154 f3(); 155 assert(false); 156 } 157 catch (const C2& c2) // can catch C2 158 { 159 assert(c2.id_ == 3); 160 throw; 161 } 162 catch (const B& a) // can not catch B (ambiguous base) 163 { 164 assert(false); 165 } 166 catch (const C1&) 167 { 168 assert(false); 169 } 170 } 171 172 void f5() 173 { 174 try 175 { 176 assert(A::count == 0); 177 assert(C1::count == 0); 178 assert(C2::count == 0); 179 assert(B::count == 0); 180 f4(); 181 assert(false); 182 } 183 catch (const C1& c1) // can catch C1 184 { 185 assert(c1.id_ == 4); 186 assert(static_cast<const B&>(c1).id_ == 8); 187 throw; 188 } 189 catch (const B& a) 190 { 191 assert(false); 192 } 193 catch (const C2&) 194 { 195 assert(false); 196 } 197 } 198 199 int main() 200 { 201 try 202 { 203 f5(); 204 assert(false); 205 } 206 catch (...) 207 { 208 } 209 assert(A::count == 0); 210 assert(C1::count == 0); 211 assert(C2::count == 0); 212 assert(B::count == 0); 213 } 214