diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1994-07-08 14:41:02 -0700 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1994-07-08 14:41:02 -0700 |
commit | 6be583037c3cc9bd254d252e6b50a7f3dba27879 (patch) | |
tree | 2b4729609923f7fbc449e6e7b58c0af83ed45d71 /gcc/expr.c | |
parent | 4ee16841d49a370564703362a152dfd75412d6ad (diff) | |
download | gcc-6be583037c3cc9bd254d252e6b50a7f3dba27879.zip gcc-6be583037c3cc9bd254d252e6b50a7f3dba27879.tar.gz gcc-6be583037c3cc9bd254d252e6b50a7f3dba27879.tar.bz2 |
(get_inner_unaligned_p): New function.
(expand_assignment, expand_expr): Use it.
From-SVN: r7685
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 50 |
1 files changed, 43 insertions, 7 deletions
@@ -147,6 +147,7 @@ static void move_by_pieces_1 PROTO((rtx (*) (), enum machine_mode, static void store_constructor PROTO((tree, rtx)); static rtx store_field PROTO((rtx, int, int, enum machine_mode, tree, enum machine_mode, int, int, int)); +static int get_inner_unaligned_p PROTO((tree)); static tree save_noncopied_parts PROTO((tree, tree)); static tree init_noncopied_parts PROTO((tree, tree)); static int safe_from_p PROTO((rtx, tree)); @@ -2353,14 +2354,16 @@ expand_assignment (to, from, want_value, suggest_reg) /* Assignment of a structure component needs special treatment if the structure component's rtx is not simply a MEM. - Assignment of an array element at a constant index - has the same problem. */ + Assignment of an array element at a constant index, and assignment of + an array element in an unaligned packed structure field, has the same + problem. */ if (TREE_CODE (to) == COMPONENT_REF || TREE_CODE (to) == BIT_FIELD_REF || (TREE_CODE (to) == ARRAY_REF - && TREE_CODE (TREE_OPERAND (to, 1)) == INTEGER_CST - && TREE_CODE (TYPE_SIZE (TREE_TYPE (to))) == INTEGER_CST)) + && ((TREE_CODE (TREE_OPERAND (to, 1)) == INTEGER_CST + && TREE_CODE (TYPE_SIZE (TREE_TYPE (to))) == INTEGER_CST) + || (STRICT_ALIGNMENT && get_inner_unaligned_p (to))))) { enum machine_mode mode1; int bitsize; @@ -3126,6 +3129,37 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, } } +/* Return true if any object containing the innermost array is an unaligned + packed structure field. */ + +static int +get_inner_unaligned_p (exp) + tree exp; +{ + int needed_alignment = TYPE_ALIGN (TREE_TYPE (exp)); + + while (1) + { + if (TREE_CODE (exp) == COMPONENT_REF || TREE_CODE (exp) == BIT_FIELD_REF) + { + if (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0))) + < needed_alignment) + return 1; + } + else if (TREE_CODE (exp) != ARRAY_REF + && TREE_CODE (exp) != NON_LVALUE_EXPR + && ! ((TREE_CODE (exp) == NOP_EXPR + || TREE_CODE (exp) == CONVERT_EXPR) + && (TYPE_MODE (TREE_TYPE (exp)) + == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))))) + break; + + exp = TREE_OPERAND (exp, 0); + } + + return 0; +} + /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF, or an ARRAY_REF, look for nested COMPONENT_REFs, BIT_FIELD_REFs, or ARRAY_REFs and find the ultimate containing object, which we return. @@ -4232,10 +4266,12 @@ expand_expr (exp, target, tmode, modifier) index = fold (build (MINUS_EXPR, index_type, index, convert (sizetype, low_bound))); - if (TREE_CODE (index) != INTEGER_CST - || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + if ((TREE_CODE (index) != INTEGER_CST + || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + && (! STRICT_ALIGNMENT || ! get_inner_unaligned_p (exp))) { - /* Nonconstant array index or nonconstant element size. + /* Nonconstant array index or nonconstant element size, and + not an array in an unaligned (packed) structure field. Generate the tree for *(&array+index) and expand that, except do it in a language-independent way and don't complain about non-lvalue arrays. |