Patchwork C++ PATCH for c++/53492 (ICE with wrong template headers)

login
register
mail settings
Submitter Jason Merrill
Date March 10, 2014, 3:44 p.m.
Message ID <531DDDC3.4010706@redhat.com>
Download mbox | patch
Permalink /patch/328605/
State New
Headers show

Comments

Jason Merrill - March 10, 2014, 3:44 p.m.
We diagnose problems with template headers in push_template_decl, but 
this testcase was skirting around the different places where we call 
that function.  Fixed thus.

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

Patch

commit 5b5dadf2538f7684232cd72bd14ed1cdce2b0788
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Mar 8 00:05:16 2014 -0500

    	PR c++/53492
    	* parser.c (cp_parser_class_head): Also check PRIMARY_TEMPLATE_P
    	when deciding whether to call push_template_decl for a member class.
    	* pt.c (push_template_decl_real): Return after wrong levels error.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 64583ba..a3c8d7e 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19888,7 +19888,13 @@  cp_parser_class_head (cp_parser* parser,
       pushed_scope = push_scope (nested_name_specifier);
       /* Get the canonical version of this type.  */
       type = TYPE_MAIN_DECL (TREE_TYPE (type));
-      if (PROCESSING_REAL_TEMPLATE_DECL_P ()
+      /* Call push_template_decl if it seems like we should be defining a
+	 template either from the template headers or the type we're
+	 defining, so that we diagnose both extra and missing headers.  */
+      if ((PROCESSING_REAL_TEMPLATE_DECL_P ()
+	   || (CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (type))
+	       && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE
+				      (TREE_TYPE (type)))))
 	  && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
 	{
 	  type = push_template_decl (type);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5afe0fd..7e287f7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4908,6 +4908,8 @@  push_template_decl_real (tree decl, bool is_friend)
 	{
 	  error ("expected %d levels of template parms for %q#D, got %d",
 		 i, decl, TMPL_ARGS_DEPTH (args));
+	  DECL_INTERFACE_KNOWN (decl) = 1;
+	  return error_mark_node;
 	}
       else
 	for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms))
diff --git a/gcc/testsuite/g++.dg/template/memtmpl4.C b/gcc/testsuite/g++.dg/template/memtmpl4.C
new file mode 100644
index 0000000..54558b9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/memtmpl4.C
@@ -0,0 +1,10 @@ 
+// PR c++/53492
+
+template<typename T> struct A
+{
+  template<typename U> struct B;
+};
+
+template <> template<class T> struct A<T>::B { }; // { dg-error "expected 2 levels" }
+
+A<int>::B<int> b;		// { dg-error "" }