]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: tf_partial and instantiate_template [PR117887]
authorPatrick Palka <ppalka@redhat.com>
Thu, 9 Jan 2025 15:50:16 +0000 (10:50 -0500)
committerPatrick Palka <ppalka@redhat.com>
Thu, 9 Jan 2025 15:50:16 +0000 (10:50 -0500)
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 <jason@redhat.com>
gcc/cp/pt.cc
gcc/testsuite/g++.dg/cpp2a/concepts-requires39.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/lambda-targ10.C [new file with mode: 0644]

index 081285ef72099213c0e155d348d918fd704cc430..19df9ccb6afd3e6550bc4219de486a455558f3ce 100644 (file)
@@ -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 (file)
index 0000000..b136820
--- /dev/null
@@ -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 (file)
index 0000000..7f175c9
--- /dev/null
@@ -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>();