]> gcc.gnu.org Git - gcc.git/commitdiff
c++: erroneous partial spec vs primary tmpl [PR116064]
authorPatrick Palka <ppalka@redhat.com>
Wed, 7 Aug 2024 18:28:26 +0000 (14:28 -0400)
committerPatrick Palka <ppalka@redhat.com>
Wed, 7 Aug 2024 18:28:26 +0000 (14:28 -0400)
When a partial specialization is deemed erroneous at parse time, we
currently flag the primary template as erroneous instead.  Later
at instantiation time we check if the primary template is erroneous
rather than the selected partial specialization, so at least we're
consistent.

But it's better not to conflate a partial specialization with the
primary template since they're instantiated independenty.  This avoids
rejecting the instantiation of A<int> in the below testcase.

PR c++/116064

gcc/cp/ChangeLog:

* error.cc (get_current_template): If the current scope is
a partial specialization, return it instead of the primary
template.
* pt.cc (instantiate_class_template): Pass the partial
specialization if any to maybe_diagnose_erroneous_template
instead of the primary template.

gcc/testsuite/ChangeLog:

* g++.dg/template/permissive-error2.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
gcc/cp/error.cc
gcc/cp/pt.cc
gcc/testsuite/g++.dg/template/permissive-error2.C [new file with mode: 0644]

index 6c22ff55b46391be4490c0c3cdf58b90857d4363..879e5a115cfe970c7fdca22234d53fbf21122aa6 100644 (file)
@@ -173,7 +173,11 @@ get_current_template ()
 {
   if (scope_chain && in_template_context && !current_instantiation ())
     if (tree ti = get_template_info (current_scope ()))
-      return TI_TEMPLATE (ti);
+      {
+       if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti)) && TI_PARTIAL_INFO (ti))
+         ti = TI_PARTIAL_INFO (ti);
+       return TI_TEMPLATE (ti);
+      }
 
   return NULL_TREE;
 }
index 542962b6387f473c1b42ac9f58edc1cda194e6d5..3e55d5c0fea5a3e7d8bcad193daed95a0a8f3395 100644 (file)
@@ -12381,7 +12381,7 @@ instantiate_class_template (tree type)
   if (! push_tinst_level (type))
     return type;
 
-  maybe_diagnose_erroneous_template (templ);
+  maybe_diagnose_erroneous_template (t ? TI_TEMPLATE (t) : templ);
 
   int saved_unevaluated_operand = cp_unevaluated_operand;
   int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
diff --git a/gcc/testsuite/g++.dg/template/permissive-error2.C b/gcc/testsuite/g++.dg/template/permissive-error2.C
new file mode 100644 (file)
index 0000000..692e7c7
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/116064
+// { dg-additional-options -fpermissive }
+// Verify we correctly mark a partial specialization as erroneous
+// instead its primary template.
+
+template<class T>
+struct A { };
+
+template<class T>
+struct A<T*> { // { dg-error "instantiating erroneous template" }
+  void f(typename A::type); // { dg-warning "does not name a type" }
+};
+
+A<int> a;  // { dg-bogus "" }
+A<int*> b; // { dg-message "required from here" }
This page took 0.097773 seconds and 5 git commands to generate.