On Thu, Dec 12, 2024 at 4:08 PM Patrick Palka <ppa...@redhat.com> wrote: > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > OK for trunk only? The original testcase from the PR seems to compile > successfully on the release branches so I'm avoiding doing anything on > the release branches for now.
Ping. > > -- >8 -- > > Ever since r15-3530-gdfb63765e994be the extra-args mechanism now expects > to see tf_partial whenever doing a partial substitution containing > dependent arguments. The below testcase shows that instantiate_template > for AT with args={T}/{T*}A is neglecting to set it in that case, and we > end up ICEing from add_extra_args during the subsequent full substitution. > This patch just fixes this by setting tf_partial appropriately. > > PR c++/117887 > > gcc/cp/ChangeLog: > > * pt.cc (instantiate_template): Set tf_partial if arguments are > dependent. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/concepts-requires39.C: New test. > * g++.dg/cpp2a/lambda-targ10.C: New test. > --- > gcc/cp/pt.cc | 15 ++++++++++++--- > .../g++.dg/cpp2a/concepts-requires39.C | 17 +++++++++++++++++ > gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C | 17 +++++++++++++++++ > 3 files changed, 46 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C > create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 2f2ec39b083..781590ab2e0 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -22272,7 +22272,11 @@ instantiate_template (tree tmpl, tree orig_args, > tsubst_flags_t complain) > substitution of a template variable, but the type of the variable > template may be auto, in which case we will call do_auto_deduction > in mark_used (which clears tf_partial) and the auto must be properly > - reduced at that time for the deduction to work. */ > + reduced at that time for the deduction to work. > + > + Note that later below we set tf_partial iff there are dependent > + arguments, but the above is concerned specifically about the > + non-dependent case. */ > complain &= tf_warning_or_error; > > gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); > @@ -22351,9 +22355,14 @@ instantiate_template (tree tmpl, tree orig_args, > tsubst_flags_t complain) > template, not the context of the overload resolution we're doing. */ > push_to_top_level (); > /* If there are dependent arguments, e.g. because we're doing partial > - ordering, make sure processing_template_decl stays set. */ > + ordering, make sure processing_template_decl stays set. And set > + tf_partial mainly for benefit of instantiation of alias templates > + that contain extra-args trees. */ > if (uses_template_parms (targ_ptr)) > - ++processing_template_decl; > + { > + ++processing_template_decl; > + complain |= tf_partial; > + } > if (DECL_CLASS_SCOPE_P (gen_tmpl)) > { > tree ctx; > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C > b/gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C > new file mode 100644 > index 00000000000..b13682033da > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C > @@ -0,0 +1,17 @@ > +// PR c++/117887 > +// { dg-do compile { target c++20 } } > + > +template<bool V> struct A { static constexpr bool value = V; }; > + > +template<class T> > +using AT = A<requires { requires sizeof(T) != sizeof(T*); }>; > + > +template<class T> struct B { using type = T; }; > + > +template<class T> > +void f() { > + static_assert( B<AT<T>>::type::value); > + static_assert(!B<AT<T*>>::type::value); > +} > + > +template void f<char>(); > diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C > b/gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C > new file mode 100644 > index 00000000000..7f175c93062 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C > @@ -0,0 +1,17 @@ > +// PR c++/117887 > +// { dg-do compile { target c++20 } } > + > +template<bool V, class T> struct A { static constexpr bool value = V; }; > + > +template<class T> > +using AT = A<[]{return sizeof(T) != sizeof(T*); }(), T>; > + > +template<class T> struct B { using type = T; }; > + > +template<class T> > +void f() { > + static_assert( B<AT<T>>::type::value); > + static_assert(!B<AT<T*>>::type::value); > +} > + > +template void f<char>(); > -- > 2.47.1.440.gcaacdb5dfd >