This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Backport of fix for PR c++/27398 to 4.1 branch


This patch backports the patch for PR c++/27398 to the 4.1 branch by
returning error_mark_node from grokdeclarator instead of void_type_node
or NULL_TREE on invalid decls.

In addition, grokbitfield has to be changed to check for error_mark_node
instead of NULL_TREE after a call to grokdeclarator. This is done by
backporting the patch for PR c++/28054, too.

The only difference in the testresults is in g++.dg/parse/undefined1.C:

  struct foo
  {
      X x;                   // { dg-error "" }

      foo(X)              {}
      foo(X y, int) : x() {} // { dg-error "" }
  };

We used to emit an error for the first constructor, too.
But given the fact that we already complained about X being
undefined, it's IMHO OK to suppress this error message.

Bootstrapped and regtested on x86_64-unknown-linux-gnu.
Ok for the 4.1 branch?

Regards,
Volker

:ADDPATCH C++:


2006-08-03  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/27398
	* decl.c (grokdeclarator): Return error_mark_node instead of
	NULL_TREE or void_type_node.

	Backport:
	2006-06-25  Lee Millward  <lee.millward@gmail.com>
		    Mark Mitchell <mark@codesuorcery.com>
	PR c++/28054
	* decl2.c (grokbitfield): Remove check for grokdeclarator
	returning NULL_TREE, instead check for error_mark_node
	to indicate failure.
	* decl.c (grokdeclarator): Adjust block comment.

===================================================================
--- gcc/gcc/cp/decl.c	(revision 113948)
+++ gcc/gcc/cp/decl.c	(working copy)
@@ -6688,7 +6688,11 @@
      void S::f() { ... }
 
    when grokdeclarator is called for `S::f', the CURRENT_CLASS_TYPE
-   should not be `S'.  */
+   should not be `S'.
+
+   Returns a DECL (if a declarator is present), a TYPE (if there is no
+   declarator, in cases like "struct S;"), or the ERROR_MARK_NODE if an
+   error occurs. */
 
 tree
 grokdeclarator (const cp_declarator *declarator,
@@ -6897,7 +6901,7 @@ grokdeclarator (const cp_declarator *declarator,
      a function declarator.  */
 
   if (funcdef_flag && innermost_code != cdk_function)
-    return 0;
+    return error_mark_node;
 
   if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)
       && innermost_code != cdk_function
@@ -7181,7 +7185,7 @@ grokdeclarator (const cp_declarator *declarator,
   if (dependant_name && !friendp)
     {
       error ("%<%T::%D%> is not a valid declarator", ctype, dependant_name);
-      return void_type_node;
+      return error_mark_node;
     }
 
   /* Issue errors about use of storage classes for parameters.  */
@@ -7422,7 +7426,7 @@ grokdeclarator (const cp_declarator *declarator,
 			if (! member_function_or_else (ctype,
 						       current_class_type,
 						       flags))
-			  return void_type_node;
+			  return error_mark_node;
 		      }
 		  }
 		else /* It's a constructor.  */
@@ -7450,10 +7454,10 @@ grokdeclarator (const cp_declarator *declarator,
 			if (! member_function_or_else (ctype,
 						       current_class_type,
 						       flags))
-			  return void_type_node;
+			  return error_mark_node;
 			TYPE_HAS_CONSTRUCTOR (ctype) = 1;
 			if (sfk != sfk_constructor)
-			  return NULL_TREE;
+			  return error_mark_node;
 		      }
 		  }
 		if (decl_context == FIELD)
@@ -7684,7 +7688,7 @@ grokdeclarator (const cp_declarator *declarator,
 	    {
 	      error ("cannot declare member %<%T::%s%> within %qT",
 		     ctype, name, current_class_type);
-	      return void_type_node;
+	      return error_mark_node;
 	    }
 	}
       else
@@ -8071,7 +8075,7 @@ grokdeclarator (const cp_declarator *declarator,
 		  {
 		    error ("can't make %qD into a method -- not in a class",
 			   unqualified_id);
-		    return void_type_node;
+		    return error_mark_node;
 		  }
 
 		/* ``A union may [ ... ] not [ have ] virtual functions.''
@@ -8080,7 +8084,7 @@ grokdeclarator (const cp_declarator *declarator,
 		  {
 		    error ("function %qD declared virtual inside a union",
 			   unqualified_id);
-		    return void_type_node;
+		    return error_mark_node;
 		  }
 
 		if (NEW_DELETE_OPNAME_P (unqualified_id))
@@ -8136,7 +8140,7 @@ grokdeclarator (const cp_declarator *declarator,
 			       sfk,
 			       funcdef_flag, template_count, in_namespace, attrlist);
 	    if (decl == NULL_TREE)
-	      return decl;
+	      return error_mark_node;
 #if 0
 	    /* This clobbers the attrs stored in `decl' from `attrlist'.  */
 	    /* The decl and setting of decl_attr is also turned off.  */
