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