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 // UNSUPPORTED: no-exceptions
11 // 1b00fc5d8133 made it in the dylib in macOS 10.11
12 // XFAIL: stdlib=apple-libc++ && target={{.+}}-apple-macosx10.{{9|10}}
18 // Roll our own assertion macro to get better error messages out of the tests.
19 // In particular on systems that don't use __PRETTY_FUNCTION__ in assertions.
20 #define my_assert(pred, msg) do_assert(pred, msg, __LINE__, __PRETTY_FUNCTION__)
22 void do_assert(bool assert_passed
, const char* msg
, int line
, const char* func
) {
25 std::printf("%s:%d %s: Assertion Failed '%s'\n\n", __FILE__
, line
, func
, msg
);
31 struct Derived
: public Base
{};
34 bool test_conversion(To
) { return true; }
37 bool test_conversion(...) { return false; }
39 template <class Pointer
>
40 struct CreatePointer
{
41 Pointer
operator()() const {
47 struct CreatePointer
<Tp
*> {
48 Tp
* operator()() const {
53 template <class Throw
, class Catch
>
54 void catch_pointer_test() {
55 Throw throw_ptr
= CreatePointer
<Throw
>()();
56 // Use the compiler to determine if the exception of type Throw can be
57 // implicitly converted to type Catch.
58 const bool can_convert
= test_conversion
<Catch
>(throw_ptr
);
62 } catch (Catch catch_ptr
) {
63 Catch catch2
= CreatePointer
<Catch
>()();
64 my_assert(can_convert
, "non-convertible type incorrectly caught");
65 my_assert(catch_ptr
== catch2
,
66 "Thrown pointer does not match caught ptr");
68 my_assert(!can_convert
, "convertible type incorrectly not caught");
72 // Generate CV qualified pointer typedefs.
73 template <class Tp
, bool First
= false>
76 typedef Tp
const* CType
;
77 typedef Tp
volatile* VType
;
78 typedef Tp
const volatile* CVType
;
81 // Special case for cv-qualifying a pointer-to-member without adding an extra
83 template <class Member
, class Class
>
84 struct TestTypes
<Member
Class::*, true> {
85 typedef Member (Class::*Type
);
86 typedef const Member (Class::*CType
);
87 typedef volatile Member (Class::*VType
);
88 typedef const volatile Member (Class::*CVType
);
91 template <class Throw
, class Catch
, int level
, bool first
= false>
92 struct generate_tests_imp
{
93 typedef TestTypes
<Throw
, first
> ThrowTypes
;
94 typedef TestTypes
<Catch
, first
> CatchTypes
;
96 typedef typename
ThrowTypes::Type Type
;
97 typedef typename
ThrowTypes::CType CType
;
98 typedef typename
ThrowTypes::VType VType
;
99 typedef typename
ThrowTypes::CVType CVType
;
101 run_catch_tests
<Type
>();
102 run_catch_tests
<CType
>();
103 run_catch_tests
<VType
>();
104 run_catch_tests
<CVType
>();
107 template <class ThrowTp
>
108 void run_catch_tests() {
109 typedef typename
CatchTypes::Type Type
;
110 typedef typename
CatchTypes::CType CType
;
111 typedef typename
CatchTypes::VType VType
;
112 typedef typename
CatchTypes::CVType CVType
;
114 catch_pointer_test
<ThrowTp
, Type
>();
115 catch_pointer_test
<ThrowTp
, CType
>();
116 catch_pointer_test
<ThrowTp
, VType
>();
117 catch_pointer_test
<ThrowTp
, CVType
>();
119 generate_tests_imp
<ThrowTp
, Type
, level
-1>()();
120 generate_tests_imp
<ThrowTp
, CType
, level
-1>()();
121 generate_tests_imp
<ThrowTp
, VType
, level
-1>()();
122 generate_tests_imp
<ThrowTp
, CVType
, level
-1>()();
126 template <class Throw
, class Catch
, bool first
>
127 struct generate_tests_imp
<Throw
, Catch
, 0, first
> {
129 catch_pointer_test
<Throw
, Catch
>();
133 template <class Throw
, class Catch
, int level
>
134 struct generate_tests
: generate_tests_imp
<Throw
, Catch
, level
, true> {};
136 int main(int, char**)
138 generate_tests
<int, int, 3>()();
139 generate_tests
<Base
, Derived
, 2>()();
140 generate_tests
<Derived
, Base
, 2>()();
141 generate_tests
<int, void, 2>()();
142 generate_tests
<void, int, 2>()();
144 generate_tests
<int A::*, int A::*, 3>()();
145 generate_tests
<int A::*, void, 2>()();
146 generate_tests
<void, int A::*, 2>()();