diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 3fc8835154d..a139b293e00 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8028,11 +8028,11 @@ wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data) Unfortunately, there's no way to express this properly in terms of nesting, as the regions for the temporaries overlap the region for the variable itself; if there are two temporaries, the variable needs to be - the first thing destroyed if either of them throws. However, we only - want to run the variable's cleanup if it actually got constructed. So - we need to guard the temporary cleanups with the variable's cleanup if - they are run on the normal path, but not if they are run on the - exceptional path. We implement this by telling + the first thing destroyed if either of the temporary destructors throws. + However, we only want to run the variable's cleanup if it actually got + constructed. So we need to guard the temporary cleanups with the + variable's cleanup if they are run on the normal path, but not if they + are run on the exceptional path. We implement this by telling honor_protect_cleanup_actions to strip the variable cleanup from the exceptional path. diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index 7bb98f445c3..906e401974c 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -4685,8 +4685,14 @@ build_vec_init (tree base, tree maxindex, tree init, for any temporaries in the initialization are naturally within our cleanup region, so we don't want wrap_temporary_cleanups to do anything for arrays. But if the array is a subobject, we need to - tell split_nonconstant_init how to turn off this cleanup in favor of - the cleanup for the complete object. */ + tell split_nonconstant_init or cp_genericize_target_expr how to turn + off this cleanup in favor of the cleanup for the complete object. + + ??? For an array temporary such as an initializer_list backing array, + it would avoid redundancy to leave this cleanup active, clear + CLEANUP_EH_ONLY, and not build another cleanup for the temporary + itself. But that breaks when gimplify_target_expr adds a clobber + cleanup that runs before the build_vec_init cleanup. */ if (cleanup_flags) vec_safe_push (*cleanup_flags, build_tree_list (iterator, maxindex)); }