On Wed, 15 May 2024, Patrick Palka wrote: > > On Fri, 10 May 2024, Seyed Sajad Kahani wrote: > > > This patch resolves PR114915 by replacing the logic that fills in the > > missing levels in do_auto_deduction in cp/pt.cc. > > The new approach now trims targs if the depth of targs is deeper than > > desired (this will only happen in specific contexts), and still fills targs > > with empty layers if it has fewer depths than expected. > > The logic looks good to me, thanks! Note that as per > https://gcc.gnu.org/contribute.html patches need a ChangeLog entry in > the commit message, for example let's use: > > PR c++/114915 > > gcc/cp/ChangeLog: > > * pt.cc (do_auto_deduction): Handle excess outer template > arguments during constrained auto satisfaction. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/concepts-placeholder14.C: New test. > * g++.dg/cpp2a/concepts-placeholder15.C: New test. > * g++.dg/cpp2a/concepts-placeholder16.C: New test. > > Jason, what do you think?
... now sent to the correct email, sorry for the spam > > > --- > > gcc/cp/pt.cc | 20 ++++++++--- > > .../g++.dg/cpp2a/concepts-placeholder14.C | 19 +++++++++++ > > .../g++.dg/cpp2a/concepts-placeholder15.C | 15 +++++++++ > > .../g++.dg/cpp2a/concepts-placeholder16.C | 33 +++++++++++++++++++ > > 4 files changed, 83 insertions(+), 4 deletions(-) > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C > > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > index 3b2106dd3..479b2a5bd 100644 > > --- a/gcc/cp/pt.cc > > +++ b/gcc/cp/pt.cc > > @@ -31253,6 +31253,19 @@ do_auto_deduction (tree type, tree init, tree > > auto_node, > > full_targs = add_outermost_template_args (tmpl, full_targs); > > full_targs = add_to_template_args (full_targs, targs); > > > > + int want = TEMPLATE_TYPE_ORIG_LEVEL (auto_node); > > + int have = TMPL_ARGS_DEPTH (full_targs); > > + > > + if (want < have) > > + { > > + // if a constrained auto is declared in an explicit specialization > > + gcc_assert (context == adc_variable_type || context == adc_return_type > > + || context == adc_decomp_type); > > + tree trimmed_full_args = get_innermost_template_args > > + (full_targs, want); > > + full_targs = trimmed_full_args; > > + } > > + > > /* HACK: Compensate for callers not always communicating all levels > > of > > outer template arguments by filling in the outermost missing levels > > with dummy levels before checking satisfaction. We'll still crash > > @@ -31260,11 +31273,10 @@ do_auto_deduction (tree type, tree init, tree > > auto_node, > > these missing levels, but this hack otherwise allows us to handle a > > large subset of possible constraints (including all non-dependent > > constraints). */ > > - if (int missing_levels = (TEMPLATE_TYPE_ORIG_LEVEL (auto_node) > > - - TMPL_ARGS_DEPTH (full_targs))) > > + if (want > have) > > { > > - tree dummy_levels = make_tree_vec (missing_levels); > > - for (int i = 0; i < missing_levels; ++i) > > + tree dummy_levels = make_tree_vec (want - have); > > + for (int i = 0; i < want - have; ++i) > > TREE_VEC_ELT (dummy_levels, i) = make_tree_vec (0); > > full_targs = add_to_template_args (dummy_levels, full_targs); > > } > > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C > > b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C > > new file mode 100644 > > index 000000000..fcdbd7608 > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder14.C > > @@ -0,0 +1,19 @@ > > +// PR c++/114915 > > +// { dg-do compile { target c++20 } } > > + > > +template<typename T> > > +concept C = __is_same(T, int); > > + > > +template<typename T> > > +void f() { > > +} > > + > > +template<> > > +void f<int>() { > > + C auto x = 1; > > +} > > + > > +int main() { > > + f<int>(); > > + return 0; > > +} > > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C > > b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C > > new file mode 100644 > > index 000000000..b4f73f407 > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder15.C > > @@ -0,0 +1,15 @@ > > +// PR c++/114915 > > +// { dg-do compile { target c++20 } } > > + > > +template<typename T, typename U> > > +concept C = __is_same(T, U); > > + > > +template<typename T> > > +int x = 0; > > + > > +template<> > > +C<double> auto x<double> = 1.0; > > + > > +int main() { > > + return 0; > > +} > > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C > > b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C > > new file mode 100644 > > index 000000000..f808ef1b6 > > --- /dev/null > > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder16.C > > @@ -0,0 +1,33 @@ > > +// PR c++/114915 > > +// { dg-do compile { target c++20 } } > > + > > +template<typename T, typename U> > > +concept C = __is_same(T, U); > > + > > +template<typename T> > > +struct A > > +{ > > + template<typename U> > > + void f() { > > + } > > +}; > > + > > +template<> > > +template<> > > +void A<int>::f<int>() { > > + C<int> auto x = 1; > > +} > > + > > +template<> > > +template<typename U> > > +void A<bool>::f() { > > + C<int> auto x = 1; > > +} > > + > > +int main() { > > + A<bool> a; > > + a.f<char>(); > > + A<int> b; > > + b.f<int>(); > > + return 0; > > +} > > -- > > 2.45.0 > > > > >