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}}
14 // mps2-an385 machine used for testing of picolibc has just 4 MB of "flash"
15 // memory and this test requires almost 5 MB
16 // UNSUPPORTED: LIBCXX-PICOLIBC-FIXME
22 // Roll our own assertion macro to get better error messages out of the tests.
23 // In particular on systems that don't use __PRETTY_FUNCTION__ in assertions.
24 #define my_assert(pred, msg) do_assert(pred, msg, __LINE__, __PRETTY_FUNCTION__)
26 void do_assert(bool assert_passed
, const char* msg
, int line
, const char* func
) {
29 std::printf("%s:%d %s: Assertion Failed '%s'\n\n", __FILE__
, line
, func
, msg
);
35 struct Derived
: public Base
{};
38 bool test_conversion(To
) { return true; }
41 bool test_conversion(...) { return false; }
43 template <class Pointer
>
44 struct CreatePointer
{
45 Pointer
operator()() const {
51 struct CreatePointer
<Tp
*> {
52 Tp
* operator()() const {
57 template <class Throw
, class Catch
>
58 void catch_pointer_test() {
59 Throw throw_ptr
= CreatePointer
<Throw
>()();
60 // Use the compiler to determine if the exception of type Throw can be
61 // implicitly converted to type Catch.
62 const bool can_convert
= test_conversion
<Catch
>(throw_ptr
);
66 } catch (Catch catch_ptr
) {
67 Catch catch2
= CreatePointer
<Catch
>()();
68 my_assert(can_convert
, "non-convertible type incorrectly caught");
69 my_assert(catch_ptr
== catch2
,
70 "Thrown pointer does not match caught ptr");
72 my_assert(!can_convert
, "convertible type incorrectly not caught");
76 // Generate CV qualified pointer typedefs.
77 template <class Tp
, bool First
= false>
80 typedef Tp
const* CType
;
81 typedef Tp
volatile* VType
;
82 typedef Tp
const volatile* CVType
;
85 // Special case for cv-qualifying a pointer-to-member without adding an extra
87 template <class Member
, class Class
>
88 struct TestTypes
<Member
Class::*, true> {
89 typedef Member (Class::*Type
);
90 typedef const Member (Class::*CType
);
91 typedef volatile Member (Class::*VType
);
92 typedef const volatile Member (Class::*CVType
);
95 template <class Throw
, class Catch
, int level
, bool first
= false>
96 struct generate_tests_imp
{
97 typedef TestTypes
<Throw
, first
> ThrowTypes
;
98 typedef TestTypes
<Catch
, first
> CatchTypes
;
100 typedef typename
ThrowTypes::Type Type
;
101 typedef typename
ThrowTypes::CType CType
;
102 typedef typename
ThrowTypes::VType VType
;
103 typedef typename
ThrowTypes::CVType CVType
;
105 run_catch_tests
<Type
>();
106 run_catch_tests
<CType
>();
107 run_catch_tests
<VType
>();
108 run_catch_tests
<CVType
>();
111 template <class ThrowTp
>
112 void run_catch_tests() {
113 typedef typename
CatchTypes::Type Type
;
114 typedef typename
CatchTypes::CType CType
;
115 typedef typename
CatchTypes::VType VType
;
116 typedef typename
CatchTypes::CVType CVType
;
118 catch_pointer_test
<ThrowTp
, Type
>();
119 catch_pointer_test
<ThrowTp
, CType
>();
120 catch_pointer_test
<ThrowTp
, VType
>();
121 catch_pointer_test
<ThrowTp
, CVType
>();
123 generate_tests_imp
<ThrowTp
, Type
, level
-1>()();
124 generate_tests_imp
<ThrowTp
, CType
, level
-1>()();
125 generate_tests_imp
<ThrowTp
, VType
, level
-1>()();
126 generate_tests_imp
<ThrowTp
, CVType
, level
-1>()();
130 template <class Throw
, class Catch
, bool first
>
131 struct generate_tests_imp
<Throw
, Catch
, 0, first
> {
133 catch_pointer_test
<Throw
, Catch
>();
137 template <class Throw
, class Catch
, int level
>
138 struct generate_tests
: generate_tests_imp
<Throw
, Catch
, level
, true> {};
140 int main(int, char**)
142 generate_tests
<int, int, 3>()();
143 generate_tests
<Base
, Derived
, 2>()();
144 generate_tests
<Derived
, Base
, 2>()();
145 generate_tests
<int, void, 2>()();
146 generate_tests
<void, int, 2>()();
148 generate_tests
<int A::*, int A::*, 3>()();
149 generate_tests
<int A::*, void, 2>()();
150 generate_tests
<void, int A::*, 2>()();