1*c05d8e5dSAndroid Build Coastguard Worker //===---------------------- catch_class_04.cpp ----------------------------===//
2*c05d8e5dSAndroid Build Coastguard Worker //
3*c05d8e5dSAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*c05d8e5dSAndroid Build Coastguard Worker //
5*c05d8e5dSAndroid Build Coastguard Worker // This file is dual licensed under the MIT and the University of Illinois Open
6*c05d8e5dSAndroid Build Coastguard Worker // Source Licenses. See LICENSE.TXT for details.
7*c05d8e5dSAndroid Build Coastguard Worker //
8*c05d8e5dSAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*c05d8e5dSAndroid Build Coastguard Worker
10*c05d8e5dSAndroid Build Coastguard Worker /*
11*c05d8e5dSAndroid Build Coastguard Worker This test checks that adjustedPtr is correct as there exist offsets in this
12*c05d8e5dSAndroid Build Coastguard Worker object for the various subobjects, all of which have a unique id_ to
13*c05d8e5dSAndroid Build Coastguard Worker check against. It also checks that virtual bases work properly
14*c05d8e5dSAndroid Build Coastguard Worker */
15*c05d8e5dSAndroid Build Coastguard Worker
16*c05d8e5dSAndroid Build Coastguard Worker // UNSUPPORTED: libcxxabi-no-exceptions
17*c05d8e5dSAndroid Build Coastguard Worker
18*c05d8e5dSAndroid Build Coastguard Worker #include <exception>
19*c05d8e5dSAndroid Build Coastguard Worker #include <stdlib.h>
20*c05d8e5dSAndroid Build Coastguard Worker #include <assert.h>
21*c05d8e5dSAndroid Build Coastguard Worker
22*c05d8e5dSAndroid Build Coastguard Worker // Clang emits warnings about exceptions of type 'Child' being caught by
23*c05d8e5dSAndroid Build Coastguard Worker // an earlier handler of type 'Base'. Congrats clang, you've just
24*c05d8e5dSAndroid Build Coastguard Worker // diagnosed the behavior under test.
25*c05d8e5dSAndroid Build Coastguard Worker #if defined(__clang__)
26*c05d8e5dSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wexceptions"
27*c05d8e5dSAndroid Build Coastguard Worker #endif
28*c05d8e5dSAndroid Build Coastguard Worker
29*c05d8e5dSAndroid Build Coastguard Worker struct B
30*c05d8e5dSAndroid Build Coastguard Worker {
31*c05d8e5dSAndroid Build Coastguard Worker static int count;
32*c05d8e5dSAndroid Build Coastguard Worker int id_;
BB33*c05d8e5dSAndroid Build Coastguard Worker explicit B(int id) : id_(id) {count++;}
BB34*c05d8e5dSAndroid Build Coastguard Worker B(const B& a) : id_(a.id_) {count++;}
~BB35*c05d8e5dSAndroid Build Coastguard Worker ~B() {count--;}
36*c05d8e5dSAndroid Build Coastguard Worker };
37*c05d8e5dSAndroid Build Coastguard Worker
38*c05d8e5dSAndroid Build Coastguard Worker int B::count = 0;
39*c05d8e5dSAndroid Build Coastguard Worker
40*c05d8e5dSAndroid Build Coastguard Worker struct C1
41*c05d8e5dSAndroid Build Coastguard Worker : virtual B
42*c05d8e5dSAndroid Build Coastguard Worker {
43*c05d8e5dSAndroid Build Coastguard Worker static int count;
44*c05d8e5dSAndroid Build Coastguard Worker int id_;
C1C145*c05d8e5dSAndroid Build Coastguard Worker explicit C1(int id) : B(id-2), id_(id) {count++;}
C1C146*c05d8e5dSAndroid Build Coastguard Worker C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}
~C1C147*c05d8e5dSAndroid Build Coastguard Worker ~C1() {count--;}
48*c05d8e5dSAndroid Build Coastguard Worker };
49*c05d8e5dSAndroid Build Coastguard Worker
50*c05d8e5dSAndroid Build Coastguard Worker int C1::count = 0;
51*c05d8e5dSAndroid Build Coastguard Worker
52*c05d8e5dSAndroid Build Coastguard Worker struct C2
53*c05d8e5dSAndroid Build Coastguard Worker : virtual private B
54*c05d8e5dSAndroid Build Coastguard Worker {
55*c05d8e5dSAndroid Build Coastguard Worker static int count;
56*c05d8e5dSAndroid Build Coastguard Worker int id_;
C2C257*c05d8e5dSAndroid Build Coastguard Worker explicit C2(int id) : B(id-2), id_(id) {count++;}
C2C258*c05d8e5dSAndroid Build Coastguard Worker C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}
~C2C259*c05d8e5dSAndroid Build Coastguard Worker ~C2() {count--;}
60*c05d8e5dSAndroid Build Coastguard Worker };
61*c05d8e5dSAndroid Build Coastguard Worker
62*c05d8e5dSAndroid Build Coastguard Worker int C2::count = 0;
63*c05d8e5dSAndroid Build Coastguard Worker
64*c05d8e5dSAndroid Build Coastguard Worker struct A
65*c05d8e5dSAndroid Build Coastguard Worker : C1, C2
66*c05d8e5dSAndroid Build Coastguard Worker {
67*c05d8e5dSAndroid Build Coastguard Worker static int count;
68*c05d8e5dSAndroid Build Coastguard Worker int id_;
AA69*c05d8e5dSAndroid Build Coastguard Worker explicit A(int id) : B(id+3), C1(id-1), C2(id-2), id_(id) {count++;}
AA70*c05d8e5dSAndroid Build Coastguard Worker A(const A& a) : B(a.id_+3), C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;}
~AA71*c05d8e5dSAndroid Build Coastguard Worker ~A() {count--;}
72*c05d8e5dSAndroid Build Coastguard Worker };
73*c05d8e5dSAndroid Build Coastguard Worker
74*c05d8e5dSAndroid Build Coastguard Worker int A::count = 0;
75*c05d8e5dSAndroid Build Coastguard Worker
76*c05d8e5dSAndroid Build Coastguard Worker A a(5);
77*c05d8e5dSAndroid Build Coastguard Worker
f1()78*c05d8e5dSAndroid Build Coastguard Worker void f1()
79*c05d8e5dSAndroid Build Coastguard Worker {
80*c05d8e5dSAndroid Build Coastguard Worker throw &a;
81*c05d8e5dSAndroid Build Coastguard Worker assert(false);
82*c05d8e5dSAndroid Build Coastguard Worker }
83*c05d8e5dSAndroid Build Coastguard Worker
f2()84*c05d8e5dSAndroid Build Coastguard Worker void f2()
85*c05d8e5dSAndroid Build Coastguard Worker {
86*c05d8e5dSAndroid Build Coastguard Worker try
87*c05d8e5dSAndroid Build Coastguard Worker {
88*c05d8e5dSAndroid Build Coastguard Worker f1();
89*c05d8e5dSAndroid Build Coastguard Worker assert(false);
90*c05d8e5dSAndroid Build Coastguard Worker }
91*c05d8e5dSAndroid Build Coastguard Worker catch (const A* a) // can catch A
92*c05d8e5dSAndroid Build Coastguard Worker {
93*c05d8e5dSAndroid Build Coastguard Worker assert(a->id_ == 5);
94*c05d8e5dSAndroid Build Coastguard Worker assert(static_cast<const C1*>(a)->id_ == 4);
95*c05d8e5dSAndroid Build Coastguard Worker assert(static_cast<const C2*>(a)->id_ == 3);
96*c05d8e5dSAndroid Build Coastguard Worker assert(static_cast<const B*>(a)->id_ == 8);
97*c05d8e5dSAndroid Build Coastguard Worker throw;
98*c05d8e5dSAndroid Build Coastguard Worker }
99*c05d8e5dSAndroid Build Coastguard Worker catch (const C1*)
100*c05d8e5dSAndroid Build Coastguard Worker {
101*c05d8e5dSAndroid Build Coastguard Worker assert(false);
102*c05d8e5dSAndroid Build Coastguard Worker }
103*c05d8e5dSAndroid Build Coastguard Worker catch (const C2*)
104*c05d8e5dSAndroid Build Coastguard Worker {
105*c05d8e5dSAndroid Build Coastguard Worker assert(false);
106*c05d8e5dSAndroid Build Coastguard Worker }
107*c05d8e5dSAndroid Build Coastguard Worker catch (const B*)
108*c05d8e5dSAndroid Build Coastguard Worker {
109*c05d8e5dSAndroid Build Coastguard Worker assert(false);
110*c05d8e5dSAndroid Build Coastguard Worker }
111*c05d8e5dSAndroid Build Coastguard Worker }
112*c05d8e5dSAndroid Build Coastguard Worker
f3()113*c05d8e5dSAndroid Build Coastguard Worker void f3()
114*c05d8e5dSAndroid Build Coastguard Worker {
115*c05d8e5dSAndroid Build Coastguard Worker try
116*c05d8e5dSAndroid Build Coastguard Worker {
117*c05d8e5dSAndroid Build Coastguard Worker f2();
118*c05d8e5dSAndroid Build Coastguard Worker assert(false);
119*c05d8e5dSAndroid Build Coastguard Worker }
120*c05d8e5dSAndroid Build Coastguard Worker catch (const B* a) // can catch B
121*c05d8e5dSAndroid Build Coastguard Worker {
122*c05d8e5dSAndroid Build Coastguard Worker assert(static_cast<const B*>(a)->id_ == 8);
123*c05d8e5dSAndroid Build Coastguard Worker throw;
124*c05d8e5dSAndroid Build Coastguard Worker }
125*c05d8e5dSAndroid Build Coastguard Worker catch (const C1* c1)
126*c05d8e5dSAndroid Build Coastguard Worker {
127*c05d8e5dSAndroid Build Coastguard Worker assert(false);
128*c05d8e5dSAndroid Build Coastguard Worker }
129*c05d8e5dSAndroid Build Coastguard Worker catch (const C2*)
130*c05d8e5dSAndroid Build Coastguard Worker {
131*c05d8e5dSAndroid Build Coastguard Worker assert(false);
132*c05d8e5dSAndroid Build Coastguard Worker }
133*c05d8e5dSAndroid Build Coastguard Worker }
134*c05d8e5dSAndroid Build Coastguard Worker
f4()135*c05d8e5dSAndroid Build Coastguard Worker void f4()
136*c05d8e5dSAndroid Build Coastguard Worker {
137*c05d8e5dSAndroid Build Coastguard Worker try
138*c05d8e5dSAndroid Build Coastguard Worker {
139*c05d8e5dSAndroid Build Coastguard Worker f3();
140*c05d8e5dSAndroid Build Coastguard Worker assert(false);
141*c05d8e5dSAndroid Build Coastguard Worker }
142*c05d8e5dSAndroid Build Coastguard Worker catch (const C2* c2) // can catch C2
143*c05d8e5dSAndroid Build Coastguard Worker {
144*c05d8e5dSAndroid Build Coastguard Worker assert(c2->id_ == 3);
145*c05d8e5dSAndroid Build Coastguard Worker throw;
146*c05d8e5dSAndroid Build Coastguard Worker }
147*c05d8e5dSAndroid Build Coastguard Worker catch (const B* a)
148*c05d8e5dSAndroid Build Coastguard Worker {
149*c05d8e5dSAndroid Build Coastguard Worker assert(false);
150*c05d8e5dSAndroid Build Coastguard Worker }
151*c05d8e5dSAndroid Build Coastguard Worker catch (const C1*)
152*c05d8e5dSAndroid Build Coastguard Worker {
153*c05d8e5dSAndroid Build Coastguard Worker assert(false);
154*c05d8e5dSAndroid Build Coastguard Worker }
155*c05d8e5dSAndroid Build Coastguard Worker }
156*c05d8e5dSAndroid Build Coastguard Worker
f5()157*c05d8e5dSAndroid Build Coastguard Worker void f5()
158*c05d8e5dSAndroid Build Coastguard Worker {
159*c05d8e5dSAndroid Build Coastguard Worker try
160*c05d8e5dSAndroid Build Coastguard Worker {
161*c05d8e5dSAndroid Build Coastguard Worker f4();
162*c05d8e5dSAndroid Build Coastguard Worker assert(false);
163*c05d8e5dSAndroid Build Coastguard Worker }
164*c05d8e5dSAndroid Build Coastguard Worker catch (const C1* c1) // can catch C1
165*c05d8e5dSAndroid Build Coastguard Worker {
166*c05d8e5dSAndroid Build Coastguard Worker assert(c1->id_ == 4);
167*c05d8e5dSAndroid Build Coastguard Worker assert(static_cast<const B*>(c1)->id_ == 8);
168*c05d8e5dSAndroid Build Coastguard Worker throw;
169*c05d8e5dSAndroid Build Coastguard Worker }
170*c05d8e5dSAndroid Build Coastguard Worker catch (const B* a)
171*c05d8e5dSAndroid Build Coastguard Worker {
172*c05d8e5dSAndroid Build Coastguard Worker assert(false);
173*c05d8e5dSAndroid Build Coastguard Worker }
174*c05d8e5dSAndroid Build Coastguard Worker catch (const C2*)
175*c05d8e5dSAndroid Build Coastguard Worker {
176*c05d8e5dSAndroid Build Coastguard Worker assert(false);
177*c05d8e5dSAndroid Build Coastguard Worker }
178*c05d8e5dSAndroid Build Coastguard Worker }
179*c05d8e5dSAndroid Build Coastguard Worker
main()180*c05d8e5dSAndroid Build Coastguard Worker int main()
181*c05d8e5dSAndroid Build Coastguard Worker {
182*c05d8e5dSAndroid Build Coastguard Worker try
183*c05d8e5dSAndroid Build Coastguard Worker {
184*c05d8e5dSAndroid Build Coastguard Worker f5();
185*c05d8e5dSAndroid Build Coastguard Worker assert(false);
186*c05d8e5dSAndroid Build Coastguard Worker }
187*c05d8e5dSAndroid Build Coastguard Worker catch (...)
188*c05d8e5dSAndroid Build Coastguard Worker {
189*c05d8e5dSAndroid Build Coastguard Worker }
190*c05d8e5dSAndroid Build Coastguard Worker }
191