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