diff mbox

Minor C++ PATCH to specialization matching

Message ID 5037CE94.1000304@redhat.com
State New
Headers show

Commit Message

Jason Merrill Aug. 24, 2012, 6:57 p.m. UTC
Another patch I'm working on revealed a couple of latent issues in 
specialization matching.

First, check_specialization_namespace takes the template as an argument, 
not the specialization; fixing this improves the error location on spec25.C.

Second, allowing determine_specialization to match a member of an 
uninstantiated class was leading to an abort in other code that relied 
on that not happening, since it's ill-formed.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit 47e1174262229c446ff4cdb9a01e131ed269e7d3
Author: Jason Merrill <jason@redhat.com>
Date:   Sun Aug 12 22:25:11 2012 -0400

    	* pt.c (register_specialization): Correct argument to
    	check_specialization_namespace.
    	(determine_specialization): Don't consider members of
    	unspecialized types.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ad81bab..580a3d4 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -735,7 +735,7 @@  end_explicit_instantiation (void)
   processing_explicit_instantiation = false;
 }
 
-/* An explicit specialization or partial specialization TMPL is being
+/* An explicit specialization or partial specialization of TMPL is being
    declared.  Check that the namespace in which the specialization is
    occurring is permissible.  Returns false iff it is invalid to
    specialize TMPL in the current namespace.  */
@@ -1407,7 +1407,7 @@  register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
 		  DECL_SOURCE_LOCATION (clone)
 		    = DECL_SOURCE_LOCATION (fn);
 		}
-	      check_specialization_namespace (fn);
+	      check_specialization_namespace (tmpl);
 
 	      return fn;
 	    }
@@ -1804,6 +1804,16 @@  determine_specialization (tree template_id,
   if (template_id == error_mark_node || decl == error_mark_node)
     return error_mark_node;
 
+  /* We shouldn't be specializing a member template of an
+     unspecialized class template; we already gave an error in
+     check_specialization_scope, now avoid crashing.  */
+  if (template_count && DECL_CLASS_SCOPE_P (decl)
+      && template_class_depth (DECL_CONTEXT (decl)) > 0)
+    {
+      gcc_assert (errorcount);
+      return error_mark_node;
+    }
+
   fns = TREE_OPERAND (template_id, 0);
   explicit_targs = TREE_OPERAND (template_id, 1);
 
diff --git a/gcc/testsuite/g++.dg/template/spec25.C b/gcc/testsuite/g++.dg/template/spec25.C
index 3f641fe..385d19a 100644
--- a/gcc/testsuite/g++.dg/template/spec25.C
+++ b/gcc/testsuite/g++.dg/template/spec25.C
@@ -1,10 +1,10 @@ 
 namespace N {
   template <typename T>
   struct S {
-    void f() {}
+    void f() {}			// { dg-error "definition" }
   };
 }
 
 namespace K {
-  template <> void N::S<char>::f() {} // { dg-error "namespace|definition" }
+  template <> void N::S<char>::f() {} // { dg-error "different namespace" }
 }