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: libcxxabi-no-exceptions, libcxxabi-no-noexcept-function-type
13 
14 // GCC 7 and 8 support noexcept function types but this test still fails.
15 // This is likely a bug in their implementation. Investigation needed.
16 // XFAIL: gcc-7, gcc-8, gcc-9
17 
18 #include <cassert>
19 
20 struct X {
fX21   template<bool Noexcept> void f() noexcept(Noexcept) {}
22 };
23 template<bool Noexcept> using FnType = void (X::*)() noexcept(Noexcept);
24 
25 template<bool ThrowNoexcept, bool CatchNoexcept>
check()26 void check()
27 {
28     try
29     {
30         auto p = &X::f<ThrowNoexcept>;
31         throw p;
32         assert(false);
33     }
34     catch (FnType<CatchNoexcept> p)
35     {
36         assert(ThrowNoexcept || !CatchNoexcept);
37         assert(p == &X::f<ThrowNoexcept>);
38     }
39     catch (...)
40     {
41         assert(!ThrowNoexcept && CatchNoexcept);
42     }
43 }
44 
check_deep()45 void check_deep() {
46     FnType<true> p = &X::f<true>;
47     try
48     {
49         throw &p;
50     }
51     catch (FnType<false> *q)
52     {
53         assert(false);
54     }
55     catch (FnType<true> *q)
56     {
57     }
58     catch (...)
59     {
60         assert(false);
61     }
62 }
63 
main()64 int main()
65 {
66     check<false, false>();
67     check<false, true>();
68     check<true, false>();
69     check<true, true>();
70     check_deep();
71 }
72