[patch] Fix C++ PRs 28736, 28737 and 28738

Lee Millward lee.millward@codesourcery.com
Sat Aug 26 16:34:00 GMT 2006


Forgot to attach the patch.
-------------- next part --------------
Index: gcc/testsuite/g++.dg/template/void3.C
===================================================================
--- gcc/testsuite/g++.dg/template/void3.C	(revision 116419)
+++ gcc/testsuite/g++.dg/template/void3.C	(working copy)
@@ -1,5 +1,5 @@
 //PR c++/28637
 
 template<void> struct A {};  // { dg-error "not a valid type" }
-A<0> a;
+A<0> a;                      // { dg-error "type" }
 
Index: gcc/testsuite/g++.dg/template/void10.C
===================================================================
--- gcc/testsuite/g++.dg/template/void10.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/void10.C	(revision 0)
@@ -0,0 +1,10 @@
+//PR c++/28736
+
+template<void> struct A                 // { dg-error "not a valid type" }
+{
+    template<typename> friend struct B;
+};
+
+template<typename> struct B {};
+
+B<int> b;                              // { dg-error "template argument|invalid type" }
Index: gcc/testsuite/g++.dg/template/void4.C
===================================================================
--- gcc/testsuite/g++.dg/template/void4.C	(revision 116419)
+++ gcc/testsuite/g++.dg/template/void4.C	(working copy)
@@ -4,4 +4,4 @@ template<void> struct A;  // { dg-error 
 
 template<template<int> class> struct B {};
 
-B<A> b;
+B<A> b;                  // { dg-error "template|invalid type" }
Index: gcc/testsuite/g++.dg/template/crash55.C
===================================================================
--- gcc/testsuite/g++.dg/template/crash55.C	(revision 116419)
+++ gcc/testsuite/g++.dg/template/crash55.C	(working copy)
@@ -3,4 +3,4 @@
 template<typename class T, T = T()> // { dg-error "nested-name-specifier|two or more|valid type" }
 struct A {};                        // { dg-error "definition"
 
-template<int> void foo(A<int>);     // { dg-error "mismatch|constant" }
+template<int> void foo(A<int>);     // { dg-error "mismatch|constant|template argument" }
Index: gcc/testsuite/g++.dg/template/void7.C
===================================================================
--- gcc/testsuite/g++.dg/template/void7.C	(revision 116419)
+++ gcc/testsuite/g++.dg/template/void7.C	(working copy)
@@ -5,4 +5,4 @@ template<void> struct A         // { dg-
   static int i;
 };
 
