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