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, libcxxabi-no-qualified-function-types
14 
15 #include <cassert>
16 
17 struct X {
18   template<bool Noexcept> void f() noexcept(Noexcept) {}
19 };
20 template<bool Noexcept> using FnType = void (X::*)() noexcept(Noexcept);
21 
22 template<bool ThrowNoexcept, bool CatchNoexcept>
23 void check()
24 {
25     try
26     {
27         auto p = &X::f<ThrowNoexcept>;
28         throw p;
29         assert(false);
30     }
31     catch (FnType<CatchNoexcept> p)
32     {
33         assert(ThrowNoexcept || !CatchNoexcept);
34         assert(p == &X::f<ThrowNoexcept>);
35     }
36     catch (...)
37     {
38         assert(!ThrowNoexcept && CatchNoexcept);
39     }
40 }
41 
42 void check_deep() {
43     FnType<true> p = &X::f<true>;
44     try
45     {
46         throw &p;
47     }
48     catch (FnType<false> *q)
49     {
50         assert(false);
51     }
52     catch (FnType<true> *q)
53     {
54     }
55     catch (...)
56     {
57         assert(false);
58     }
59 }
60 
61 int main()
62 {
63     check<false, false>();
64     check<false, true>();
65     check<true, false>();
66     check<true, true>();
67     check_deep();
68 }
69