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 // UNSUPPORTED: libcxxabi-no-exceptions 17 18 #include <exception> 19 #include <stdlib.h> 20 #include <assert.h> 21 22 // Clang emits warnings about exceptions of type 'Child' being caught by 23 // an earlier handler of type 'Base'. Congrats clang, you've just 24 // diagnosed the behavior under test. 25 #if defined(__clang__) 26 #pragma clang diagnostic ignored "-Wexceptions" 27 #endif 28 29 struct B 30 { 31 static int count; 32 int id_; 33 explicit B(int id) : id_(id) {count++;} 34 B(const B& a) : id_(a.id_) {count++;} 35 ~B() {count--;} 36 }; 37 38 int B::count = 0; 39 40 struct C1 41 : B 42 { 43 static int count; 44 int id_; 45 explicit C1(int id) : B(id-2), id_(id) {count++;} 46 C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;} 47 ~C1() {count--;} 48 }; 49 50 int C1::count = 0; 51 52 struct C2 53 : B 54 { 55 static int count; 56 int id_; 57 explicit C2(int id) : B(id-2), id_(id) {count++;} 58 C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;} 59 ~C2() {count--;} 60 }; 61 62 int C2::count = 0; 63 64 struct A 65 : C1, C2 66 { 67 static int count; 68 int id_; 69 explicit A(int id) : C1(id-1), C2(id-2), id_(id) {count++;} 70 A(const A& a) : C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;} 71 ~A() {count--;} 72 }; 73 74 int A::count = 0; 75 76 void f1() 77 { 78 assert(A::count == 0); 79 assert(C1::count == 0); 80 assert(C2::count == 0); 81 assert(B::count == 0); 82 A a(5); 83 assert(A::count == 1); 84 assert(C1::count == 1); 85 assert(C2::count == 1); 86 assert(B::count == 2); 87 88 assert(a.id_ == 5); 89 assert(static_cast<C1&>(a).id_ == 4); 90 assert(static_cast<C2&>(a).id_ == 3); 91 assert(static_cast<B&>(static_cast<C1&>(a)).id_ == 2); 92 assert(static_cast<B&>(static_cast<C2&>(a)).id_ == 1); 93 throw a; 94 assert(false); 95 } 96 97 void f2() 98 { 99 try 100 { 101 assert(A::count == 0); 102 assert(C1::count == 0); 103 assert(C2::count == 0); 104 assert(B::count == 0); 105 f1(); 106 assert(false); 107 } 108 catch (const A& a) // can catch A 109 { 110 assert(a.id_ == 5); 111 assert(static_cast<const C1&>(a).id_ == 4); 112 assert(static_cast<const C2&>(a).id_ == 3); 113 assert(static_cast<const B&>(static_cast<const C1&>(a)).id_ == 2); 114 assert(static_cast<const B&>(static_cast<const C2&>(a)).id_ == 1); 115 throw; 116 } 117 catch (const C1&) 118 { 119 assert(false); 120 } 121 catch (const C2&) 122 { 123 assert(false); 124 } 125 catch (const B&) 126 { 127 assert(false); 128 } 129 } 130 131 void f3() 132 { 133 try 134 { 135 assert(A::count == 0); 136 assert(C1::count == 0); 137 assert(C2::count == 0); 138 assert(B::count == 0); 139 f2(); 140 assert(false); 141 } 142 catch (const B& a) // can not catch B (ambiguous base) 143 { 144 assert(false); 145 } 146 catch (const C1& c1) // can catch C1 147 { 148 assert(c1.id_ == 4); 149 assert(static_cast<const B&>(c1).id_ == 2); 150 throw; 151 } 152 catch (const C2&) 153 { 154 assert(false); 155 } 156 } 157 158 void f4() 159 { 160 try 161 { 162 assert(A::count == 0); 163 assert(C1::count == 0); 164 assert(C2::count == 0); 165 assert(B::count == 0); 166 f3(); 167 assert(false); 168 } 169 catch (const B& a) // can not catch B (ambiguous base) 170 { 171 assert(false); 172 } 173 catch (const C2& c2) // can catch C2 174 { 175 assert(c2.id_ == 3); 176 assert(static_cast<const B&>(c2).id_ == 1); 177 throw; 178 } 179 catch (const C1&) 180 { 181 assert(false); 182 } 183 } 184 185 int main() 186 { 187 try 188 { 189 f4(); 190 assert(false); 191 } 192 catch (...) 193 { 194 } 195 assert(A::count == 0); 196 assert(C1::count == 0); 197 assert(C2::count == 0); 198 assert(B::count == 0); 199 } 200