This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Backport of fix for PR c++/27398 to 4.1 branch
- From: Volker Reichelt <reichelt at igpm dot rwth-aachen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 03 Aug 2006 22:09:37 +0200 (CEST)
- Subject: [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" }
+};
+
===================================================================