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