https://gcc.gnu.org/g:d1fc9816df81e953308428641685d6ec6d84c9ac

commit r15-2802-gd1fc9816df81e953308428641685d6ec6d84c9ac
Author: Patrick Palka <ppa...@redhat.com>
Date:   Wed Aug 7 14:28:26 2024 -0400

    c++: erroneous partial spec vs primary tmpl [PR116064]
    
    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 <ja...@redhat.com>

Diff:
---
 gcc/cp/error.cc                                   |  6 +++++-
 gcc/cp/pt.cc                                      |  2 +-
 gcc/testsuite/g++.dg/template/permissive-error2.C | 15 +++++++++++++++
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 6c22ff55b463..879e5a115cfe 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -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;
 }
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 542962b6387f..3e55d5c0fea5 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -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
index 000000000000..692e7c7ac82c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/permissive-error2.C
@@ -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" }

Reply via email to