1 //===--------------------- catch_pointer_nullptr.cpp ----------------------===//
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 // UNSUPPORTED: libcxxabi-no-exceptions
15 // Roll our own assertion macro to get better error messages out of the tests.
16 // In particular on systems that don't use __PRETTY_FUNCTION__ in assertions.
17 #define my_assert(pred, msg) do_assert(pred, msg, __LINE__, __PRETTY_FUNCTION__)
19 void do_assert(bool assert_passed
, const char* msg
, int line
, const char* func
) {
20 if (assert_passed
) return;
21 std::cerr
<< __FILE__
<< ":" << line
<< " " << func
22 << ": Assertion Failed `" << msg
<< "'\n\n";
28 struct Derived
: public Base
{};
31 bool test_conversion(To
) { return true; }
34 bool test_conversion(...) { return false; }
36 template <class Pointer
>
37 struct CreatePointer
{
38 Pointer
operator()() const {
44 struct CreatePointer
<Tp
*> {
45 Tp
* operator()() const {
50 template <class Throw
, class Catch
>
51 void catch_pointer_test() {
52 Throw throw_ptr
= CreatePointer
<Throw
>()();
53 // Use the compiler to determine if the exception of type Throw can be
54 // implicitly converted to type Catch.
55 const bool can_convert
= test_conversion
<Catch
>(throw_ptr
);
59 } catch (Catch catch_ptr
) {
60 Catch catch2
= CreatePointer
<Catch
>()();
61 my_assert(can_convert
, "non-convertible type incorrectly caught");
62 my_assert(catch_ptr
== catch2
,
63 "Thrown pointer does not match caught ptr");
65 my_assert(!can_convert
, "convertible type incorrectly not caught");
69 // Generate CV qualified pointer typedefs.
70 template <class Tp
, bool First
= false>
73 typedef Tp
const* CType
;
74 typedef Tp
volatile* VType
;
75 typedef Tp
const volatile* CVType
;
78 // Special case for cv-qualifying a pointer-to-member without adding an extra
80 template <class Member
, class Class
>
81 struct TestTypes
<Member
Class::*, true> {
82 typedef Member (Class::*Type
);
83 typedef const Member (Class::*CType
);
84 typedef volatile Member (Class::*VType
);
85 typedef const volatile Member (Class::*CVType
);
88 template <class Throw
, class Catch
, int level
, bool first
= false>
89 struct generate_tests_imp
{
90 typedef TestTypes
<Throw
, first
> ThrowTypes
;
91 typedef TestTypes
<Catch
, first
> CatchTypes
;
93 typedef typename
ThrowTypes::Type Type
;
94 typedef typename
ThrowTypes::CType CType
;
95 typedef typename
ThrowTypes::VType VType
;
96 typedef typename
ThrowTypes::CVType CVType
;
98 run_catch_tests
<Type
>();
99 run_catch_tests
<CType
>();
100 run_catch_tests
<VType
>();
101 run_catch_tests
<CVType
>();
104 template <class ThrowTp
>
105 void run_catch_tests() {
106 typedef typename
CatchTypes::Type Type
;
107 typedef typename
CatchTypes::CType CType
;
108 typedef typename
CatchTypes::VType VType
;
109 typedef typename
CatchTypes::CVType CVType
;
111 catch_pointer_test
<ThrowTp
, Type
>();
112 catch_pointer_test
<ThrowTp
, CType
>();
113 catch_pointer_test
<ThrowTp
, VType
>();
114 catch_pointer_test
<ThrowTp
, CVType
>();
116 generate_tests_imp
<ThrowTp
, Type
, level
-1>()();
117 generate_tests_imp
<ThrowTp
, CType
, level
-1>()();
118 generate_tests_imp
<ThrowTp
, VType
, level
-1>()();
119 generate_tests_imp
<ThrowTp
, CVType
, level
-1>()();
123 template <class Throw
, class Catch
, bool first
>
124 struct generate_tests_imp
<Throw
, Catch
, 0, first
> {
126 catch_pointer_test
<Throw
, Catch
>();
130 template <class Throw
, class Catch
, int level
>
131 struct generate_tests
: generate_tests_imp
<Throw
, Catch
, level
, true> {};
135 generate_tests
<int, int, 3>()();
136 generate_tests
<Base
, Derived
, 2>()();
137 generate_tests
<Derived
, Base
, 2>()();
138 generate_tests
<int, void, 2>()();
139 generate_tests
<void, int, 2>()();
141 generate_tests
<int A::*, int A::*, 3>()();
142 generate_tests
<int A::*, void, 2>()();
143 generate_tests
<void, int A::*, 2>()();