This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR c++/33207: ICE redeclaring namespace as struct
- From: Simon Martin <simartin at users dot sourceforge dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 08 Sep 2007 07:50:26 +0200
- Subject: [PATCH] Fix PR c++/33207: ICE redeclaring namespace as struct
Hi all.
The following code snippet triggers an ICE with the mainline:
=== cut here ===
namespace N { }
struct N;
struct N* p;
=== cut here ===
The problem is that the type for 'struct N', when processed by
'pushtag', is not completely setup: we leave the function earlier
because we end up with error_mark_node after 'pushdecl_with_scope' since
N is already the name of a namespace. In particular, the type's
TYPE_STUB_DECL is not set, so it (and TYPE_MAIN_DECL) remains NULL_TREE.
When processing the declaration for 'p', in 'no_linkage_check', the
type's TYPE_MAIN_DECL is used to call 'decl_function_context', which
does not check if its argument is NULL_TREE or not before dereferencing
it, hence the ICE.
The attached patch fixes this by making sure that 'pushtag' properly
sets up TYPE even in case of error.
I have successfully regtested it on i386-apple-darwin8.10.1. Is it OK
for mainline?
Thanks in advance,
Simon
:ADDPATCH c++:
2007-09-08 Simon Martin <simartin@users.sourceforge.net>
PR c++/33207
* name-lookup.c (pushtag_finish_type): New helper function to pushtag
to finish to setup TYPE.
(pushtag): Use it, even in case of error.
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c (revision 128174)
+++ gcc/cp/name-lookup.c (working copy)
@@ -4853,6 +4853,20 @@ maybe_process_template_type_declaration
return decl;
}
+/* Helper function to pushtag. Finish to setup TYPE. */
+
+static void
+pushtag_finish_type (tree type)
+{
+ tree decl = TYPE_NAME (type);
+ gcc_assert (TREE_CODE (decl) == TYPE_DECL);
+ TYPE_STUB_DECL (type) = decl;
+
+ /* Set type visibility now if this is a forward declaration. */
+ TREE_PUBLIC (decl) = 1;
+ determine_visibility (decl);
+}
+
/* Push a tag name NAME for struct/class/union/enum type TYPE. In case
that the NAME is a class template, the tag is processed but not pushed.
@@ -4942,7 +4956,10 @@ pushtag (tree name, tree type, tag_scope
decl = maybe_process_template_type_declaration
(type, scope == ts_within_enclosing_non_class, b);
if (decl == error_mark_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+ {
+ pushtag_finish_type (type);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ }
if (! in_class)
set_identifier_type_value_with_scope (name, tdef, b);
@@ -4962,7 +4979,10 @@ pushtag (tree name, tree type, tag_scope
{
decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
if (decl == error_mark_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+ {
+ pushtag_finish_type (type);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ }
}
TYPE_CONTEXT (type) = DECL_CONTEXT (decl);
@@ -4991,13 +5011,7 @@ pushtag (tree name, tree type, tag_scope
(CLASSTYPE_NESTED_UTDS (current_class_type), name, type);
}
- decl = TYPE_NAME (type);
- gcc_assert (TREE_CODE (decl) == TYPE_DECL);
- TYPE_STUB_DECL (type) = decl;
-
- /* Set type visibility now if this is a forward declaration. */
- TREE_PUBLIC (decl) = 1;
- determine_visibility (decl);
+ pushtag_finish_type (type);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
}
2007-09-08 Simon Martin <simartin@users.sourceforge.net>
PR c++/33207
* g++.dg/parse/crash38.C: New test.
/* PR c++/33207 */
/* This used to ICE. */
namespace N { } /* { dg-error "previous declaration" } */
struct N; /* { dg-error "redeclared as different kind of symbol" } */
struct N* p;