PATCH for crash with anonymous unions
Mark Mitchell
mmitchell@usa.net
Tue May 19 19:49:00 GMT 1998
Jason --
Here's a patch for the abort on code like this:
static union {
union {
};
};
This used to cause a crash. OK?
--
Mark Mitchell <mmitchell@usa.net>
http://home.earthlink.net/~mbmitchell
Consulting Services Available
Tue May 19 15:48:01 1998 Mark Mitchell <mmitchell@usa.net>
* decl2.c (find_representative_member): New function.
(finish_anon_union): Use it.
Index: decl2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl2.c,v
retrieving revision 1.71
diff -c -p -r1.71 decl2.c
*** decl2.c 1998/05/18 23:23:05 1.71
--- decl2.c 1998/05/19 22:49:32
*************** static int is_namespace_ancestor PROTO((
*** 52,57 ****
--- 52,58 ----
static tree namespace_ancestor PROTO((tree, tree));
static void add_using_namespace PROTO((tree, tree, int));
static tree ambiguous_decl PROTO((tree, tree, tree));
+ static tree find_representative_member PROTO((tree));
extern int current_class_depth;
*************** get_temp_regvar (type, init)
*** 2144,2149 ****
--- 2148,2186 ----
return decl;
}
+ /* Hunt through ANON_DECL, which declares an anonymous union, for a named
+ member of the same size as ANON_DECL. */
+
+ tree
+ find_representative_member (anon_decl)
+ tree anon_decl;
+ {
+ tree field;
+ tree main_decl = NULL_TREE;
+
+ for (field = TYPE_FIELDS (TREE_TYPE (anon_decl));
+ field != NULL_TREE;
+ field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ /* Only write out one anon union element--choose the one that
+ can hold them all. */
+ if (main_decl == NULL_TREE
+ && 1 == simple_cst_equal (DECL_SIZE (field),
+ DECL_SIZE (anon_decl)))
+ main_decl =
+ DECL_NAME (field) ? field : find_representative_member (field);
+ else
+ /* ??? This causes there to be no debug info written out
+ about this decl. */
+ TREE_ASM_WRITTEN (field) = 1;
+ }
+
+ return main_decl;
+ }
+
/* Finish off the processing of a UNION_TYPE structure.
If there are static members, then all members are
static, and must be laid out together. If the
*************** finish_anon_union (anon_union_decl)
*** 2156,2168 ****
tree anon_union_decl;
{
tree type = TREE_TYPE (anon_union_decl);
! tree field, main_decl = NULL_TREE;
tree elems = NULL_TREE;
int public_p = TREE_PUBLIC (anon_union_decl);
int static_p = TREE_STATIC (anon_union_decl);
int external_p = DECL_EXTERNAL (anon_union_decl);
! if ((field = TYPE_FIELDS (type)) == NULL_TREE)
return;
if (public_p)
--- 2193,2205 ----
tree anon_union_decl;
{
tree type = TREE_TYPE (anon_union_decl);
! tree field = TYPE_FIELDS (type);
tree elems = NULL_TREE;
int public_p = TREE_PUBLIC (anon_union_decl);
int static_p = TREE_STATIC (anon_union_decl);
int external_p = DECL_EXTERNAL (anon_union_decl);
! if (field == NULL_TREE)
return;
if (public_p)
*************** finish_anon_union (anon_union_decl)
*** 2182,2187 ****
--- 2219,2231 ----
else if (TREE_PROTECTED (field))
cp_pedwarn_at ("protected member `%#D' in anonymous union", field);
+ if (DECL_NAME (field) == NULL_TREE
+ && find_representative_member (field) == NULL_TREE)
+ /* The member is an empty anonymous union. Don't make a
+ declaration for it, as finish_file will otherwise try to
+ call make_decl_rtl for it, and crash. */
+ continue;
+
decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
/* tell `pushdecl' that this is not tentative. */
DECL_INITIAL (decl) = error_mark_node;
*************** finish_anon_union (anon_union_decl)
*** 2190,2218 ****
DECL_EXTERNAL (decl) = external_p;
decl = pushdecl (decl);
- /* Only write out one anon union element--choose the one that
- can hold them all. */
- if (main_decl == NULL_TREE
- && 1 == simple_cst_equal (DECL_SIZE (decl),
- DECL_SIZE (anon_union_decl)))
- {
- main_decl = decl;
- }
- else
- {
- /* ??? This causes there to be no debug info written out
- about this decl. */
- TREE_ASM_WRITTEN (decl) = 1;
- }
-
DECL_INITIAL (decl) = NULL_TREE;
/* If there's a cleanup to do, it belongs in the
TREE_PURPOSE of the following TREE_LIST. */
elems = scratch_tree_cons (NULL_TREE, decl, elems);
TREE_TYPE (elems) = type;
}
if (static_p)
{
if (main_decl)
{
make_decl_rtl (main_decl, 0, toplevel_bindings_p ());
--- 2234,2250 ----
DECL_EXTERNAL (decl) = external_p;
decl = pushdecl (decl);
DECL_INITIAL (decl) = NULL_TREE;
/* If there's a cleanup to do, it belongs in the
TREE_PURPOSE of the following TREE_LIST. */
elems = scratch_tree_cons (NULL_TREE, decl, elems);
TREE_TYPE (elems) = type;
}
+
if (static_p)
{
+ tree main_decl = find_representative_member (anon_union_decl);
+
if (main_decl)
{
make_decl_rtl (main_decl, 0, toplevel_bindings_p ());
More information about the Gcc-bugs
mailing list