-A<0> a;
+A<0> a;                        // { dg-error "invalid type|not a valid type" }
Index: gcc/testsuite/g++.dg/template/void8.C
===================================================================
--- gcc/testsuite/g++.dg/template/void8.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/void8.C	(revision 0)
@@ -0,0 +1,7 @@
+//PR c++/28737
+
+template<void> struct A;                // { dg-error "not a valid type" }
+
+template<typename> struct B;
+
+template<void N> struct B<A<N> > {};   // { dg-error "not a valid type|declared|invalid" }
Index: gcc/testsuite/g++.dg/template/void9.C
===================================================================
--- gcc/testsuite/g++.dg/template/void9.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/void9.C	(revision 0)
@@ -0,0 +1,4 @@
+//PR c++/28738
+
+template<int,void> struct A {};    // { dg-error "not a valid type" }
+template<int N> struct A<N,0> {};  // { dg-error "not a valid type" }
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 116419)
+++ gcc/cp/pt.c	(working copy)
@@ -336,12 +336,11 @@ push_inline_template_parms_recursive (tr
 	       NULL);
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
     {
-      tree parm;
+      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
 
-      if (TREE_VEC_ELT (parms, i) == error_mark_node)
-        continue;
+      if (parm == error_mark_node)
+	continue;
 
-      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
       gcc_assert (DECL_P (parm));
 
       switch (TREE_CODE (parm))
@@ -2212,15 +2211,13 @@ comp_template_parms (tree parms1, tree p
 
       for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
 	{
-          tree parm1;
-          tree parm2;
+          tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
+          tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
 
-          if (TREE_VEC_ELT (t1, i) == error_mark_node
-              || TREE_VEC_ELT (t2, i) == error_mark_node)
-            continue;
-
-	  parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
-          parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
+          /* If either of the template parameters are invalid, assume
+             they match for the sake of error recovery. */
+          if (parm1 == error_mark_node || parm2 == error_mark_node)
+            return 1;
 
 	  if (TREE_CODE (parm1) != TREE_CODE (parm2))
 	    return 0;
@@ -2352,6 +2349,7 @@ process_template_parm (tree list, tree p
 {
   tree decl = 0;
   tree defval;
+  tree err_parm_list;
   int idx = 0;
 
   gcc_assert (TREE_CODE (parm) == TREE_LIST);
@@ -2361,7 +2359,7 @@ process_template_parm (tree list, tree p
     {
       tree p = tree_last (list);
 
-      if (p && p != error_mark_node)
+      if (p && TREE_VALUE (p) != error_mark_node)
         {
           p = TREE_VALUE (p);
           if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
@@ -2382,7 +2380,11 @@ process_template_parm (tree list, tree p
       SET_DECL_TEMPLATE_PARM_P (parm);
 
       if (TREE_TYPE (parm) == error_mark_node)
-	return chainon(list, error_mark_node);
+        {
+          err_parm_list = build_tree_list (defval, parm);
+          TREE_VALUE (err_parm_list) = error_mark_node;
+	   return chainon (list, err_parm_list);
+        }
       else
       {
 	/* [temp.param]
@@ -2391,7 +2393,11 @@ process_template_parm (tree list, tree p
 	   ignored when determining its type.  */
 	TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
 	if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
-	  return chainon(list, error_mark_node);
+          {
+            err_parm_list = build_tree_list (defval, parm);
+            TREE_VALUE (err_parm_list) = error_mark_node;
+	     return chainon (list, err_parm_list);
+          }
       }
 
       /* A template parameter is not modifiable.  */
@@ -2522,11 +2528,15 @@ current_template_args (void)
 	    {
 	      t = TREE_VALUE (t);
 
-	      if (TREE_CODE (t) == TYPE_DECL
-		  || TREE_CODE (t) == TEMPLATE_DECL)
-		t = TREE_TYPE (t);
-	      else
-		t = DECL_INITIAL (t);
+	      if (t != error_mark_node)
+		{
+		  if (TREE_CODE (t) == TYPE_DECL
+		      || TREE_CODE (t) == TEMPLATE_DECL)
+		    t = TREE_TYPE (t);
+		  else
+		    t = DECL_INITIAL (t);
+		}
+
 	      TREE_VEC_ELT (a, i) = t;
 	    }
 	}
@@ -3350,9 +3360,10 @@ redeclare_class_template (tree type, tre
 
       /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
 	 TEMPLATE_DECL.  */
-      if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
-	  || (TREE_CODE (tmpl_parm) != TYPE_DECL
-	      && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))
+      if (tmpl_parm != error_mark_node
+	   && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+	   || (TREE_CODE (tmpl_parm) != TYPE_DECL
+	       && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))))
 	{
 	  error ("template parameter %q+#D", tmpl_parm);
 	  error ("redeclared here as %q#D", parm);
@@ -4205,12 +4216,12 @@ mangle_class_name_for_template (const ch
       tree parm;
       tree arg;
 
-      if (TREE_VEC_ELT (parms, i) == error_mark_node)
-        continue;
-
       parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
       arg = TREE_VEC_ELT (arglist, i);
 
+      if (parm == error_mark_node)
+	continue;
+
       if (i)
 	ccat (',');
 


More information about the Gcc-patches mailing list