On Wed, Mar 11, 2020 at 04:02:51PM -0400, Jason Merrill via Gcc-patches wrote: > We should certainly avoid copying if they're the same. The code above for > only copying the bits that aren't going to be thrown away seems pretty > straightforward, might as well use it even if the savings aren't likely to > be large.
So like this if it passes bootstrap/regtest? Calling vec_safe_truncate with the same number of elts the vector already has is a nop, so IMHO we just should make sure we only unshare if it changed. 2020-03-11 Jakub Jelinek <ja...@redhat.com> PR c++/94124 * decl.c (reshape_init_array_1): Don't unshare constructor if there aren't any trailing zero elts, otherwise only unshare the first nelts. --- gcc/cp/decl.c.jj 2020-03-11 09:28:53.966213943 +0100 +++ gcc/cp/decl.c 2020-03-11 23:19:08.832780798 +0100 @@ -6066,10 +6066,22 @@ reshape_init_array_1 (tree elt_type, tre overload resolution. E.g., initializing a class from {{0}} might be invalid while initializing the same class from {{}} might be valid. */ - if (reuse) - new_init = unshare_constructor (new_init); - - vec_safe_truncate (CONSTRUCTOR_ELTS (new_init), nelts); + if (reuse && nelts < CONSTRUCTOR_NELTS (new_init)) + { + vec<constructor_elt, va_gc> *v = NULL; + if (nelts) + vec_alloc (v, nelts); + for (unsigned int i = 0; i < nelts; i++) + { + constructor_elt elt = *CONSTRUCTOR_ELT (new_init, i); + if (TREE_CODE (elt.value) == CONSTRUCTOR) + elt.value = unshare_constructor (elt.value); + v->quick_push (elt); + } + new_init = build_constructor (TREE_TYPE (new_init), v); + } + else + vec_safe_truncate (CONSTRUCTOR_ELTS (new_init), nelts); } return new_init; Jakub