https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103984
--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Wonder about: --- gcc/gimplify.cc.jj 2022-03-04 15:14:53.197812540 +0100 +++ gcc/gimplify.cc 2022-03-15 17:44:45.110734179 +0100 @@ -6997,8 +6997,6 @@ gimplify_target_expr (tree *expr_p, gimp if (init) { - tree cleanup = NULL_TREE; - /* TARGET_EXPR temps aren't part of the enclosing block, so add it to the temps list. Handle also variable length TARGET_EXPRs. */ if (!poly_int_tree_p (DECL_SIZE (temp))) @@ -7019,37 +7017,6 @@ gimplify_target_expr (tree *expr_p, gimp gimple_add_tmp_var (temp); } - /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the - expression is supposed to initialize the slot. */ - if (VOID_TYPE_P (TREE_TYPE (init))) - ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); - else - { - tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init); - init = init_expr; - ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); - init = NULL; - ggc_free (init_expr); - } - if (ret == GS_ERROR) - { - /* PR c++/28266 Make sure this is expanded only once. */ - TARGET_EXPR_INITIAL (targ) = NULL_TREE; - return GS_ERROR; - } - if (init) - gimplify_and_add (init, pre_p); - - /* If needed, push the cleanup for the temp. */ - if (TARGET_EXPR_CLEANUP (targ)) - { - if (CLEANUP_EH_ONLY (targ)) - gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), - CLEANUP_EH_ONLY (targ), pre_p); - else - cleanup = TARGET_EXPR_CLEANUP (targ); - } - /* Add a clobber for the temporary going out of scope, like gimplify_bind_expr. */ if (gimplify_ctxp->in_cleanup_point_expr @@ -7079,8 +7046,32 @@ gimplify_target_expr (tree *expr_p, gimp } } } - if (cleanup) - gimple_push_cleanup (temp, cleanup, false, pre_p); + + /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the + expression is supposed to initialize the slot. */ + if (VOID_TYPE_P (TREE_TYPE (init))) + ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); + else + { + tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init); + init = init_expr; + ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none); + init = NULL; + ggc_free (init_expr); + } + if (ret == GS_ERROR) + { + /* PR c++/28266 Make sure this is expanded only once. */ + TARGET_EXPR_INITIAL (targ) = NULL_TREE; + return GS_ERROR; + } + if (init) + gimplify_and_add (init, pre_p); + + /* If needed, push the cleanup for the temp. */ + if (TARGET_EXPR_CLEANUP (targ)) + gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ), + CLEANUP_EH_ONLY (targ), pre_p); /* Only expand this once. */ TREE_OPERAND (targ, 3) = init; i.e. emitting the clobber gimple_push_cleanup for the TARGET_EXPRs before the gimplification of the TARGET_EXPR_INITIAL instead of after it (and emitting the WCE earlier means the cleanup is later (as in, outer try/finally).