This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR c++/35320: ICE with invalid friend declaration
- From: Simon Martin <simartin at users dot sourceforge dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 15 Mar 2008 13:07:42 +0100
- Subject: [PATCH] Fix PR c++/35320: ICE with invalid friend declaration
Hi all.
The following invalid snippet triggers an segmentation fault since GCC 3.1:
=== cut here ===
typedef void (func_type)();
struct A
{
friend func_type f : 2;
};
=== cut here ===
The ICE happens in 'grokbitfield', that calls 'grokdeclarator' with a
null ATTRLIST, that is dereferenced when calling 'do_friend', hence the
segmentation fault.
The attached patch adds an extra argument to 'grokbitfield': the list of
attributes, that is passed to 'grokdeclarator', fixing the segmentation
fault. Moreover, since all the callers of 'grokbitfield' apply the
attributes to the created declaration, I've moved this into
'grokbitfield'... an extra reason to pass it those attributes.
I've successfully regtested this patch on x86_64-apple-darwin-9. Is it
OK for the mainline?
Best regards,
Simon
:ADDPATCH c++:
2008-03-15 Simon Martin <simartin@users.sourceforge.net>
PR c++/35320
* decl2.c (grokbitfield): Receive the list of attributes, pass it to
grokdeclarator and apply it to the created declaration.
* cp-tree.h (grokbitfield): Update prototype.
* parser.c (cp_parser_member_declaration): Don't apply the attributes
since they are now applied in grokbitfield. Adjusted the call to
grokbitfield.
(cp_parser_objc_class_ivars): Likewise.
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h (revision 133238)
+++ gcc/cp/cp-tree.h (working copy)
@@ -4283,7 +4283,7 @@ extern void check_member_template (tree
extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *,
tree, bool, tree, tree);
extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *,
- tree);
+ tree, tree);
extern void cplus_decl_attributes (tree *, tree, int);
extern void finish_anon_union (tree);
extern void cp_write_global_declarations (void);
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c (revision 133238)
+++ gcc/cp/decl2.c (working copy)
@@ -914,9 +914,10 @@ grokfield (const cp_declarator *declarat
tree
grokbitfield (const cp_declarator *declarator,
- cp_decl_specifier_seq *declspecs, tree width)
+ cp_decl_specifier_seq *declspecs, tree width,
+ tree attrlist)
{
- tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL);
+ tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, &attrlist);
if (value == error_mark_node)
return NULL_TREE; /* friends went bad. */
@@ -972,6 +974,10 @@ grokbitfield (const cp_declarator *decla
}
DECL_IN_AGGR_P (value) = 1;
+
+ if (attrlist)
+ cplus_decl_attributes (&value, attrlist, /*flags=*/0);
+
return value;
}
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c (revision 133238)
+++ gcc/cp/parser.c (working copy)
@@ -15121,9 +15121,8 @@ cp_parser_member_declaration (cp_parser*
sfk_none)
: NULL,
&decl_specifiers,
- width);
- /* Apply the attributes. */
- cplus_decl_attributes (&decl, attributes, /*flags=*/0);
+ width,
+ attributes);
}
else
{
@@ -19029,11 +19028,10 @@ cp_parser_objc_class_ivars (cp_parser* p
attributes = chainon (prefix_attributes, attributes);
if (width)
- {
/* Create the bitfield declaration. */
- decl = grokbitfield (declarator, &declspecs, width);
- cplus_decl_attributes (&decl, attributes, /*flags=*/0);
- }
+ decl = grokbitfield (declarator, &declspecs,
+ width,
+ attributes);
else
decl = grokfield (declarator, &declspecs,
NULL_TREE, /*init_const_expr_p=*/false,
2008-03-15 Simon Martin <simartin@users.sourceforge.net>
PR c++/35320
* g++.dg/parser/bitfield3.C: New test.
/* PR c++/35320 */
/* { dg-do "compile" } */
typedef void (func_type)();
struct A
{
friend func_type f : 2; /* { dg-error "with non-integral type" } */
};