diff options
author | Richard Kenner <kenner@vlsi1.ultra.nyu.edu> | 2004-04-12 21:25:55 +0000 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2004-04-12 17:25:55 -0400 |
commit | 1c9766da11d71cb57f8962a2eb88833c1ca966f5 (patch) | |
tree | fc6c6b14412060a9d6d90d3f45c768a4648b7f4b /gcc/stor-layout.c | |
parent | 040e098a5de9115501bd76ce0ea7adc9a0eded21 (diff) | |
download | gcc-1c9766da11d71cb57f8962a2eb88833c1ca966f5.tar.gz |
c-decl.c (finish_decl): Make a decl_stmt for a variable-sized TYPE_DECL.
* c-decl.c (finish_decl): Make a decl_stmt for a variable-sized
TYPE_DECL.
* c-semantics.c (genrtl_decl_stmt): Handle TYPE_DECL.
* stmt.c (expand_decl): Remove redundant expansion of TYPE_DOMAIN.
* stor-layout.c (variable_size): Don't check for MINUS_EXPR.
Use skip_simple_arithmetic to find SAVE_EXPR.
(force_type_save_exprs, force_type_save_exprs_1): New functions.
* tree-inline.c (remap_type, case POINTER_TYPE, case REFERENCE_TYPE):
Properly chain multiple pointers.
(copy_tree_r): Copy a TYPE_DECL.
* tree.c (variably_modified_type_p): Add some missing tests and
make some other minor changes.
* tree.h (force_type_save_exprs): New declaration.
* gcc.c-torture/execute/20040411-1.c: New test.
From-SVN: r80629
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 63 |
1 files changed, 57 insertions, 6 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 2baa36432a4..d19fc9fdf3f 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -66,6 +66,7 @@ static void place_union_field (record_layout_info, tree); static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, tree); #endif +static void force_type_save_exprs_1 (tree); static unsigned int update_alignment_for_field (record_layout_info, tree, unsigned int); extern void debug_rli (record_layout_info); @@ -146,12 +147,7 @@ variable_size (tree size) || CONTAINS_PLACEHOLDER_P (size)) return size; - if (TREE_CODE (size) == MINUS_EXPR && integer_onep (TREE_OPERAND (size, 1))) - /* If this is the upper bound of a C array, leave the minus 1 outside - the SAVE_EXPR so it can be folded away. */ - TREE_OPERAND (size, 0) = save = save_expr (TREE_OPERAND (size, 0)); - else - size = save = save_expr (size); + size = save_expr (size); /* If an array with a variable number of elements is declared, and the elements require destruction, we will emit a cleanup for the @@ -161,6 +157,7 @@ variable_size (tree size) `unsaved', i.e., all SAVE_EXPRs are recalculated. However, we do not wish to do that here; the array-size is the same in both places. */ + save = skip_simple_arithmetic (size); if (TREE_CODE (save) == SAVE_EXPR) SAVE_EXPR_PERSISTENT_P (save) = 1; @@ -185,6 +182,60 @@ variable_size (tree size) return size; } + +/* Given a type T, force elaboration of any SAVE_EXPRs used in the definition + of that type. */ + +void +force_type_save_exprs (tree t) +{ + tree field; + + switch (TREE_CODE (t)) + { + case ERROR_MARK: + return; + + case ARRAY_TYPE: + case SET_TYPE: + case VECTOR_TYPE: + /* It's probably overly-conservative to force elaboration of bounds and + also the sizes, but it's better to be safe than sorry. */ + force_type_save_exprs_1 (TYPE_MIN_VALUE (TYPE_DOMAIN (t))); + force_type_save_exprs_1 (TYPE_MAX_VALUE (TYPE_DOMAIN (t))); + break; + + case RECORD_TYPE: + case UNION_TYPE: + case QUAL_UNION_TYPE: + for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL) + { + force_type_save_exprs (TREE_TYPE (field)); + force_type_save_exprs_1 (DECL_FIELD_OFFSET (field)); + } + break; + + default: + break; + } + + force_type_save_exprs_1 (TYPE_SIZE (t)); + force_type_save_exprs_1 (TYPE_SIZE_UNIT (t)); +} + +/* Utility routine of above, to verify that SIZE has been elaborated and + do so it it is a SAVE_EXPR and has not been. */ + +static void +force_type_save_exprs_1 (tree size) +{ + if (size + && (size = skip_simple_arithmetic (size)) + && TREE_CODE (size) == SAVE_EXPR + && !SAVE_EXPR_RTL (size)) + expand_expr (size, NULL_RTX, VOIDmode, 0); +} #ifndef MAX_FIXED_MODE_SIZE #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode) |