On Tue, Jan 21, 2025 at 05:35:02PM +0100, Jakub Jelinek wrote: > On Tue, Jan 21, 2025 at 05:15:17PM +0100, Jakub Jelinek wrote: > > On Tue, Jan 21, 2025 at 11:06:35AM -0500, Jason Merrill wrote: > > > > --- gcc/c-family/c-common.cc.jj 2025-01-20 18:00:35.667875671 +0100 > > > > +++ gcc/c-family/c-common.cc 2025-01-21 09:29:23.955582581 +0100 > > > > @@ -9010,33 +9010,46 @@ make_tree_vector_from_list (tree list) > > > > return ret; > > > > } > > > > -/* Get a new tree vector of the values of a CONSTRUCTOR. */ > > > > +/* Append to a tree vector the values of a CONSTRUCTOR. > > > > + nelts should be at least CONSTRUCTOR_NELTS (ctor) and v > > > > + should be initialized with make_tree_vector (); followed by > > > > + vec_safe_reserve (v, nelts); or equivalently vec_alloc (v, nelts); > > > > + optionally followed by pushes of other elements (up to > > > > + nelts - CONSTRUCTOR_NELTS (ctor)). */ > > > > > > How about using v->allocated () instead of passing in nelts? > > > > That is not necessarily the same. > > Both vec_safe_reserve (v, nelts) and vec_alloc (v, nelts); actually > > use exact=false, so they can allocate something larger (doesn't hurt > > e.g. if RAW_DATA_CST is small enough and fits), but if it used v->allocated > > (), it could overallocate from the overallocated size. > > So, e.g. even if nelts + RAW_DATA_LENGTH (x) - 1 <= v->allocated () - > > v->length () > > and thus we could just use a vector without reallocating, > > v->allocated () + RAW_DATA_LENGTH (x) - 1 could be too much. > > On the other side, if one uses v = vec_alloc (v, nelts) then v->allocated () > is guaranteed to be MAX (4, nelts) and if one uses v = make_tree_vector (); > vec_safe_reserve (v, nelts); then v->allocated () will be I think at most > MAX (24, nelts). > So perhaps not that big deal (at least if the function inside of it uses > unsigned nelts = v->allocated (); and then uses nelts rather than > v->allocated () in the loop. Unless some new caller of the function uses > a vector reallocated more times.
So, if you prefer that, here is the variant patch, so far lightly tested - GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 make check-g++ RUNTESTFLAGS="dg.exp='embed* pr118532.C explicit20.C class-deduction-aggr16.C'" can do full bootstrap/regtest tonight. 2025-01-21 Jakub Jelinek <ja...@redhat.com> gcc/c-family/ * c-common.h (append_ctor_to_tree_vector): Declare. * c-common.cc (append_ctor_to_tree_vector): New function. (make_tree_vector_from_ctor): Use it. gcc/cp/ * call.cc (add_list_candidates): Use append_ctor_to_tree_vector. --- gcc/c-family/c-common.h.jj 2025-01-17 11:29:33.139696380 +0100 +++ gcc/c-family/c-common.h 2025-01-21 09:30:09.520947570 +0100 @@ -1190,6 +1190,8 @@ extern vec<tree, va_gc> *make_tree_vecto extern void release_tree_vector (vec<tree, va_gc> *); extern vec<tree, va_gc> *make_tree_vector_single (tree); extern vec<tree, va_gc> *make_tree_vector_from_list (tree); +extern vec<tree, va_gc> *append_ctor_to_tree_vector (vec<tree, va_gc> *, + tree); extern vec<tree, va_gc> *make_tree_vector_from_ctor (tree); extern vec<tree, va_gc> *make_tree_vector_copy (const vec<tree, va_gc> *); --- gcc/c-family/c-common.cc.jj 2025-01-20 18:00:35.667875671 +0100 +++ gcc/c-family/c-common.cc 2025-01-21 09:29:23.955582581 +0100 @@ -9010,33 +9010,45 @@ make_tree_vector_from_list (tree list) return ret; } -/* Get a new tree vector of the values of a CONSTRUCTOR. */ +/* Append to a tree vector the values of a CONSTRUCTOR. + v should be initialized with make_tree_vector (); followed by + vec_safe_reserve (v, nelts); or equivalently vec_alloc (v, nelts); + optionally followed by pushes of other elements (up to + nelts - CONSTRUCTOR_NELTS (ctor)). */ vec<tree, va_gc> * -make_tree_vector_from_ctor (tree ctor) +append_ctor_to_tree_vector (vec<tree, va_gc> *v, tree ctor) { - vec<tree,va_gc> *ret = make_tree_vector (); - unsigned nelts = CONSTRUCTOR_NELTS (ctor); - vec_safe_reserve (ret, CONSTRUCTOR_NELTS (ctor)); + unsigned nelts = v->allocated (); for (unsigned i = 0; i < CONSTRUCTOR_NELTS (ctor); ++i) if (TREE_CODE (CONSTRUCTOR_ELT (ctor, i)->value) == RAW_DATA_CST) { tree raw_data = CONSTRUCTOR_ELT (ctor, i)->value; nelts += RAW_DATA_LENGTH (raw_data) - 1; - vec_safe_reserve (ret, nelts - ret->length ()); + vec_safe_reserve (v, nelts - v->length ()); if (TYPE_PRECISION (TREE_TYPE (raw_data)) > CHAR_BIT || TYPE_UNSIGNED (TREE_TYPE (raw_data))) for (unsigned j = 0; j < (unsigned) RAW_DATA_LENGTH (raw_data); ++j) - ret->quick_push (build_int_cst (TREE_TYPE (raw_data), - RAW_DATA_UCHAR_ELT (raw_data, j))); + v->quick_push (build_int_cst (TREE_TYPE (raw_data), + RAW_DATA_UCHAR_ELT (raw_data, j))); else for (unsigned j = 0; j < (unsigned) RAW_DATA_LENGTH (raw_data); ++j) - ret->quick_push (build_int_cst (TREE_TYPE (raw_data), - RAW_DATA_SCHAR_ELT (raw_data, j))); + v->quick_push (build_int_cst (TREE_TYPE (raw_data), + RAW_DATA_SCHAR_ELT (raw_data, j))); } else - ret->quick_push (CONSTRUCTOR_ELT (ctor, i)->value); - return ret; + v->quick_push (CONSTRUCTOR_ELT (ctor, i)->value); + return v; +} + +/* Get a new tree vector of the values of a CONSTRUCTOR. */ + +vec<tree, va_gc> * +make_tree_vector_from_ctor (tree ctor) +{ + vec<tree,va_gc> *ret = make_tree_vector (); + vec_safe_reserve (ret, CONSTRUCTOR_NELTS (ctor)); + return append_ctor_to_tree_vector (ret, ctor); } /* Get a new tree vector which is a copy of an existing one. */ --- gcc/cp/call.cc.jj 2025-01-21 09:11:58.214113697 +0100 +++ gcc/cp/call.cc 2025-01-21 19:13:01.568407526 +0100 @@ -4258,30 +4258,10 @@ add_list_candidates (tree fns, tree firs /* Expand the CONSTRUCTOR into a new argument vec. */ vec<tree, va_gc> *new_args; - unsigned nelts = nart + CONSTRUCTOR_NELTS (init_list); - vec_alloc (new_args, nelts); + vec_alloc (new_args, nart + CONSTRUCTOR_NELTS (init_list)); for (unsigned i = 0; i < nart; ++i) new_args->quick_push ((*args)[i]); - for (unsigned i = 0; i < CONSTRUCTOR_NELTS (init_list); ++i) - if (TREE_CODE (CONSTRUCTOR_ELT (init_list, i)->value) == RAW_DATA_CST) - { - tree raw_data = CONSTRUCTOR_ELT (init_list, i)->value; - nelts += RAW_DATA_LENGTH (raw_data) - 1; - vec_safe_reserve (new_args, nelts - new_args->length ()); - if (TYPE_PRECISION (TREE_TYPE (raw_data)) > CHAR_BIT - || TYPE_UNSIGNED (TREE_TYPE (raw_data))) - for (unsigned j = 0; j < (unsigned) RAW_DATA_LENGTH (raw_data); ++j) - new_args->quick_push (build_int_cst (TREE_TYPE (raw_data), - RAW_DATA_UCHAR_ELT (raw_data, - j))); - else - for (unsigned j = 0; j < (unsigned) RAW_DATA_LENGTH (raw_data); ++j) - new_args->quick_push (build_int_cst (TREE_TYPE (raw_data), - RAW_DATA_SCHAR_ELT (raw_data, - j))); - } - else - new_args->quick_push (CONSTRUCTOR_ELT (init_list, i)->value); + new_args = append_ctor_to_tree_vector (new_args, init_list); /* We aren't looking for list-ctors anymore. */ flags &= ~LOOKUP_LIST_ONLY; Jakub