180b64f08SRichard Smith //===---------------------- catch_function_03.cpp -------------------------===// 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 980b64f08SRichard Smith // Can a noexcept function pointer be caught by a non-noexcept catch clause? 108c61114cSLouis Dionne // UNSUPPORTED: no-exceptions, libcxxabi-no-noexcept-function-type 1180b64f08SRichard Smith 1280b64f08SRichard Smith #include <cassert> 1380b64f08SRichard Smith 1480b64f08SRichard Smith template<bool Noexcept> void f() noexcept(Noexcept) {} 1580b64f08SRichard Smith template<bool Noexcept> using FnType = void() noexcept(Noexcept); 1680b64f08SRichard Smith 1780b64f08SRichard Smith template<bool ThrowNoexcept, bool CatchNoexcept> 1880b64f08SRichard Smith void check() 1980b64f08SRichard Smith { 2080b64f08SRichard Smith try 2180b64f08SRichard Smith { 2280b64f08SRichard Smith auto *p = f<ThrowNoexcept>; 2380b64f08SRichard Smith throw p; 2480b64f08SRichard Smith assert(false); 2580b64f08SRichard Smith } 2680b64f08SRichard Smith catch (FnType<CatchNoexcept> *p) 2780b64f08SRichard Smith { 2880b64f08SRichard Smith assert(ThrowNoexcept || !CatchNoexcept); 2980b64f08SRichard Smith assert(p == &f<ThrowNoexcept>); 3080b64f08SRichard Smith } 3180b64f08SRichard Smith catch (...) 3280b64f08SRichard Smith { 3380b64f08SRichard Smith assert(!ThrowNoexcept && CatchNoexcept); 3480b64f08SRichard Smith } 3580b64f08SRichard Smith } 3680b64f08SRichard Smith 3780b64f08SRichard Smith void check_deep() { 3880b64f08SRichard Smith auto *p = f<true>; 3980b64f08SRichard Smith try 4080b64f08SRichard Smith { 4180b64f08SRichard Smith throw &p; 4280b64f08SRichard Smith } 4380b64f08SRichard Smith catch (FnType<false> **q) 4480b64f08SRichard Smith { 4580b64f08SRichard Smith assert(false); 4680b64f08SRichard Smith } 4780b64f08SRichard Smith catch (FnType<true> **q) 4880b64f08SRichard Smith { 4980b64f08SRichard Smith } 5080b64f08SRichard Smith catch (...) 5180b64f08SRichard Smith { 5280b64f08SRichard Smith assert(false); 5380b64f08SRichard Smith } 5480b64f08SRichard Smith } 5580b64f08SRichard Smith 56*504bc07dSLouis Dionne int main(int, char**) 5780b64f08SRichard Smith { 5880b64f08SRichard Smith check<false, false>(); 5980b64f08SRichard Smith check<false, true>(); 6080b64f08SRichard Smith check<true, false>(); 6180b64f08SRichard Smith check<true, true>(); 6280b64f08SRichard Smith check_deep(); 63*504bc07dSLouis Dionne 64*504bc07dSLouis Dionne return 0; 6580b64f08SRichard Smith } 66