1eb8650a7SLouis Dionne //===----------------------------------------------------------------------===// 280b64f08SRichard Smith // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 680b64f08SRichard Smith // 780b64f08SRichard Smith //===----------------------------------------------------------------------===// 880b64f08SRichard Smith 98fb47456SLouis Dionne // Can a noexcept member function pointer be caught by a non-noexcept catch clause? 10*401b76fdSArthur O'Dwyer // UNSUPPORTED: c++03, c++11, c++14 11*401b76fdSArthur O'Dwyer // UNSUPPORTED: no-exceptions 128fb47456SLouis Dionne 138fb47456SLouis Dionne // Support for catching a function pointer including noexcept was shipped in macOS 10.13 148fb47456SLouis Dionne // XFAIL: use_system_cxx_lib && {{.+}}-apple-macosx10.{{9|10|11|12}} 1580b64f08SRichard Smith 166900df37SLouis Dionne // GCC supports noexcept function types but this test still fails. 170af53563SEric Fiselier // This is likely a bug in their implementation. Investigation needed. 186900df37SLouis Dionne // XFAIL: gcc-11 190af53563SEric Fiselier 2080b64f08SRichard Smith #include <cassert> 2180b64f08SRichard Smith 2280b64f08SRichard Smith struct X { 2380b64f08SRichard Smith template<bool Noexcept> void f() noexcept(Noexcept) {} 2480b64f08SRichard Smith }; 2580b64f08SRichard Smith template<bool Noexcept> using FnType = void (X::*)() noexcept(Noexcept); 2680b64f08SRichard Smith 2780b64f08SRichard Smith template<bool ThrowNoexcept, bool CatchNoexcept> 2880b64f08SRichard Smith void check() 2980b64f08SRichard Smith { 3080b64f08SRichard Smith try 3180b64f08SRichard Smith { 3280b64f08SRichard Smith auto p = &X::f<ThrowNoexcept>; 3380b64f08SRichard Smith throw p; 3480b64f08SRichard Smith assert(false); 3580b64f08SRichard Smith } 3680b64f08SRichard Smith catch (FnType<CatchNoexcept> p) 3780b64f08SRichard Smith { 3880b64f08SRichard Smith assert(ThrowNoexcept || !CatchNoexcept); 3980b64f08SRichard Smith assert(p == &X::f<ThrowNoexcept>); 4080b64f08SRichard Smith } 4180b64f08SRichard Smith catch (...) 4280b64f08SRichard Smith { 4380b64f08SRichard Smith assert(!ThrowNoexcept && CatchNoexcept); 4480b64f08SRichard Smith } 4580b64f08SRichard Smith } 4680b64f08SRichard Smith 4780b64f08SRichard Smith void check_deep() { 4880b64f08SRichard Smith FnType<true> p = &X::f<true>; 4980b64f08SRichard Smith try 5080b64f08SRichard Smith { 5180b64f08SRichard Smith throw &p; 5280b64f08SRichard Smith } 5380b64f08SRichard Smith catch (FnType<false> *q) 5480b64f08SRichard Smith { 5580b64f08SRichard Smith assert(false); 5680b64f08SRichard Smith } 5780b64f08SRichard Smith catch (FnType<true> *q) 5880b64f08SRichard Smith { 5980b64f08SRichard Smith } 6080b64f08SRichard Smith catch (...) 6180b64f08SRichard Smith { 6280b64f08SRichard Smith assert(false); 6380b64f08SRichard Smith } 6480b64f08SRichard Smith } 6580b64f08SRichard Smith 66504bc07dSLouis Dionne int main(int, char**) 6780b64f08SRichard Smith { 6880b64f08SRichard Smith check<false, false>(); 6980b64f08SRichard Smith check<false, true>(); 7080b64f08SRichard Smith check<true, false>(); 7180b64f08SRichard Smith check<true, true>(); 7280b64f08SRichard Smith check_deep(); 73504bc07dSLouis Dionne 74504bc07dSLouis Dionne return 0; 7580b64f08SRichard Smith } 76