On Thu, May 24, 2018 at 4:10 PM, Marek Polacek <pola...@redhat.com> wrote: > Here we were failing to deduce template arguments for a class, because the > code in build_new only handled the case when INIT had 1 element. That works > for e.g. new auto (foo) or new Foo{1, 2}, but not new Foo(1, 2). I noticed > that it works without "new" because we simply create a tree list of the > arguments and pass it down to do_auto_deduction (in build_functional_cast). > do_class_deduction is prepared to receive a tree list. > > (Sorry if this is totally bogus.) > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2018-05-24 Marek Polacek <pola...@redhat.com> > > PR c++/85883 > * init.c (build_new): Handle deducing a class with new > with more than one argument. > > * g++.dg/cpp1z/class-deduction55.C: New test. > * g++.dg/cpp1z/class-deduction56.C: New test. > * g++.dg/cpp1z/class-deduction57.C: New test. > > diff --git gcc/cp/init.c gcc/cp/init.c > index 3f1e49bae21..3b175f94ecb 100644 > --- gcc/cp/init.c > +++ gcc/cp/init.c > @@ -3585,11 +3585,25 @@ build_new (vec<tree, va_gc> **placement, tree type, > tree nelts, > if (auto_node) > { > tree d_init = NULL_TREE; > - if (vec_safe_length (*init) == 1) > + const size_t len = vec_safe_length (*init); > + /* E.g. new auto(x) must have exactly one element, or > + a {} initializer will have one element. */ > + if (len == 1) > { > d_init = (**init)[0]; > d_init = resolve_nondeduced_context (d_init, complain); > } > + /* For the rest, e.g. new A(1, 2, 3), create a list. */ > + else if (len > 1) > + { > + unsigned int n; > + tree t; > + FOR_EACH_VEC_ELT (**init, n, t) > + { > + t = resolve_nondeduced_context (t, complain); > + d_init = chainon (d_init, build_tree_list (NULL_TREE, t));
Using chainon here means that for each element, we have to walk the whole list to find the end. See build_tree_list_vec. Jason