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