xref: /aosp_15_r20/external/libcxxabi/test/catch_pointer_reference.pass.cpp (revision c05d8e5dc3e10f6ce4317e8bc22cc4a25f55fa94)
1*c05d8e5dSAndroid Build Coastguard Worker //===---------------------- catch_pointer_referece.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 //  This test case checks specifically the cases under bullet 3.1 & 3.2:
11*c05d8e5dSAndroid Build Coastguard Worker //
12*c05d8e5dSAndroid Build Coastguard Worker //  C++ ABI 15.3:
13*c05d8e5dSAndroid Build Coastguard Worker //  A handler is a match for an exception object of type E if
14*c05d8e5dSAndroid Build Coastguard Worker //     *  The handler is of type cv T or cv T& and E and T are the same type
15*c05d8e5dSAndroid Build Coastguard Worker //        (ignoring the top-level cv-qualifiers), or
16*c05d8e5dSAndroid Build Coastguard Worker //     *  the handler is of type cv T or cv T& and T is an unambiguous base
17*c05d8e5dSAndroid Build Coastguard Worker //        class of E, or
18*c05d8e5dSAndroid Build Coastguard Worker //  /  *  the handler is of type cv1 T* cv2 and E is a pointer type that can   \
19*c05d8e5dSAndroid Build Coastguard Worker //  |     be converted to the type of the handler by either or both of         |
20*c05d8e5dSAndroid Build Coastguard Worker //  |       o  a standard pointer conversion (4.10 [conv.ptr]) not involving   |
21*c05d8e5dSAndroid Build Coastguard Worker //  |          conversions to private or protected or ambiguous classes        |
22*c05d8e5dSAndroid Build Coastguard Worker //  \       o  a qualification conversion                                      /
23*c05d8e5dSAndroid Build Coastguard Worker //     *  the handler is a pointer or pointer to member type and E is
24*c05d8e5dSAndroid Build Coastguard Worker //        std::nullptr_t
25*c05d8e5dSAndroid Build Coastguard Worker //
26*c05d8e5dSAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
27*c05d8e5dSAndroid Build Coastguard Worker 
28*c05d8e5dSAndroid Build Coastguard Worker // UNSUPPORTED: libcxxabi-no-exceptions
29*c05d8e5dSAndroid Build Coastguard Worker 
30*c05d8e5dSAndroid Build Coastguard Worker #include <exception>
31*c05d8e5dSAndroid Build Coastguard Worker #include <stdlib.h>
32*c05d8e5dSAndroid Build Coastguard Worker #include <assert.h>
33*c05d8e5dSAndroid Build Coastguard Worker #include <stdio.h>
34*c05d8e5dSAndroid Build Coastguard Worker 
35*c05d8e5dSAndroid Build Coastguard Worker struct Base {};
36*c05d8e5dSAndroid Build Coastguard Worker struct Derived  : Base {};
37*c05d8e5dSAndroid Build Coastguard Worker struct Derived2 : Base {};
38*c05d8e5dSAndroid Build Coastguard Worker struct Ambiguous : Derived, Derived2 {};
39*c05d8e5dSAndroid Build Coastguard Worker struct Private : private Base {};
40*c05d8e5dSAndroid Build Coastguard Worker struct Protected : protected Base {};
41*c05d8e5dSAndroid Build Coastguard Worker 
42*c05d8e5dSAndroid Build Coastguard Worker template <typename T  // Handler type
43*c05d8e5dSAndroid Build Coastguard Worker          ,typename E  // Thrown exception type
44*c05d8e5dSAndroid Build Coastguard Worker          ,typename O  // Object type
45*c05d8e5dSAndroid Build Coastguard Worker          >
assert_catches()46*c05d8e5dSAndroid Build Coastguard Worker void assert_catches()
47*c05d8e5dSAndroid Build Coastguard Worker {
48*c05d8e5dSAndroid Build Coastguard Worker     try
49*c05d8e5dSAndroid Build Coastguard Worker     {
50*c05d8e5dSAndroid Build Coastguard Worker         O o;
51*c05d8e5dSAndroid Build Coastguard Worker         throw static_cast<E>(&o);
52*c05d8e5dSAndroid Build Coastguard Worker         printf("%s\n", __PRETTY_FUNCTION__);
53*c05d8e5dSAndroid Build Coastguard Worker         assert(false && "Statements after throw must be unreachable");
54*c05d8e5dSAndroid Build Coastguard Worker     }
55*c05d8e5dSAndroid Build Coastguard Worker     catch (T t)
56*c05d8e5dSAndroid Build Coastguard Worker     {
57*c05d8e5dSAndroid Build Coastguard Worker         assert(true);
58*c05d8e5dSAndroid Build Coastguard Worker         return;
59*c05d8e5dSAndroid Build Coastguard Worker     }
60*c05d8e5dSAndroid Build Coastguard Worker     catch (...)
61*c05d8e5dSAndroid Build Coastguard Worker     {
62*c05d8e5dSAndroid Build Coastguard Worker         printf("%s\n", __PRETTY_FUNCTION__);
63*c05d8e5dSAndroid Build Coastguard Worker         assert(false && "Should not have entered catch-all");
64*c05d8e5dSAndroid Build Coastguard Worker     }
65*c05d8e5dSAndroid Build Coastguard Worker 
66*c05d8e5dSAndroid Build Coastguard Worker     printf("%s\n", __PRETTY_FUNCTION__);
67*c05d8e5dSAndroid Build Coastguard Worker     assert(false && "The catch should have returned");
68*c05d8e5dSAndroid Build Coastguard Worker }
69*c05d8e5dSAndroid Build Coastguard Worker 
70*c05d8e5dSAndroid Build Coastguard Worker template <typename T  // Handler type
71*c05d8e5dSAndroid Build Coastguard Worker          ,typename E  // Thrown exception type
72*c05d8e5dSAndroid Build Coastguard Worker          ,typename O  // Object type
73*c05d8e5dSAndroid Build Coastguard Worker          >
assert_cannot_catch()74*c05d8e5dSAndroid Build Coastguard Worker void assert_cannot_catch()
75*c05d8e5dSAndroid Build Coastguard Worker {
76*c05d8e5dSAndroid Build Coastguard Worker     try
77*c05d8e5dSAndroid Build Coastguard Worker     {
78*c05d8e5dSAndroid Build Coastguard Worker         O o;
79*c05d8e5dSAndroid Build Coastguard Worker         throw static_cast<E>(&o);
80*c05d8e5dSAndroid Build Coastguard Worker         printf("%s\n", __PRETTY_FUNCTION__);
81*c05d8e5dSAndroid Build Coastguard Worker         assert(false && "Statements after throw must be unreachable");
82*c05d8e5dSAndroid Build Coastguard Worker     }
83*c05d8e5dSAndroid Build Coastguard Worker     catch (T t)
84*c05d8e5dSAndroid Build Coastguard Worker     {
85*c05d8e5dSAndroid Build Coastguard Worker         printf("%s\n", __PRETTY_FUNCTION__);
86*c05d8e5dSAndroid Build Coastguard Worker         assert(false && "Should not have entered the catch");
87*c05d8e5dSAndroid Build Coastguard Worker     }
88*c05d8e5dSAndroid Build Coastguard Worker     catch (...)
89*c05d8e5dSAndroid Build Coastguard Worker     {
90*c05d8e5dSAndroid Build Coastguard Worker         assert(true);
91*c05d8e5dSAndroid Build Coastguard Worker         return;
92*c05d8e5dSAndroid Build Coastguard Worker     }
93*c05d8e5dSAndroid Build Coastguard Worker 
94*c05d8e5dSAndroid Build Coastguard Worker     printf("%s\n", __PRETTY_FUNCTION__);
95*c05d8e5dSAndroid Build Coastguard Worker     assert(false && "The catch-all should have returned");
96*c05d8e5dSAndroid Build Coastguard Worker }
97*c05d8e5dSAndroid Build Coastguard Worker 
f1()98*c05d8e5dSAndroid Build Coastguard Worker void f1()
99*c05d8e5dSAndroid Build Coastguard Worker {
100*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
101*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Base * cv2
102*c05d8e5dSAndroid Build Coastguard Worker     // catches an exception of type:
103*c05d8e5dSAndroid Build Coastguard Worker     //   Derived *
104*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base *               , Derived *, Derived>();
105*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base *               , Derived *, Derived>();
106*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base *               , Derived *, Derived>();
107*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base *               , Derived *, Derived>();
108*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base * const         , Derived *, Derived>();
109*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base * const         , Derived *, Derived>();
110*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base * const         , Derived *, Derived>();
111*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base * const         , Derived *, Derived>();
112*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base *       volatile, Derived *, Derived>();
113*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base *       volatile, Derived *, Derived>();
114*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base *       volatile, Derived *, Derived>();
115*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base *       volatile, Derived *, Derived>();
116*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base * const volatile, Derived *, Derived>();
117*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base * const volatile, Derived *, Derived>();
118*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base * const volatile, Derived *, Derived>();
119*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base * const volatile, Derived *, Derived>();
120*c05d8e5dSAndroid Build Coastguard Worker }
121*c05d8e5dSAndroid Build Coastguard Worker 
f2()122*c05d8e5dSAndroid Build Coastguard Worker void f2()
123*c05d8e5dSAndroid Build Coastguard Worker {
124*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
125*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Base * cv2
126*c05d8e5dSAndroid Build Coastguard Worker     // catches an exception of type:
127*c05d8e5dSAndroid Build Coastguard Worker     //   Base *
128*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base *               , Base *, Derived>();
129*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base *               , Base *, Derived>();
130*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base *               , Base *, Derived>();
131*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base *               , Base *, Derived>();
132*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base * const         , Base *, Derived>();
133*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base * const         , Base *, Derived>();
134*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base * const         , Base *, Derived>();
135*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base * const         , Base *, Derived>();
136*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base *       volatile, Base *, Derived>();
137*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base *       volatile, Base *, Derived>();
138*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base *       volatile, Base *, Derived>();
139*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base *       volatile, Base *, Derived>();
140*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base * const volatile, Base *, Derived>();
141*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base * const volatile, Base *, Derived>();
142*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base * const volatile, Base *, Derived>();
143*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base * const volatile, Base *, Derived>();
144*c05d8e5dSAndroid Build Coastguard Worker }
145*c05d8e5dSAndroid Build Coastguard Worker 
f3()146*c05d8e5dSAndroid Build Coastguard Worker void f3()
147*c05d8e5dSAndroid Build Coastguard Worker {
148*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
149*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Derived * cv2
150*c05d8e5dSAndroid Build Coastguard Worker     // catches an exception of type:
151*c05d8e5dSAndroid Build Coastguard Worker     //   Derived *
152*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Derived *               , Derived *, Derived>();
153*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Derived *               , Derived *, Derived>();
154*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Derived *               , Derived *, Derived>();
155*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Derived *               , Derived *, Derived>();
156*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Derived * const         , Derived *, Derived>();
157*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Derived * const         , Derived *, Derived>();
158*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Derived * const         , Derived *, Derived>();
159*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Derived * const         , Derived *, Derived>();
160*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Derived *       volatile, Derived *, Derived>();
161*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Derived *       volatile, Derived *, Derived>();
162*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Derived *       volatile, Derived *, Derived>();
163*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Derived *       volatile, Derived *, Derived>();
164*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Derived * const volatile, Derived *, Derived>();
165*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Derived * const volatile, Derived *, Derived>();
166*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Derived * const volatile, Derived *, Derived>();
167*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Derived * const volatile, Derived *, Derived>();
168*c05d8e5dSAndroid Build Coastguard Worker }
169*c05d8e5dSAndroid Build Coastguard Worker 
f4()170*c05d8e5dSAndroid Build Coastguard Worker void f4()
171*c05d8e5dSAndroid Build Coastguard Worker {
172*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
173*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Derived * cv2
174*c05d8e5dSAndroid Build Coastguard Worker     // cannot catch an exception of type:
175*c05d8e5dSAndroid Build Coastguard Worker     //   Base *
176*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Derived *               , Base *, Derived>();
177*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Derived *               , Base *, Derived>();
178*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Derived *               , Base *, Derived>();
179*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Derived *               , Base *, Derived>();
180*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Derived * const         , Base *, Derived>();
181*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Derived * const         , Base *, Derived>();
182*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Derived * const         , Base *, Derived>();
183*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Derived * const         , Base *, Derived>();
184*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Derived *       volatile, Base *, Derived>();
185*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Derived *       volatile, Base *, Derived>();
186*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Derived *       volatile, Base *, Derived>();
187*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Derived *       volatile, Base *, Derived>();
188*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Derived * const volatile, Base *, Derived>();
189*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Derived * const volatile, Base *, Derived>();
190*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Derived * const volatile, Base *, Derived>();
191*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Derived * const volatile, Base *, Derived>();
192*c05d8e5dSAndroid Build Coastguard Worker }
193*c05d8e5dSAndroid Build Coastguard Worker 
f5()194*c05d8e5dSAndroid Build Coastguard Worker void f5()
195*c05d8e5dSAndroid Build Coastguard Worker {
196*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
197*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Derived * cv2 &
198*c05d8e5dSAndroid Build Coastguard Worker     // catches an exception of type:
199*c05d8e5dSAndroid Build Coastguard Worker     //   Derived *
200*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Derived *                &, Derived *, Derived>();
201*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Derived *                &, Derived *, Derived>();
202*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Derived *                &, Derived *, Derived>();
203*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Derived *                &, Derived *, Derived>();
204*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Derived * const          &, Derived *, Derived>();
205*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Derived * const          &, Derived *, Derived>();
206*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Derived * const          &, Derived *, Derived>();
207*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Derived * const          &, Derived *, Derived>();
208*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Derived *       volatile &, Derived *, Derived>();
209*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Derived *       volatile &, Derived *, Derived>();
210*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Derived *       volatile &, Derived *, Derived>();
211*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Derived *       volatile &, Derived *, Derived>();
212*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Derived * const volatile &, Derived *, Derived>();
213*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Derived * const volatile &, Derived *, Derived>();
214*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Derived * const volatile &, Derived *, Derived>();
215*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Derived * const volatile &, Derived *, Derived>();
216*c05d8e5dSAndroid Build Coastguard Worker }
217*c05d8e5dSAndroid Build Coastguard Worker 
f6()218*c05d8e5dSAndroid Build Coastguard Worker void f6()
219*c05d8e5dSAndroid Build Coastguard Worker {
220*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
221*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Base * cv2 &
222*c05d8e5dSAndroid Build Coastguard Worker     // catches an exception of type:
223*c05d8e5dSAndroid Build Coastguard Worker     //   Base *
224*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base *                &, Base *, Derived>();
225*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base *                &, Base *, Derived>();
226*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base *                &, Base *, Derived>();
227*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base *                &, Base *, Derived>();
228*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base * const          &, Base *, Derived>();
229*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base * const          &, Base *, Derived>();
230*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base * const          &, Base *, Derived>();
231*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base * const          &, Base *, Derived>();
232*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base *       volatile &, Base *, Derived>();
233*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base *       volatile &, Base *, Derived>();
234*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base *       volatile &, Base *, Derived>();
235*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base *       volatile &, Base *, Derived>();
236*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base * const volatile &, Base *, Derived>();
237*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base * const volatile &, Base *, Derived>();
238*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base * const volatile &, Base *, Derived>();
239*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base * const volatile &, Base *, Derived>();
240*c05d8e5dSAndroid Build Coastguard Worker 
241*c05d8e5dSAndroid Build Coastguard Worker }
242*c05d8e5dSAndroid Build Coastguard Worker 
f7()243*c05d8e5dSAndroid Build Coastguard Worker void f7()
244*c05d8e5dSAndroid Build Coastguard Worker {
245*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
246*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Derived * cv2 &
247*c05d8e5dSAndroid Build Coastguard Worker     // cannot catch an exception of type:
248*c05d8e5dSAndroid Build Coastguard Worker     //   Base *
249*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Derived *                &, Base *, Derived>();
250*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Derived *                &, Base *, Derived>();
251*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Derived *                &, Base *, Derived>();
252*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Derived *                &, Base *, Derived>();
253*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Derived * const          &, Base *, Derived>();
254*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Derived * const          &, Base *, Derived>();
255*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Derived * const          &, Base *, Derived>();
256*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Derived * const          &, Base *, Derived>();
257*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Derived *       volatile &, Base *, Derived>();
258*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Derived *       volatile &, Base *, Derived>();
259*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Derived *       volatile &, Base *, Derived>();
260*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Derived *       volatile &, Base *, Derived>();
261*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Derived * const volatile &, Base *, Derived>();
262*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Derived * const volatile &, Base *, Derived>();
263*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Derived * const volatile &, Base *, Derived>();
264*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Derived * const volatile &, Base *, Derived>();
265*c05d8e5dSAndroid Build Coastguard Worker }
266*c05d8e5dSAndroid Build Coastguard Worker 
f8()267*c05d8e5dSAndroid Build Coastguard Worker void f8()
268*c05d8e5dSAndroid Build Coastguard Worker {
269*c05d8e5dSAndroid Build Coastguard Worker     // This test case has a caveat noted in the discussion here:
270*c05d8e5dSAndroid Build Coastguard Worker     //   https://gcc.gnu.org/ml/gcc-patches/2009-08/msg00264.html
271*c05d8e5dSAndroid Build Coastguard Worker     // Specifically:
272*c05d8e5dSAndroid Build Coastguard Worker     //   This [test exposes a] corner case of the ARM C++ ABI. The generic C++
273*c05d8e5dSAndroid Build Coastguard Worker     //   ABI also gets this wrong, because I failed to notice the subtlety here.
274*c05d8e5dSAndroid Build Coastguard Worker     //   The issue is that 15.3/3 3rd bullet says:
275*c05d8e5dSAndroid Build Coastguard Worker     //     The handler is of type cv1 T* cv2 and E is a pointer type that
276*c05d8e5dSAndroid Build Coastguard Worker     //     can be converted to the type of the handler by either or both of:
277*c05d8e5dSAndroid Build Coastguard Worker     //       * a standard pointer conversion (4.10) not involving conversions
278*c05d8e5dSAndroid Build Coastguard Worker     //         to pointers to private or protected or ambiguous classes
279*c05d8e5dSAndroid Build Coastguard Worker     //   Notice that the handlers of type "cv1 T*cv2&" are not allowed such
280*c05d8e5dSAndroid Build Coastguard Worker     //   freedom to find a base class. The ABI error is that we treat handlers
281*c05d8e5dSAndroid Build Coastguard Worker     //   of reference type exactly the same as the corresponding hander of
282*c05d8e5dSAndroid Build Coastguard Worker     //   non-reference type. Elsewhere in the exception handling this makes no
283*c05d8e5dSAndroid Build Coastguard Worker     //   difference (for instance bullet 1 explicitly says 'cv T or cv T&').
284*c05d8e5dSAndroid Build Coastguard Worker     //
285*c05d8e5dSAndroid Build Coastguard Worker     // See also: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#388
286*c05d8e5dSAndroid Build Coastguard Worker     //
287*c05d8e5dSAndroid Build Coastguard Worker     //  TL;DR: it is an unresolved C++ ABI defect that these do catch
288*c05d8e5dSAndroid Build Coastguard Worker 
289*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
290*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Base * cv2 &
291*c05d8e5dSAndroid Build Coastguard Worker     // catches an exception of type:
292*c05d8e5dSAndroid Build Coastguard Worker     //   Derived *
293*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base *                &, Derived *, Derived>();
294*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base *                &, Derived *, Derived>();
295*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base *                &, Derived *, Derived>();
296*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base *                &, Derived *, Derived>();
297*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base * const          &, Derived *, Derived>();
298*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base * const          &, Derived *, Derived>();
299*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base * const          &, Derived *, Derived>();
300*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base * const          &, Derived *, Derived>();
301*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base *       volatile &, Derived *, Derived>();
302*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base *       volatile &, Derived *, Derived>();
303*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base *       volatile &, Derived *, Derived>();
304*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base *       volatile &, Derived *, Derived>();
305*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<               Base * const volatile &, Derived *, Derived>();
306*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const          Base * const volatile &, Derived *, Derived>();
307*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<      volatile Base * const volatile &, Derived *, Derived>();
308*c05d8e5dSAndroid Build Coastguard Worker     assert_catches<const volatile Base * const volatile &, Derived *, Derived>();
309*c05d8e5dSAndroid Build Coastguard Worker }
310*c05d8e5dSAndroid Build Coastguard Worker 
f9()311*c05d8e5dSAndroid Build Coastguard Worker void f9()
312*c05d8e5dSAndroid Build Coastguard Worker {
313*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
314*c05d8e5dSAndroid Build Coastguard Worker     //   cv1 Base * cv2
315*c05d8e5dSAndroid Build Coastguard Worker     // cannot catch an exception of type:
316*c05d8e5dSAndroid Build Coastguard Worker     //   Ambiguous *
317*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *               , Ambiguous *, Ambiguous>();
318*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *               , Ambiguous *, Ambiguous>();
319*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *               , Ambiguous *, Ambiguous>();
320*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *               , Ambiguous *, Ambiguous>();
321*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const         , Ambiguous *, Ambiguous>();
322*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const         , Ambiguous *, Ambiguous>();
323*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const         , Ambiguous *, Ambiguous>();
324*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const         , Ambiguous *, Ambiguous>();
325*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *       volatile, Ambiguous *, Ambiguous>();
326*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *       volatile, Ambiguous *, Ambiguous>();
327*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *       volatile, Ambiguous *, Ambiguous>();
328*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *       volatile, Ambiguous *, Ambiguous>();
329*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const volatile, Ambiguous *, Ambiguous>();
330*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const volatile, Ambiguous *, Ambiguous>();
331*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const volatile, Ambiguous *, Ambiguous>();
332*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const volatile, Ambiguous *, Ambiguous>();
333*c05d8e5dSAndroid Build Coastguard Worker }
334*c05d8e5dSAndroid Build Coastguard Worker 
f10()335*c05d8e5dSAndroid Build Coastguard Worker void f10()
336*c05d8e5dSAndroid Build Coastguard Worker {
337*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
338*c05d8e5dSAndroid Build Coastguard Worker     //  cv1 Base * cv2
339*c05d8e5dSAndroid Build Coastguard Worker     // cannot catch an exception of type:
340*c05d8e5dSAndroid Build Coastguard Worker     //  Private *
341*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *               , Private *, Private>();
342*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *               , Private *, Private>();
343*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *               , Private *, Private>();
344*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *               , Private *, Private>();
345*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const         , Private *, Private>();
346*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const         , Private *, Private>();
347*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const         , Private *, Private>();
348*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const         , Private *, Private>();
349*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *       volatile, Private *, Private>();
350*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *       volatile, Private *, Private>();
351*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *       volatile, Private *, Private>();
352*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *       volatile, Private *, Private>();
353*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const volatile, Private *, Private>();
354*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const volatile, Private *, Private>();
355*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const volatile, Private *, Private>();
356*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const volatile, Private *, Private>();
357*c05d8e5dSAndroid Build Coastguard Worker }
358*c05d8e5dSAndroid Build Coastguard Worker 
f11()359*c05d8e5dSAndroid Build Coastguard Worker void f11()
360*c05d8e5dSAndroid Build Coastguard Worker {
361*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
362*c05d8e5dSAndroid Build Coastguard Worker     //  cv1 Base * cv2
363*c05d8e5dSAndroid Build Coastguard Worker     // cannot catch an exception of type:
364*c05d8e5dSAndroid Build Coastguard Worker     //  Protected *
365*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *               , Protected *, Protected>();
366*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *               , Protected *, Protected>();
367*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *               , Protected *, Protected>();
368*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *               , Protected *, Protected>();
369*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const         , Protected *, Protected>();
370*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const         , Protected *, Protected>();
371*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const         , Protected *, Protected>();
372*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const         , Protected *, Protected>();
373*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *       volatile, Protected *, Protected>();
374*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *       volatile, Protected *, Protected>();
375*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *       volatile, Protected *, Protected>();
376*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *       volatile, Protected *, Protected>();
377*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const volatile, Protected *, Protected>();
378*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const volatile, Protected *, Protected>();
379*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const volatile, Protected *, Protected>();
380*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const volatile, Protected *, Protected>();
381*c05d8e5dSAndroid Build Coastguard Worker }
382*c05d8e5dSAndroid Build Coastguard Worker 
f12()383*c05d8e5dSAndroid Build Coastguard Worker void f12()
384*c05d8e5dSAndroid Build Coastguard Worker {
385*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
386*c05d8e5dSAndroid Build Coastguard Worker     //  cv1 Base * cv2 &
387*c05d8e5dSAndroid Build Coastguard Worker     // cannot catch an exception of type:
388*c05d8e5dSAndroid Build Coastguard Worker     //  Private *
389*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *                &, Private *, Private>();
390*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *                &, Private *, Private>();
391*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *                &, Private *, Private>();
392*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *                &, Private *, Private>();
393*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const          &, Private *, Private>();
394*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const          &, Private *, Private>();
395*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const          &, Private *, Private>();
396*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const          &, Private *, Private>();
397*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *       volatile &, Private *, Private>();
398*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *       volatile &, Private *, Private>();
399*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *       volatile &, Private *, Private>();
400*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *       volatile &, Private *, Private>();
401*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const volatile &, Private *, Private>();
402*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const volatile &, Private *, Private>();
403*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const volatile &, Private *, Private>();
404*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const volatile &, Private *, Private>();
405*c05d8e5dSAndroid Build Coastguard Worker }
406*c05d8e5dSAndroid Build Coastguard Worker 
f13()407*c05d8e5dSAndroid Build Coastguard Worker void f13()
408*c05d8e5dSAndroid Build Coastguard Worker {
409*c05d8e5dSAndroid Build Coastguard Worker     // Test that every combination of handler of type:
410*c05d8e5dSAndroid Build Coastguard Worker     //  cv1 Base * cv2 &
411*c05d8e5dSAndroid Build Coastguard Worker     // cannot catch an exception of type:
412*c05d8e5dSAndroid Build Coastguard Worker     //  Protected *
413*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *                &, Protected *, Protected>();
414*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *                &, Protected *, Protected>();
415*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *                &, Protected *, Protected>();
416*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *                &, Protected *, Protected>();
417*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const          &, Protected *, Protected>();
418*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const          &, Protected *, Protected>();
419*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const          &, Protected *, Protected>();
420*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const          &, Protected *, Protected>();
421*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base *       volatile &, Protected *, Protected>();
422*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base *       volatile &, Protected *, Protected>();
423*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base *       volatile &, Protected *, Protected>();
424*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base *       volatile &, Protected *, Protected>();
425*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<               Base * const volatile &, Protected *, Protected>();
426*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const          Base * const volatile &, Protected *, Protected>();
427*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<      volatile Base * const volatile &, Protected *, Protected>();
428*c05d8e5dSAndroid Build Coastguard Worker     assert_cannot_catch<const volatile Base * const volatile &, Protected *, Protected>();
429*c05d8e5dSAndroid Build Coastguard Worker }
430*c05d8e5dSAndroid Build Coastguard Worker 
main()431*c05d8e5dSAndroid Build Coastguard Worker int main()
432*c05d8e5dSAndroid Build Coastguard Worker {
433*c05d8e5dSAndroid Build Coastguard Worker     f1();
434*c05d8e5dSAndroid Build Coastguard Worker     f2();
435*c05d8e5dSAndroid Build Coastguard Worker     f3();
436*c05d8e5dSAndroid Build Coastguard Worker     f4();
437*c05d8e5dSAndroid Build Coastguard Worker     f5();
438*c05d8e5dSAndroid Build Coastguard Worker     f6();
439*c05d8e5dSAndroid Build Coastguard Worker     f7();
440*c05d8e5dSAndroid Build Coastguard Worker     f8();
441*c05d8e5dSAndroid Build Coastguard Worker     f9();
442*c05d8e5dSAndroid Build Coastguard Worker     f10();
443*c05d8e5dSAndroid Build Coastguard Worker     f11();
444*c05d8e5dSAndroid Build Coastguard Worker     f12();
445*c05d8e5dSAndroid Build Coastguard Worker     f13();
446*c05d8e5dSAndroid Build Coastguard Worker }
447