On Wed, Nov 22, 2023 at 01:06:28PM +0100, Jakub Jelinek wrote: > Looking at a trivial example > void bar (); > void > foo (void) > { > try { bar (); } catch (int) {} > } > it seems it is even more complicated, because what e.g. the gimplification > sees is not TRY_CATCH_EXPR with CATCH_EXPR second operand, but > TRY_BLOCK with HANDLER second operand (note, certainly not wrapped in a > STATEMENT_LIST, one would need another catch (long) {} for it after it), > C++ FE specific trees. > And cp_gimplify_expr then on the fly turns the TRY_BLOCK into TRY_CATCH_EXPR > (in genericize_try_block) and HANDLER into CATCH_EXPR > (genericize_catch_block). > When gimplifying EH_SPEC_BLOCK in genericize_eh_spec_block it even > creates TRY_CATCH_EXPR with genericize_eh_spec_block -> > build_gimple_eh_filter_tree > if even creates TRY_CATCH_EXPR with EH_FILTER_EXPR as its second operand > (without intervening STATEMENT_LIST).
Ah, and the difference between the above where TRY_BLOCK is turned into TRY_CATCH_EXPR and HANDLER into CATCH_EXPR vs. the ICE on the testcase from the PR is that in that case it isn't TRY_BLOCK, but CLEANUP_STMT which is not changed during gimplification but already during cp generication. So, pedantically perhaps just assuming TRY_CATCH_EXPR where second argument is not STATEMENT_LIST to be the CATCH_EXPR/EH_FILTER_EXPR case could work for C++, but there are other FEs and it would be fragile (and weird, given that STATEMENT_LIST with single stmt in it vs. that stmt ought to be generally interchangeable). Plus of course question whether we want to handle TRY_BLOCK/EH_SPEC_BLOCK in cxx_block_may_fallthru in addition to that remains (it apparently already handles CLEANUP_STMT, but strangely just the try/finally special case of it - I'd assume the CLEANUP_EH_ONLY case would be (block_may_fallthru (CLEANUP_BODY (stmt)) || block_may_fallthru (CLEANUP_EXPR (stmt))) because if the body can fallthru, everything can, and if there is an exception and cleanup can fallthru, then it could fallthru as well). Jakub