https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Jason Merrill <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:2415024e0f81f8c09bf08f947c790b43de9d0bbc

commit r14-1527-g2415024e0f81f8c09bf08f947c790b43de9d0bbc
Author: Jason Merrill <ja...@redhat.com>
Date:   Tue May 23 12:25:15 2023 -0400

    c++: use __cxa_call_terminate for MUST_NOT_THROW [PR97720]

    [except.handle]/7 says that when we enter std::terminate due to a throw,
    that is considered an active handler.  We already implemented that properly
    for the case of not finding a handler (__cxa_throw calls __cxa_begin_catch
    before std::terminate) and the case of finding a callsite with no landing
    pad (the personality function calls __cxa_call_terminate which calls
    __cxa_begin_catch), but for the case of a throw in a try/catch in a
noexcept
    function, we were emitting a cleanup that calls std::terminate directly
    without ever calling __cxa_begin_catch to handle the exception.

    A straightforward way to fix this seems to be calling __cxa_call_terminate
    instead.  However, that requires exporting it from libstdc++, which we have
    not previously done.  Despite the name, it isn't actually part of the ABI
    standard.  Nor is __cxa_call_unexpected, as far as I can tell, but that one
    is also used by clang.  For this case they use __clang_call_terminate; it
    seems reasonable to me for us to stick with __cxa_call_terminate.

    I also change __cxa_call_terminate to take void* for simplicity in the
front
    end (and consistency with __cxa_call_unexpected) but that isn't necessary
if
    it's undesirable for some reason.

    This patch does not fix the issue that representing the noexcept as a
    cleanup is wrong, and confuses the handler search; since it looks like a
    cleanup in the EH tables, the unwinder keeps looking until it finds the
    catch in main(), which it should never have gotten to.  Without the
    try/catch in main, the unwinder would reach the end of the stack and say no
    handler was found.  The noexcept is a handler, and should be treated as
one,
    as it is when the landing pad is omitted.

    The best fix for that issue seems to me to be to represent an
    ERT_MUST_NOT_THROW after an ERT_TRY in an action list as though it were an
    ERT_ALLOWED_EXCEPTIONS (since indeed it is an exception-specification). 
The
    actual code generation shouldn't need to change (apart from the change made
    by this patch), only the action table entry.

            PR c++/97720

    gcc/cp/ChangeLog:

            * cp-tree.h (enum cp_tree_index): Add CPTI_CALL_TERMINATE_FN.
            (call_terminate_fn): New macro.
            * cp-gimplify.cc (gimplify_must_not_throw_expr): Use it.
            * except.cc (init_exception_processing): Set it.
            (cp_protect_cleanup_actions): Return it.

    gcc/ChangeLog:

            * tree-eh.cc (lower_resx): Pass the exception pointer to the
            failure_decl.
            * except.h: Tweak comment.

    libstdc++-v3/ChangeLog:

            * libsupc++/eh_call.cc (__cxa_call_terminate): Take void*.
            * config/abi/pre/gnu.ver: Add it.

    gcc/testsuite/ChangeLog:

            * g++.dg/eh/terminate2.C: New test.

Reply via email to