1 //===---------------------- catch_function_03.cpp -------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // Can a noexcept function pointer be caught by a non-noexcept catch clause?
10 // UNSUPPORTED: no-exceptions, no-noexcept-function-type
11 
12 // Support for catching a function pointer including noexcept was shipped in macOS 10.13
13 // XFAIL: use_system_cxx_lib && {{.+}}-apple-macosx10.{{9|10|11|12}}
14 
15 #include <cassert>
16 
17 template<bool Noexcept> void f() noexcept(Noexcept) {}
18 template<bool Noexcept> using FnType = void() noexcept(Noexcept);
19 
20 template<bool ThrowNoexcept, bool CatchNoexcept>
21 void check()
22 {
23     try
24     {
25         auto *p = f<ThrowNoexcept>;
26         throw p;
27         assert(false);
28     }
29     catch (FnType<CatchNoexcept> *p)
30     {
31         assert(ThrowNoexcept || !CatchNoexcept);
32         assert(p == &f<ThrowNoexcept>);
33     }
34     catch (...)
35     {
36         assert(!ThrowNoexcept && CatchNoexcept);
37     }
38 }
39 
40 void check_deep() {
41     auto *p = f<true>;
42     try
43     {
44         throw &p;
45     }
46     catch (FnType<false> **q)
47     {
48         assert(false);
49     }
50     catch (FnType<true> **q)
51     {
52     }
53     catch (...)
54     {
55         assert(false);
56     }
57 }
58 
59 int main(int, char**)
60 {
61     check<false, false>();
62     check<false, true>();
63     check<true, false>();
64     check<true, true>();
65     check_deep();
66 
67     return 0;
68 }
69