Message ID | 20220131160728.1761950-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: CTAD for class tmpl defined inside partial spec [PR104294] | expand |
On Mon, Jan 31, 2022 at 11:07 AM Patrick Palka <ppalka@redhat.com> wrote: > > Here during deduction guide generation for the nested class template > B<char(int)>::C, the computation of outer_targs yields the template > arguments relative to the primary template for B (i.e. {char(int)}) > but what we really what is those relative to the enclosing scope, the > partial specialization of B (i.e. {char, int}). > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk? > > PR c++/104294 > > gcc/cp/ChangeLog: > > * pt.cc (ctor_deduction_guides_for): Correct computation of > outer_targs. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp1z/class-deduction106.C: New test. > --- > gcc/cp/pt.cc | 4 +++- > .../g++.dg/cpp1z/class-deduction106.C | 19 +++++++++++++++++++ > 2 files changed, 22 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction106.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index f46a7ad6655..0fe0ad4e44e 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -29568,7 +29568,9 @@ ctor_deduction_guides_for (tree tmpl, tsubst_flags_t complain) > if (DECL_CLASS_SCOPE_P (tmpl) > && CLASSTYPE_TEMPLATE_INSTANTIATION (DECL_CONTEXT (tmpl))) > { > - outer_args = CLASSTYPE_TI_ARGS (DECL_CONTEXT (tmpl)); > + outer_args = copy_node (CLASSTYPE_TI_ARGS (type)); > + gcc_assert (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (outer_args)); Whoops, this assert should be slightly stronger: TMPL_ARGS_DEPTH (outer_args) > 1. Consider that fixed (pending another bootstrap/regtest cycle). > + --TREE_VEC_LENGTH (outer_args); > type = TREE_TYPE (most_general_template (tmpl)); > } > > diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C > new file mode 100644 > index 00000000000..382f6b70ef5 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C > @@ -0,0 +1,19 @@ > +// PR c++/104294 > +// { dg-do compile { target c++17 } } > + > +template<class> > +struct B; > + > +template <class R, class... Args> > +struct B<R(Args...)> { > + template<class T> > + struct C { C(T); }; > + > + C(decltype(nullptr)) -> C<void*>; > +}; > + > +using ty1 = decltype(B<char(int)>::C{0}); > +using ty1 = B<char(int)>::C<int>; > + > +using ty2 = decltype(B<char(int)>::C{nullptr}); > +using ty2 = B<char(int)>::C<void*>; > -- > 2.35.0 >
On 1/31/22 11:14, Patrick Palka wrote: > On Mon, Jan 31, 2022 at 11:07 AM Patrick Palka <ppalka@redhat.com> wrote: >> >> Here during deduction guide generation for the nested class template >> B<char(int)>::C, the computation of outer_targs yields the template >> arguments relative to the primary template for B (i.e. {char(int)}) >> but what we really what is those relative to the enclosing scope, the >> partial specialization of B (i.e. {char, int}). >> >> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for >> trunk? >> >> PR c++/104294 >> >> gcc/cp/ChangeLog: >> >> * pt.cc (ctor_deduction_guides_for): Correct computation of >> outer_targs. >> >> gcc/testsuite/ChangeLog: >> >> * g++.dg/cpp1z/class-deduction106.C: New test. >> --- >> gcc/cp/pt.cc | 4 +++- >> .../g++.dg/cpp1z/class-deduction106.C | 19 +++++++++++++++++++ >> 2 files changed, 22 insertions(+), 1 deletion(-) >> create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction106.C >> >> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc >> index f46a7ad6655..0fe0ad4e44e 100644 >> --- a/gcc/cp/pt.cc >> +++ b/gcc/cp/pt.cc >> @@ -29568,7 +29568,9 @@ ctor_deduction_guides_for (tree tmpl, tsubst_flags_t complain) >> if (DECL_CLASS_SCOPE_P (tmpl) >> && CLASSTYPE_TEMPLATE_INSTANTIATION (DECL_CONTEXT (tmpl))) >> { >> - outer_args = CLASSTYPE_TI_ARGS (DECL_CONTEXT (tmpl)); >> + outer_args = copy_node (CLASSTYPE_TI_ARGS (type)); >> + gcc_assert (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (outer_args)); > > Whoops, this assert should be slightly stronger: TMPL_ARGS_DEPTH > (outer_args) > 1. Consider that fixed (pending another > bootstrap/regtest cycle). OK. >> + --TREE_VEC_LENGTH (outer_args); >> type = TREE_TYPE (most_general_template (tmpl)); >> } >> >> diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C >> new file mode 100644 >> index 00000000000..382f6b70ef5 >> --- /dev/null >> +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C >> @@ -0,0 +1,19 @@ >> +// PR c++/104294 >> +// { dg-do compile { target c++17 } } >> + >> +template<class> >> +struct B; >> + >> +template <class R, class... Args> >> +struct B<R(Args...)> { >> + template<class T> >> + struct C { C(T); }; >> + >> + C(decltype(nullptr)) -> C<void*>; >> +}; >> + >> +using ty1 = decltype(B<char(int)>::C{0}); >> +using ty1 = B<char(int)>::C<int>; >> + >> +using ty2 = decltype(B<char(int)>::C{nullptr}); >> +using ty2 = B<char(int)>::C<void*>; >> -- >> 2.35.0 >> >
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index f46a7ad6655..0fe0ad4e44e 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -29568,7 +29568,9 @@ ctor_deduction_guides_for (tree tmpl, tsubst_flags_t complain) if (DECL_CLASS_SCOPE_P (tmpl) && CLASSTYPE_TEMPLATE_INSTANTIATION (DECL_CONTEXT (tmpl))) { - outer_args = CLASSTYPE_TI_ARGS (DECL_CONTEXT (tmpl)); + outer_args = copy_node (CLASSTYPE_TI_ARGS (type)); + gcc_assert (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (outer_args)); + --TREE_VEC_LENGTH (outer_args); type = TREE_TYPE (most_general_template (tmpl)); } diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C new file mode 100644 index 00000000000..382f6b70ef5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction106.C @@ -0,0 +1,19 @@ +// PR c++/104294 +// { dg-do compile { target c++17 } } + +template<class> +struct B; + +template <class R, class... Args> +struct B<R(Args...)> { + template<class T> + struct C { C(T); }; + + C(decltype(nullptr)) -> C<void*>; +}; + +using ty1 = decltype(B<char(int)>::C{0}); +using ty1 = B<char(int)>::C<int>; + +using ty2 = decltype(B<char(int)>::C{nullptr}); +using ty2 = B<char(int)>::C<void*>;