@@ -8184,7 +8188,7 @@ grokdeclarator (const cp_declarator *declarator,
 			       funcdef_flag, template_count, in_namespace,
 			       attrlist);
 	    if (decl == NULL_TREE)
-	      return NULL_TREE;
+	      return error_mark_node;
 	  }
 	else if (!staticp && !dependent_type_p (type)
 		 && !COMPLETE_TYPE_P (complete_type (type))
@@ -8240,7 +8244,7 @@ grokdeclarator (const cp_declarator *declarator,
 		return decl;
 	      }
 	    else
-	      return void_type_node;
+	      return error_mark_node;
 	  }
 
 	/* Structure field.  It may not be a function, except for C++.  */
@@ -8279,7 +8283,7 @@ grokdeclarator (const cp_declarator *declarator,
 		     void_type_node, as if this was a friend
 		     declaration, to cause callers to completely
 		     ignore this declaration.  */
-		  return void_type_node;
+		  return error_mark_node;
 	      }
 
 	    if (staticp)
@@ -8326,7 +8330,7 @@ grokdeclarator (const cp_declarator *declarator,
 	int publicp = 0;
 
 	if (!unqualified_id)
-	  return NULL_TREE;
+	  return error_mark_node;
 
 	if (TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR)
 	  original_name = dname;
@@ -8381,7 +8385,7 @@ grokdeclarator (const cp_declarator *declarator,
 			   publicp, inlinep, sfk, funcdef_flag,
 			   template_count, in_namespace, attrlist);
 	if (decl == NULL_TREE)
-	  return NULL_TREE;
+	  return error_mark_node;
 
 	if (staticp == 1)
 	  {
===================================================================
--- gcc/gcc/cp/decl2.c	2006/06/25 11:07:05	114985
+++ gcc/gcc/cp/decl2.c	2006/06/25 11:28:01	114986
@@ -990,7 +990,8 @@
 {
   tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL);
 
-  if (! value) return NULL_TREE; /* friends went bad.  */
+  if (value == error_mark_node) 
+    return NULL_TREE; /* friends went bad.  */
 
   /* Pass friendly classes back.  */
   if (TREE_CODE (value) == VOID_TYPE)
===================================================================

2006-08-03  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>

	PR c++/27398
	* g++.dg/template/crash50.C: New test.
	* g++.dg/parse/undefined1.C: Remove error marker.

	Backport:
	2006-06-25  Lee Millward  <lee.millward@gmail.com>
	PR c++/28054
	* g++.dg/other/incomplete3.C: New test.

===================================================================
--- gcc/gcc/testsuite/g++.dg/template/crash50.C	2005-08-29 00:25:44 +0200
+++ gcc/gcc/testsuite/g++.dg/template/crash50.C	2006-05-17 16:43:33 +0200
@@ -0,0 +1,7 @@
+// PR c++/27398
+// { dg-do compile }
+
+struct A
+{
+  template<int> void* foo(; // { dg-error "primary-expression|initialization|static" }
+};
===================================================================
--- gcc/gcc/testsuite/g++.dg/parse/undefined1.C	(revision 113967)
+++ gcc/gcc/testsuite/g++.dg/parse/undefined1.C	(working copy)
@@ -5,6 +5,6 @@
 {
     X x;                   // { dg-error "" }
 
-    foo(X)              {} // { dg-error "" }
+    foo(X)              {}
     foo(X y, int) : x() {} // { dg-error "" }
 };
===================================================================
--- gcc/gcc/testsuite/g++.dg/other/incomplete3.C	2005-08-29 00:25:44 +0200
+++ gcc/gcc/testsuite/g++.dg/other/incomplete3.C	2006-08-03 16:36:55 +0200
@@ -0,0 +1,9 @@
+//PR c++/28054
+
+struct A;
+
+struct B
+{
+    friend A : 2; // { dg-error "incomplete type" }
+};
+
===================================================================



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]