From 2ed0bcc0e4c0784d4408fbf4204649e2283b34c9 Mon Sep 17 00:00:00 2001
From: lmillward <lmillward@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 25 Sep 2006 19:45:34 +0000
Subject: [PATCH]         PR c++/27329         PR c++/26938         * cp-tree.h
 (redeclare_class_template): Adjust declaration         to return bool instead
 of void.         * pt.c (redeclare_class_template): Update definition. Return
         false on error.         * decl.c (xref_tag): Return error_mark_node
 if redeclare_class_template         returned false.

        * g++.dg/template/crash58.C: New test.
        * g++.dg/template/crash59.C: New test.
        * g++.dg/parse/crash28.C: Adjust error markers.
        * g++.dg/template/crash34.C: Likewise.
        * g++.dg/template/friend31.C: Likewise.
        * g++.dg/template/crash32.C: Likewise.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117205 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cp/ChangeLog                         | 11 +++++++++++
 gcc/cp/cp-tree.h                         |  2 +-
 gcc/cp/decl.c                            |  5 ++++-
 gcc/cp/pt.c                              | 16 +++++++++-------
 gcc/testsuite/ChangeLog                  | 12 ++++++++++++
 gcc/testsuite/g++.dg/parse/crash28.C     |  2 +-
 gcc/testsuite/g++.dg/template/crash32.C  |  2 +-
 gcc/testsuite/g++.dg/template/crash34.C  |  2 +-
 gcc/testsuite/g++.dg/template/crash58.C  | 10 ++++++++++
 gcc/testsuite/g++.dg/template/crash59.C  | 19 +++++++++++++++++++
 gcc/testsuite/g++.dg/template/friend31.C |  4 ++--
 11 files changed, 71 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/crash58.C
 create mode 100644 gcc/testsuite/g++.dg/template/crash59.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9661c8f6bc50..a41714cdcd1a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2006-09-25  Lee Millward  <lee.millward@codesourcery.com>
+
+        PR c++/27329
+        PR c++/26938
+        * cp-tree.h (redeclare_class_template): Adjust declaration
+        to return bool instead of void.
+        * pt.c (redeclare_class_template): Update definition.
+	Return false on error.
+        * decl.c (xref_tag): Return error_mark_node if
+	redeclare_class_template returned false.
+	
 2006-09-21  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/29016
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8f88976e7870..227fc9dfdec0 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4097,7 +4097,7 @@ extern tree end_template_parm_list		(tree);
 extern void end_template_decl			(void);
 extern tree push_template_decl			(tree);
 extern tree push_template_decl_real		(tree, bool);
-extern void redeclare_class_template		(tree, tree);
+extern bool redeclare_class_template		(tree, tree);
 extern tree lookup_template_class		(tree, tree, tree, tree,
 						 int, tsubst_flags_t);
 extern tree lookup_template_function		(tree, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 7b932c05b1ec..84f2aaa49b3e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9712,7 +9712,10 @@ xref_tag (enum tag_types tag_code, tree name,
   else
     {
       if (template_header_p && IS_AGGR_TYPE (t))
-	redeclare_class_template (t, current_template_parms);
+        {
+	  if (!redeclare_class_template (t, current_template_parms))
+            POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+        }
       else if (!processing_template_decl
 	       && CLASS_TYPE_P (t)
 	       && CLASSTYPE_IS_TEMPLATE (t))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index aea943ed0c18..daee2522047c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3315,7 +3315,7 @@ push_template_decl (tree decl)
      template <class T> struct S;
      template <class T> struct S {};  */
 
-void
+bool
 redeclare_class_template (tree type, tree parms)
 {
   tree tmpl;
@@ -3325,7 +3325,7 @@ redeclare_class_template (tree type, tree parms)
   if (!TYPE_TEMPLATE_INFO (type))
     {
       error ("%qT is not a template type", type);
-      return;
+      return false;
     }
 
   tmpl = TYPE_TI_TEMPLATE (type);
@@ -3333,13 +3333,13 @@ redeclare_class_template (tree type, tree parms)
     /* The type is nested in some template class.  Nothing to worry
        about here; there are no new template parameters for the nested
        type.  */
-    return;
+    return true;
 
   if (!parms)
     {
       error ("template specifiers not specified in declaration of %qD",
 	     tmpl);
-      return;
+      return false;
     }
 
   parms = INNERMOST_TEMPLATE_PARMS (parms);
@@ -3351,7 +3351,7 @@ redeclare_class_template (tree type, tree parms)
       error ("used %d template parameter(s) instead of %d",
 	     TREE_VEC_LENGTH (tmpl_parms),
 	     TREE_VEC_LENGTH (parms));
-      return;
+      return false;
     }
 
   for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i)
@@ -3379,7 +3379,7 @@ redeclare_class_template (tree type, tree parms)
 	{
 	  error ("template parameter %q+#D", tmpl_parm);
 	  error ("redeclared here as %q#D", parm);
-	  return;
+	  return false;
 	}
 
       if (tmpl_default != NULL_TREE && parm_default != NULL_TREE)
@@ -3390,7 +3390,7 @@ redeclare_class_template (tree type, tree parms)
 	     by two different declarations in the same scope.  */
 	  error ("redefinition of default argument for %q#D", parm);
 	  error ("%J  original definition appeared here", tmpl_parm);
-	  return;
+	  return false;
 	}
 
       if (parm_default != NULL_TREE)
@@ -3402,6 +3402,8 @@ redeclare_class_template (tree type, tree parms)
 	   parameters for any members.  */
 	TREE_PURPOSE (TREE_VEC_ELT (parms, i)) = tmpl_default;
     }
