This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH for c++/85883, class tmpl args deduction fail with new
- From: Jason Merrill <jason at redhat dot com>
- To: Marek Polacek <polacek at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 29 May 2018 13:01:14 -0400
- Subject: Re: C++ PATCH for c++/85883, class tmpl args deduction fail with new
- References: <20180524201010.GB3559@redhat.com> <CADzB+2=QXtcc0k=gi760EN7k0Stc2tVe4m7+=AS9jN4YgaJCjw@mail.gmail.com> <20180529155508.GG3559@redhat.com>
OK.
On Tue, May 29, 2018 at 11:55 AM, Marek Polacek <polacek@redhat.com> wrote:
> On Fri, May 25, 2018 at 01:58:53PM -0400, Jason Merrill wrote:
>> > + /* 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.
>
> Good point. Fixed here:
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2018-05-29 Marek Polacek <polacek@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..da80e07f65b 100644
> --- gcc/cp/init.c
> +++ gcc/cp/init.c
> @@ -3585,11 +3585,27 @@ 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;
> + tree *pp = &d_init;
> + FOR_EACH_VEC_ELT (**init, n, t)
> + {
> + t = resolve_nondeduced_context (t, complain);
> + *pp = build_tree_list (NULL_TREE, t);
> + pp = &TREE_CHAIN (*pp);
> + }
> + }
> type = do_auto_deduction (type, d_init, auto_node, complain);
> }
> }
> diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction55.C gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
> index e69de29bb2d..a93d7203681 100644
> --- gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
> +++ gcc/testsuite/g++.dg/cpp1z/class-deduction55.C
> @@ -0,0 +1,15 @@
> +// PR c++/85883
> +// { dg-options -std=c++17 }
> +
> +template <typename T>
> +struct Bar
> +{
> + Bar(T) { }
> +};
> +
> +int
> +main ()
> +{
> + auto x = Bar(1);
> + auto y = new Bar(3);
> +}
> diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction56.C gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
> index e69de29bb2d..71dbfa1904d 100644
> --- gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
> +++ gcc/testsuite/g++.dg/cpp1z/class-deduction56.C
> @@ -0,0 +1,15 @@
> +// PR c++/85883
> +// { dg-options -std=c++17 }
> +
> +template <typename T1, typename T2>
> +struct Bar
> +{
> + Bar(T1, T2) { }
> +};
> +
> +int
> +main ()
> +{
> + auto x = Bar(1, 2);
> + auto y = new Bar(3, 4);
> +}
> diff --git gcc/testsuite/g++.dg/cpp1z/class-deduction57.C gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
> index e69de29bb2d..200ba6c3536 100644
> --- gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
> +++ gcc/testsuite/g++.dg/cpp1z/class-deduction57.C
> @@ -0,0 +1,15 @@
> +// PR c++/85883
> +// { dg-options -std=c++17 }
> +
> +template <typename T1, typename T2, typename T3>
> +struct Bar
> +{
> + Bar(T1, T2, T3) { }
> +};
> +
> +int
> +main ()
> +{
> + auto x = Bar(1, 2, 3);
> + auto y = new Bar(3, 4, 5);
> +}