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

Reply via email to