1*80b64f08SRichard Smith //===---------------------- catch_function_03.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 function pointer be caught by a non-noexcept catch clause?
11*80b64f08SRichard Smith // UNSUPPORTED: c++98, c++03, c++11, c++14
12*80b64f08SRichard Smith // UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-qualified-function-types
13*80b64f08SRichard Smith 
14*80b64f08SRichard Smith #include <cassert>
15*80b64f08SRichard Smith 
16*80b64f08SRichard Smith template<bool Noexcept> void f() noexcept(Noexcept) {}
17*80b64f08SRichard Smith template<bool Noexcept> using FnType = void() noexcept(Noexcept);
18*80b64f08SRichard Smith 
19*80b64f08SRichard Smith template<bool ThrowNoexcept, bool CatchNoexcept>
20*80b64f08SRichard Smith void check()
21*80b64f08SRichard Smith {
22*80b64f08SRichard Smith     try
23*80b64f08SRichard Smith     {
24*80b64f08SRichard Smith         auto *p = f<ThrowNoexcept>;
25*80b64f08SRichard Smith         throw p;
26*80b64f08SRichard Smith         assert(false);
27*80b64f08SRichard Smith     }
28*80b64f08SRichard Smith     catch (FnType<CatchNoexcept> *p)
29*80b64f08SRichard Smith     {
30*80b64f08SRichard Smith         assert(ThrowNoexcept || !CatchNoexcept);
31*80b64f08SRichard Smith         assert(p == &f<ThrowNoexcept>);
32*80b64f08SRichard Smith     }
33*80b64f08SRichard Smith     catch (...)
34*80b64f08SRichard Smith     {
35*80b64f08SRichard Smith         assert(!ThrowNoexcept && CatchNoexcept);
36*80b64f08SRichard Smith     }
37*80b64f08SRichard Smith }
38*80b64f08SRichard Smith 
39*80b64f08SRichard Smith void check_deep() {
40*80b64f08SRichard Smith     auto *p = f<true>;
41*80b64f08SRichard Smith     try
42*80b64f08SRichard Smith     {
43*80b64f08SRichard Smith         throw &p;
44*80b64f08SRichard Smith     }
45*80b64f08SRichard Smith     catch (FnType<false> **q)
46*80b64f08SRichard Smith     {
47*80b64f08SRichard Smith         assert(false);
48*80b64f08SRichard Smith     }
49*80b64f08SRichard Smith     catch (FnType<true> **q)
50*80b64f08SRichard Smith     {
51*80b64f08SRichard Smith     }
52*80b64f08SRichard Smith     catch (...)
53*80b64f08SRichard Smith     {
54*80b64f08SRichard Smith         assert(false);
55*80b64f08SRichard Smith     }
56*80b64f08SRichard Smith }
57*80b64f08SRichard Smith 
58*80b64f08SRichard Smith int main()
59*80b64f08SRichard Smith {
60*80b64f08SRichard Smith     check<false, false>();
61*80b64f08SRichard Smith     check<false, true>();
62*80b64f08SRichard Smith     check<true, false>();
63*80b64f08SRichard Smith     check<true, true>();
64*80b64f08SRichard Smith     check_deep();
65*80b64f08SRichard Smith }
66