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
>

Reply via email to