diff options
author | Jason Merrill <merrill@gnu.org> | 1994-10-11 18:39:14 +0000 |
---|---|---|
committer | Jason Merrill <merrill@gnu.org> | 1994-10-11 18:39:14 +0000 |
commit | 0171aeabee95d99ba1c6988f98210409a62b37c4 (patch) | |
tree | 2a8b84d728ba429a675a6a9f4d1ab449ec0a3632 | |
parent | fef71f9d2bc4f87bd2ea6c8874a00f76ba8b0676 (diff) | |
download | gcc-0171aeabee95d99ba1c6988f98210409a62b37c4.zip gcc-0171aeabee95d99ba1c6988f98210409a62b37c4.tar.gz gcc-0171aeabee95d99ba1c6988f98210409a62b37c4.tar.bz2 |
(do_build_copy_constructor): Handle anonymous unions.
(do_build_assign_ref): Ditto.
(largest_union_member): Move from lex.c.
From-SVN: r8253
-rw-r--r-- | gcc/cp/method.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/gcc/cp/method.c b/gcc/cp/method.c index f32d005..23fffe4 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1980,6 +1980,23 @@ build_default_constructor (fndecl) finish_function (lineno, 0); } +/* For the anonymous union in TYPE, return the member that is at least as + large as the rest of the members, so we can copy it. */ +static tree +largest_union_member (type) + tree type; +{ + tree f, type_size = TYPE_SIZE (type); + + for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f)) + if (simple_cst_equal (DECL_SIZE (f), type_size)) + return f; + + /* We should always find one. */ + my_friendly_abort (323); + return NULL_TREE; +} + /* Generate code for default X(X&) constructor. */ void build_copy_constructor (fndecl) @@ -2034,7 +2051,7 @@ build_copy_constructor (fndecl) } for (; fields; fields = TREE_CHAIN (fields)) { - tree name, init; + tree name, init, t; if (TREE_CODE (fields) != FIELD_DECL) continue; if (DECL_NAME (fields)) @@ -2048,6 +2065,13 @@ build_copy_constructor (fndecl) if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) continue; } + else if ((t = TREE_TYPE (fields)) != NULL_TREE + && TREE_CODE (t) == UNION_TYPE + && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)) + && TYPE_FIELDS (t) != NULL_TREE) + fields = largest_union_member (t); + else + continue; init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); init = build_tree_list (NULL_TREE, init); @@ -2103,7 +2127,7 @@ build_assign_ref (fndecl) } for (; fields; fields = TREE_CHAIN (fields)) { - tree comp, init; + tree comp, init, t; if (TREE_CODE (fields) != FIELD_DECL) continue; if (DECL_NAME (fields)) @@ -2117,6 +2141,13 @@ build_assign_ref (fndecl) if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) continue; } + else if ((t = TREE_TYPE (fields)) != NULL_TREE + && TREE_CODE (t) == UNION_TYPE + && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)) + && TYPE_FIELDS (t) != NULL_TREE) + fields = largest_union_member (t); + else + continue; comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields); init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); |