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 20struct 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 29int B::count = 0; 30 31struct 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 41int C1::count = 0; 42 43struct 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 53int C2::count = 0; 54 55struct 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 65int A::count = 0; 66 67void 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 87void 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 120void 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 146void 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 172void 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 199int 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