/ test / catch_function_03.pass.cpp
catch_function_03.pass.cpp
 1  //===---------------------- catch_function_03.cpp -------------------------===//
 2  //
 3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 4  // See https://llvm.org/LICENSE.txt for license information.
 5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 6  //
 7  //===----------------------------------------------------------------------===//
 8  
 9  // Can a noexcept function pointer be caught by a non-noexcept catch clause?
10  // UNSUPPORTED: no-exceptions, no-noexcept-function-type
11  
12  // Support for catching a function pointer including noexcept was shipped in macOS 10.13
13  // XFAIL: use_system_cxx_lib && {{.+}}-apple-macosx10.{{9|10|11|12}}
14  
15  #include <cassert>
16  
17  template<bool Noexcept> void f() noexcept(Noexcept) {}
18  template<bool Noexcept> using FnType = void() noexcept(Noexcept);
19  
20  template<bool ThrowNoexcept, bool CatchNoexcept>
21  void check()
22  {
23      try
24      {
25          auto *p = f<ThrowNoexcept>;
26          throw p;
27          assert(false);
28      }
29      catch (FnType<CatchNoexcept> *p)
30      {
31          assert(ThrowNoexcept || !CatchNoexcept);
32          assert(p == &f<ThrowNoexcept>);
33      }
34      catch (...)
35      {
36          assert(!ThrowNoexcept && CatchNoexcept);
37      }
38  }
39  
40  void check_deep() {
41      auto *p = f<true>;
42      try
43      {
44          throw &p;
45      }
46      catch (FnType<false> **q)
47      {
48          assert(false);
49      }
50      catch (FnType<true> **q)
51      {
52      }
53      catch (...)
54      {
55          assert(false);
56      }
57  }
58  
59  int main(int, char**)
60  {
61      check<false, false>();
62      check<false, true>();
63      check<true, false>();
64      check<true, true>();
65      check_deep();
66  
67      return 0;
68  }