aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2024-08-07 14:28:26 -0400
committerPatrick Palka <ppalka@redhat.com>2024-08-07 14:28:26 -0400
commitd1fc9816df81e953308428641685d6ec6d84c9ac (patch)
treee342a3153f56d165ce51abc9d55e55a01b79655a
parent38900247f3880d6eca2e364a000e5898f8deae64 (diff)
downloadgcc-d1fc9816df81e953308428641685d6ec6d84c9ac.zip
gcc-d1fc9816df81e953308428641685d6ec6d84c9ac.tar.gz
gcc-d1fc9816df81e953308428641685d6ec6d84c9ac.tar.bz2
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 <jason@redhat.com>
-rw-r--r--gcc/cp/error.cc6
-rw-r--r--gcc/cp/pt.cc2
-rw-r--r--gcc/testsuite/g++.dg/template/permissive-error2.C15
3 files changed, 21 insertions, 2 deletions
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 6c22ff5..879e5a1 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 542962b..3e55d5c 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 0000000..692e7c7
--- /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" }