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