+
+    return true;
 }
 
 /* Simplify EXPR if it is a non-dependent expression.  Returns the
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5a99e5a8b300..a511e5625365 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2006-09-25  Lee Millward  <lee.millward@codesourcery.com>
+
+        PR c++/26938
+        * g++.dg/template/crash58.C: New test.
+        * g++.dg/parse/crash28.C: Adjust error markers.
+        * g++.dg/template/crash34.C: Likewise.
+        * g++.dg/template/friend31.C: Likewise.
+        * g++.dg/template/crash32.C: Likewise.
+
+        PR c++/27329
+        * g++.dg/template/crash59.C: New test.
+	
 2006-09-24  Zdenek Dvorak <dvorakz@suse.cz>
 	    Adam Nemet  <anemet@caviumnetworks.com>
 
diff --git a/gcc/testsuite/g++.dg/parse/crash28.C b/gcc/testsuite/g++.dg/parse/crash28.C
index bc4916557685..67d78d6bb7f5 100644
--- a/gcc/testsuite/g++.dg/parse/crash28.C
+++ b/gcc/testsuite/g++.dg/parse/crash28.C
@@ -7,7 +7,7 @@
 
 template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
 template <class _Value> class insert_iterator<int > { // { dg-error "template" }
-  hash_set<_Value>; // { dg-error "no type|expected" }
+  hash_set<_Value>;
 };
 
 template<int> struct A<X<> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
diff --git a/gcc/testsuite/g++.dg/template/crash32.C b/gcc/testsuite/g++.dg/template/crash32.C
index a8363512e947..4c7af8a39142 100644
--- a/gcc/testsuite/g++.dg/template/crash32.C
+++ b/gcc/testsuite/g++.dg/template/crash32.C
@@ -3,7 +3,7 @@
 struct integral_constant { };
 
 template<typename _Tp>
-struct is_function : public integral_constant { }; // { dg-error "previous" }
+struct is_function : public integral_constant { };
 
 template<>
 struct is_function : public integral_constant { }; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/crash34.C b/gcc/testsuite/g++.dg/template/crash34.C
index 9cca62f05391..ef4d21b60d84 100644
--- a/gcc/testsuite/g++.dg/template/crash34.C
+++ b/gcc/testsuite/g++.dg/template/crash34.C
@@ -9,4 +9,4 @@ class Foo;
 
 template <typename T> class Foo { }; // { dg-error "not a template type" }
 
-Foo<int> x; // { dg-error "not a template" }
+Foo<int> x; // { dg-error "not a template|incomplete type" }
diff --git a/gcc/testsuite/g++.dg/template/crash58.C b/gcc/testsuite/g++.dg/template/crash58.C
new file mode 100644
index 000000000000..af2172c67326
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash58.C
@@ -0,0 +1,10 @@
+//PR 26938
+
+template<int, int = 0> struct A;  // { dg-error "previous declaration" }
+
+template<int> struct A            // { dg-error "template" }
+{
+  A();
+};
+
+A<0> a;                           // { dg-error "incomplete type" }
diff --git a/gcc/testsuite/g++.dg/template/crash59.C b/gcc/testsuite/g++.dg/template/crash59.C
new file mode 100644
index 000000000000..61d2188fc9ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash59.C
@@ -0,0 +1,19 @@
+//PR c++/27329
+
+template<int> struct A                          // { dg-error "forward declaration" }
+!                                               // { dg-error "expected unqualified-id" }
+  ;
+
+template<int> struct A { int foo(); };          // { dg-error "not a template" }
+
+int i = A<0>().foo();                           // { dg-error "not a template|invalid use" }
+
+
+template<int> struct B        
+!                                               // { dg-error "expected unqualified-id" }
+  ;
+
+template<int> struct B { static int bar(); };   // { dg-error "not a template" }
+
+int j = B<0>::bar();                            // { dg-error "not a template|incomplete type" }
+ 
diff --git a/gcc/testsuite/g++.dg/template/friend31.C b/gcc/testsuite/g++.dg/template/friend31.C
index 2d62f878a21a..222ce238d786 100644
--- a/gcc/testsuite/g++.dg/template/friend31.C
+++ b/gcc/testsuite/g++.dg/template/friend31.C
@@ -10,12 +10,12 @@ template <typename T, typename U> struct F; // { dg-error "previous declaration"
 class W
 {
   template<int i> friend class F;	// { dg-error "template parameter" }
-  int x;
+  int x;                                // { dg-error "private" }
 };
 
 template <typename T, typename U> struct F
 {
-  void Look(W& w) { w.x = 3; }
+  void Look(W& w) { w.x = 3; }          // { dg-error "within this context" }
 };
 
 int main()
-- 
GitLab