1 //===--------------- catch_member_function_pointer_02.cpp -----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // Can a noexcept member function pointer be caught by a non-noexcept catch
11 // clause?
12 // UNSUPPORTED: c++98, c++03, c++11, c++14
13 // UNSUPPORTED: libcxxabi-no-exceptions
14 
15 #include <cassert>
16 
17 #ifdef __cpp_noexcept_function_type
18 struct X {
19   template<bool Noexcept> void f() noexcept(Noexcept) {}
20 };
21 template<bool Noexcept> using FnType = void (X::*)() noexcept(Noexcept);
22 
23 template<bool ThrowNoexcept, bool CatchNoexcept>
24 void check()
25 {
26     try
27     {
28         auto p = &X::f<ThrowNoexcept>;
29         throw p;
30         assert(false);
31     }
32     catch (FnType<CatchNoexcept> p)
33     {
34         assert(ThrowNoexcept || !CatchNoexcept);
35         assert(p == &X::f<ThrowNoexcept>);
36     }
37     catch (...)
38     {
39         assert(!ThrowNoexcept && CatchNoexcept);
40     }
41 }
42 
43 void check_deep() {
44     FnType<true> p = &X::f<true>;
45     try
46     {
47         throw &p;
48     }
49     catch (FnType<false> *q)
50     {
51         assert(false);
52     }
53     catch (FnType<true> *q)
54     {
55     }
56     catch (...)
57     {
58         assert(false);
59     }
60 }
61 
62 int main()
63 {
64     check<false, false>();
65     check<false, true>();
66     check<true, false>();
67     check<true, true>();
68     check_deep();
69 }
70 #else
71 int main() {}
72 #endif
73