On Wed, 2024-05-22 at 16:30 -0400, Jason Merrill wrote:
> OK, on the right patch this time I hope.
>
> Looks like you still need either FSF copyright assignment or DCO
> certification per https://gcc.gnu.org/contribute.html#legal
>
Hi. Thanks for your patience. I now have the FSF copyright assignment.
> On 5/15/24 13:27, 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.
>
> I miss the text in your original patch that explained the problem
> more.
>
The patch that I will send in the upcoming email contains the
explanation from the v1 patch as well.
> > 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.
> >
> > PR c++/114915
>
> This line needs to start with a tab.
>
> > gcc/cp/ChangeLog:
> >
> > * pt.cc (do_auto_deduction): Handle excess outer template
> > arguments during constrained auto satisfaction.
>
> This one, too. These issues are flagged by git gcc-verify, and are
> easier to avoid with git gcc-commit-mklog.
>
Thanks for guiding me. The commit is now verified.
> > gcc/testsuite/ChangeLog:
> >
> > * g++.dg/cpp2a/concepts-placeholder14.C: New test.
> > * g++.dg/cpp2a/concepts-placeholder15.C: New test.
>
> This test still needs a variable template partial specialization.
>
Regarding this, I have added a simple variable template parameter
specialization to the test, but due to PR c++/115030, which I will be
working on right after this patch, a more complex test will fail.
> A few coding style nits below.
>
> > * g++.dg/cpp2a/concepts-placeholder16.C: New test.
> > ---
> > 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 32640f8e9..ecfda67aa 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
>
> We generally use C-style /* */ comments, that start with a capital
> letter and end with a period.
>
> > + gcc_assert (context == adc_variable_type || context ==
> > adc_return_type
> > + || context == adc_decomp_type);
>
> The || should line up with the 'c' on the previous line.
>
> > + tree trimmed_full_args = get_innermost_template_args
> > + (full_targs, want);
>
> We try to avoid having arguments to the left of the function name;
> here
> I'd start the new line with the = instead.
>
> > + full_targs = trimmed_full_args;
> > + }
> > +
>
> Unnecessary tab on this line.
>
> > /* 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;
> > +}
>
Thank you so much for your comments. They are all fixed now.