[Bug c++/97720] throw in try in noexcept fn calls terminate without handling the exception

2024-05-07 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|14.0|14.2

--- Comment #10 from Richard Biener  ---
GCC 14.1 is being released, retargeting bugs to GCC 14.2.

[Bug c++/97720] throw in try in noexcept fn calls terminate without handling the exception

2023-06-03 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720

Jason Merrill  changed:

   What|Removed |Added

 Depends on|95741   |
 Status|NEW |ASSIGNED
   Target Milestone|--- |14.0
   Assignee|unassigned at gcc dot gnu.org  |jason at gcc dot gnu.org
   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=95741

--- Comment #9 from Jason Merrill  ---
(In reply to m101010a from comment #6)
> I don't believe there's a way to solve PR55918 without modifying the
> personality function in some way

I agree; for C++17 (when dynamic exception specifications were removed) and
later we could use an alternate personality function that knows that an
exception-specification is noexcept, so we can just call terminate.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95741
[Bug 95741] Optimization skips destructor and calls terminate directly

[Bug c++/97720] throw in try in noexcept fn calls terminate without handling the exception

2023-06-03 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720

--- Comment #8 from Jason Merrill  ---
*** Bug 97339 has been marked as a duplicate of this bug. ***

[Bug c++/97720] throw in try in noexcept fn calls terminate without handling the exception

2023-06-03 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720

--- Comment #7 from CVS Commits  ---
The trunk branch has been updated by Jason Merrill :

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

commit r14-1527-g2415024e0f81f8c09bf08f947c790b43de9d0bbc
Author: Jason Merrill 
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.

[Bug c++/97720] throw in try in noexcept fn calls terminate without handling the exception

2023-05-23 Thread m101010a at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720

--- Comment #6 from m101010a at gmail dot com ---
> represent the second case in the action table as an empty exception 
> specification like C++98 throw()

That will deal with this issue and PR88218, but won't solve PR55918 since using
throw() causes the stack to unwind.  I don't believe there's a way to solve
PR55918 without modifying the personality function in some way; if terminate is
called in the handler then we're already in phase 2, which means the stack has
already been unwound.

[Bug c++/97720] throw in try in noexcept fn calls terminate without handling the exception

2023-05-22 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720

--- Comment #5 from Jason Merrill  ---
Note that Foo is unneeded, this shows the same behavior:

void bad_guy() throw() {
  try { throw 0; }
  catch (float) { }
  // Don't catch int.   
}

void level1() {
  bad_guy();
  throw "dead code";
}

int main() {
  try { level1(); }
  catch (int) { }
}

// terminate called without an active exception

Without the throw "dead code" the compiler optimizes away the catch in main, so
the handler search finds nothing, so __cxa_throw calls __cxa_call_terminate and
std::current_exception is set properly.

But of course the catch in main shouldn't make a difference, the search should
never leave bad_guy.

[Bug c++/97720] throw in try in noexcept fn calls terminate without handling the exception

2023-05-22 Thread jason at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97720

Jason Merrill  changed:

   What|Removed |Added

 Ever confirmed|0   |1
   Last reconfirmed||2023-05-22
Summary|Sometimes   |throw in try in noexcept fn
   |std::current_exception does |calls terminate without
   |not work properly in the|handling the exception
   |terminate handler   |
 Status|UNCONFIRMED |NEW
 CC||jason at gcc dot gnu.org

--- Comment #4 from Jason Merrill  ---
Yes.  https://eel.is/c++draft/except#handle-7 : "Also, an implicit handler is
considered active when the function std​::​terminate is entered due to a
throw."

This is handled properly for the case where there is no possible catch clause
between the call and the noexcept: in that case the call site has no EH landing
pad, so the personality function calls __cxa_call_terminate, which properly
handles the exception.

In the comment #3 case where there are catch clauses, we represent the noexcept
region around the catch as a cleanup.  This also means that the phase 1 search
for a handler looks past it rather than properly recognizing that we found a
(terminating) handler.  And we call std::terminate directly rather than through
__cxa_call_terminate, so indeed std::current_exception is wrong.

I assume the optimization sensitivity the original testcase is seeing is due to
inlining changing whether a particular call falls into the first or second case
above.

It looks like Clang represents the second case roughly as catch (...) {
std::terminate(); }

It seems to me that it would be superior to represent the second case in the
action table as an empty exception specification like C++98 throw(), but in the
generated code hand off to __cxa_call_terminate rather than
__cxa_call_unexpected.  Representing it that way rather than catch(...) would
work better for PR88218 and PR55918.