https://gcc.gnu.org/g:27d620d67697157f2269f3add4cb830540ac5795

commit r15-6740-g27d620d67697157f2269f3add4cb830540ac5795
Author: Patrick Palka <ppa...@redhat.com>
Date:   Thu Jan 9 10:50:16 2025 -0500

    c++: tf_partial and instantiate_template [PR117887]
    
    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 testcases show that instantiate_template
    for AT with args={T}/{T*} is neglecting to set it in that case, and we
    end up ICEing from add_extra_args during the subsequent full substitution.
    
    This patch makes instantiate_template set tf_partial accordingly.
    
            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.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>

Diff:
---
 gcc/cp/pt.cc                                     | 14 +++++++++++---
 gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C | 17 +++++++++++++++++
 gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C       | 17 +++++++++++++++++
 3 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 081285ef7209..19df9ccb6afd 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -22437,7 +22437,10 @@ 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;
+     the above is concerned specifically about the non-dependent case.  */
   complain &= tf_warning_or_error;
 
   gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
@@ -22516,9 +22519,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 000000000000..b13682033dac
--- /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 000000000000..7f175c93062f
--- /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>();

Reply via email to