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