180b64f08SRichard Smith //===--------------- catch_member_function_pointer_02.cpp -----------------===// 280b64f08SRichard Smith // 380b64f08SRichard Smith // The LLVM Compiler Infrastructure 480b64f08SRichard Smith // 580b64f08SRichard Smith // This file is dual licensed under the MIT and the University of Illinois Open 680b64f08SRichard Smith // Source Licenses. See LICENSE.TXT for details. 780b64f08SRichard Smith // 880b64f08SRichard Smith //===----------------------------------------------------------------------===// 980b64f08SRichard Smith 1080b64f08SRichard Smith // Can a noexcept member function pointer be caught by a non-noexcept catch 1180b64f08SRichard Smith // clause? 12*366bb54fSRichard Smith // UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-noexcept-function-type 1380b64f08SRichard Smith 1480b64f08SRichard Smith #include <cassert> 1580b64f08SRichard Smith 1680b64f08SRichard Smith struct X { 1780b64f08SRichard Smith template<bool Noexcept> void f() noexcept(Noexcept) {} 1880b64f08SRichard Smith }; 1980b64f08SRichard Smith template<bool Noexcept> using FnType = void (X::*)() noexcept(Noexcept); 2080b64f08SRichard Smith 2180b64f08SRichard Smith template<bool ThrowNoexcept, bool CatchNoexcept> 2280b64f08SRichard Smith void check() 2380b64f08SRichard Smith { 2480b64f08SRichard Smith try 2580b64f08SRichard Smith { 2680b64f08SRichard Smith auto p = &X::f<ThrowNoexcept>; 2780b64f08SRichard Smith throw p; 2880b64f08SRichard Smith assert(false); 2980b64f08SRichard Smith } 3080b64f08SRichard Smith catch (FnType<CatchNoexcept> p) 3180b64f08SRichard Smith { 3280b64f08SRichard Smith assert(ThrowNoexcept || !CatchNoexcept); 3380b64f08SRichard Smith assert(p == &X::f<ThrowNoexcept>); 3480b64f08SRichard Smith } 3580b64f08SRichard Smith catch (...) 3680b64f08SRichard Smith { 3780b64f08SRichard Smith assert(!ThrowNoexcept && CatchNoexcept); 3880b64f08SRichard Smith } 3980b64f08SRichard Smith } 4080b64f08SRichard Smith 4180b64f08SRichard Smith void check_deep() { 4280b64f08SRichard Smith FnType<true> p = &X::f<true>; 4380b64f08SRichard Smith try 4480b64f08SRichard Smith { 4580b64f08SRichard Smith throw &p; 4680b64f08SRichard Smith } 4780b64f08SRichard Smith catch (FnType<false> *q) 4880b64f08SRichard Smith { 4980b64f08SRichard Smith assert(false); 5080b64f08SRichard Smith } 5180b64f08SRichard Smith catch (FnType<true> *q) 5280b64f08SRichard Smith { 5380b64f08SRichard Smith } 5480b64f08SRichard Smith catch (...) 5580b64f08SRichard Smith { 5680b64f08SRichard Smith assert(false); 5780b64f08SRichard Smith } 5880b64f08SRichard Smith } 5980b64f08SRichard Smith 6080b64f08SRichard Smith int main() 6180b64f08SRichard Smith { 6280b64f08SRichard Smith check<false, false>(); 6380b64f08SRichard Smith check<false, true>(); 6480b64f08SRichard Smith check<true, false>(); 6580b64f08SRichard Smith check<true, true>(); 6680b64f08SRichard Smith check_deep(); 6780b64f08SRichard Smith } 68