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 29struct 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 38int B::count = 0; 39 40struct 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 50int C1::count = 0; 51 52struct 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 62int C2::count = 0; 63 64struct 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 74int A::count = 0; 75 76void 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 97void 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 131void 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 158void 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 185int 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