1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This test case checks specifically the cases under bullet 3.3:
12 // A handler is a match for an exception object of type E if
13 // * The handler is of type cv T or cv T& and E and T are the same type
14 // (ignoring the top-level cv-qualifiers), or
15 // * the handler is of type cv T or cv T& and T is an unambiguous base
17 // > * the handler is of type cv1 T* cv2 and E is a pointer type that can <
18 // > be converted to the type of the handler by either or both of <
19 // > o a standard pointer conversion (4.10 [conv.ptr]) not involving <
20 // > conversions to private or protected or ambiguous classes <
21 // > o a qualification conversion <
22 // * the handler is a pointer or pointer to member type and E is
25 //===----------------------------------------------------------------------===//
27 // UNSUPPORTED: no-exceptions
29 // This test requires the fix to https://github.com/llvm/llvm-project/issues/64953,
30 // which landed in d5f84e6 and is in the libc++abi built library.
31 // XFAIL: using-built-library-before-llvm-18
44 struct Derived1
: Base
{
47 struct Derived2
: Base
{
50 struct Derived3
: Base2
{
53 struct Private
: private Base
{
56 struct Protected
: protected Base
{
59 struct Virtual1
: virtual Base
{
62 struct Virtual2
: virtual Base
{
66 struct Ambiguous1
: Derived1
, Derived2
{
69 struct Ambiguous2
: Derived1
, Private
{
72 struct Ambiguous3
: Derived1
, Protected
{
76 struct NoPublic1
: Private
, Base2
{
79 struct NoPublic2
: Protected
, Base2
{
83 struct Catchable1
: Derived3
, Derived1
{
86 struct Catchable2
: Virtual1
, Virtual2
{
89 struct Catchable3
: virtual Base
, Virtual2
{
93 // Check that, when we have a null pointer-to-object that we catch a nullptr.
94 template <typename T
// Handler type
96 typename E
// Thrown exception type
98 void assert_catches() {
100 throw static_cast<E
>(0);
101 printf("%s\n", __PRETTY_FUNCTION__
);
102 assert(false && "Statements after throw must be unreachable");
104 assert(t
== nullptr);
107 printf("%s\n", __PRETTY_FUNCTION__
);
108 assert(false && "Should not have entered catch-all");
111 printf("%s\n", __PRETTY_FUNCTION__
);
112 assert(false && "The catch should have returned");
115 template <typename T
// Handler type
117 typename E
// Thrown exception type
119 void assert_cannot_catch() {
121 throw static_cast<E
>(0);
122 printf("%s\n", __PRETTY_FUNCTION__
);
123 assert(false && "Statements after throw must be unreachable");
125 printf("%s\n", __PRETTY_FUNCTION__
);
126 assert(false && "Should not have entered the catch");
132 printf("%s\n", __PRETTY_FUNCTION__
);
133 assert(false && "The catch-all should have returned");
136 // Check that when we have a pointer-to-actual-object we, in fact, get the
137 // adjusted pointer to the base class.
138 template <typename T
// Handler type
140 typename O
// Object type
142 void assert_catches_bp() {
146 printf("%s\n", __PRETTY_FUNCTION__
);
147 assert(false && "Statements after throw must be unreachable");
149 assert(t
== static_cast<T
>(o
));
150 //__builtin_printf("o = %p t = %p\n", o, t);
154 printf("%s\n", __PRETTY_FUNCTION__
);
155 assert(false && "Should not have entered catch-all");
158 printf("%s\n", __PRETTY_FUNCTION__
);
159 assert(false && "The catch should have returned");
163 assert_catches
<Base
*, Catchable1
*>();
164 assert_catches
<Base
*, Catchable2
*>();
165 assert_catches
<Base
*, Catchable3
*>();
169 assert_cannot_catch
<Base
*, Ambiguous1
*>();
170 assert_cannot_catch
<Base
*, Ambiguous2
*>();
171 assert_cannot_catch
<Base
*, Ambiguous3
*>();
172 assert_cannot_catch
<Base
*, NoPublic1
*>();
173 assert_cannot_catch
<Base
*, NoPublic2
*>();
177 assert_catches_bp
<Base
*, Catchable1
>();
178 assert_catches_bp
<Base
*, Catchable2
>();
179 assert_catches_bp
<Base
*, Catchable3
>();
182 int main(int, char**) {