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