Hi! The following testcase ICEs with -std=c++98 since r14-5086 because block_may_fallthru is called on a TRY_CATCH_EXPR whose second operand is a MODIFY_EXPR rather than STATEMENT_LIST, which try_catch_may_fallthru apparently expects. I've been wondering whether that isn't some kind of FE bug and whether there isn't some unwritten rule that second operand of TRY_CATCH_EXPR must be a STATEMENT_LIST, but then I tried --- gcc/gimplify.cc 2023-07-19 14:23:42.409875238 +0200 +++ gcc/gimplify.cc 2023-11-22 11:07:50.511000206 +0100 @@ -16730,6 +16730,10 @@ gimplify_expr (tree *expr_p, gimple_seq Note that this only affects the destructor calls in FINALLY/CATCH block, and will automatically reset to its original value by the end of gimplify_expr. */ + if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR + && TREE_OPERAND (*expr_p, 1) + && TREE_CODE (TREE_OPERAND (*expr_p, 1)) != STATEMENT_LIST) + gcc_unreachable (); input_location = UNKNOWN_LOCATION; eval = cleanup = NULL; gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval); hack in gcc 13 and triggered on hundreds of tests there within just 5 seconds of running make check-g++ -j32 (and in cases I looked at had nothing to do with the r14-5086 backports), so I believe this is just bad assumption on the try_catch_may_fallthru side, gimplify.cc certainly doesn't care, it just calls gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup); on it. So, IMHO non-STATEMENT_LIST in the second operand is equivalent to a STATEMENT_LIST containing a single statement.
Unfortunately, I don't see an easy way to create an artificial tree iterator from just a single tree statement, so the patch duplicates what the loops later do (after all, it is very simple, just didn't want to duplicate also the large comments explaning it, so the 3 See below. comments). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Shall it go to branches as well given that r14-5086 has been backported to those branches as well? 2023-11-22 Jakub Jelinek <ja...@redhat.com> PR c++/112619 * tree.cc (try_catch_may_fallthru): If second operand of TRY_CATCH_EXPR is not a STATEMENT_LIST, handle it as if it was a STATEMENT_LIST containing a single statement. * g++.dg/eh/pr112619.C: New test. --- gcc/tree.cc.jj 2023-11-14 09:24:28.436530018 +0100 +++ gcc/tree.cc 2023-11-21 19:19:19.384347469 +0100 @@ -12573,6 +12573,24 @@ try_catch_may_fallthru (const_tree stmt) if (block_may_fallthru (TREE_OPERAND (stmt, 0))) return true; + switch (TREE_CODE (TREE_OPERAND (stmt, 1))) + { + case CATCH_EXPR: + /* See below. */ + return block_may_fallthru (CATCH_BODY (TREE_OPERAND (stmt, 1))); + + case EH_FILTER_EXPR: + /* See below. */ + return block_may_fallthru (EH_FILTER_FAILURE (TREE_OPERAND (stmt, 1))); + + case STATEMENT_LIST: + break; + + default: + /* See below. */ + return false; + } + i = tsi_start (TREE_OPERAND (stmt, 1)); switch (TREE_CODE (tsi_stmt (i))) { --- gcc/testsuite/g++.dg/eh/pr112619.C.jj 2023-11-21 19:22:47.437439283 +0100 +++ gcc/testsuite/g++.dg/eh/pr112619.C 2023-11-21 19:22:24.887754376 +0100 @@ -0,0 +1,15 @@ +// PR c++/112619 +// { dg-do compile } + +struct S { S (); ~S (); }; + +S +foo (int a, int b) +{ + if (a || b) + { + S s; + return s; + } + return S (); +} Jakub