Commit 48cc8d3b by Richard Henderson Committed by Richard Henderson

For real this time...

        PR middle-end/18008
        * c-decl.c (finish_struct): Set DECL_MODE after resetting a
        field's type.
        * expr.c (store_field): Strip conversions to odd-bit-sized types
        if the destination field width matches.

From-SVN: r94294
parent eec6bb06
2005-01-26 Richard Henderson <rth@redhat.com> 2005-01-26 Richard Henderson <rth@redhat.com>
PR middle-end/18008
* c-decl.c (finish_struct): Set DECL_MODE after resetting a
field's type.
* expr.c (store_field): Strip conversions to odd-bit-sized types
if the destination field width matches.
2005-01-26 Richard Henderson <rth@redhat.com>
* c-decl.c, expmed.c, expr.c: Revert last change. * c-decl.c, expmed.c, expr.c: Revert last change.
2005-01-26 Richard Henderson <rth@redhat.com> 2005-01-26 Richard Henderson <rth@redhat.com>
......
...@@ -5301,8 +5301,11 @@ finish_struct (tree t, tree fieldlist, tree attributes) ...@@ -5301,8 +5301,11 @@ finish_struct (tree t, tree fieldlist, tree attributes)
= tree_low_cst (DECL_INITIAL (*fieldlistp), 1); = tree_low_cst (DECL_INITIAL (*fieldlistp), 1);
tree type = TREE_TYPE (*fieldlistp); tree type = TREE_TYPE (*fieldlistp);
if (width != TYPE_PRECISION (type)) if (width != TYPE_PRECISION (type))
TREE_TYPE (*fieldlistp) {
= build_nonstandard_integer_type (width, TYPE_UNSIGNED (type)); TREE_TYPE (*fieldlistp)
= build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp));
}
DECL_INITIAL (*fieldlistp) = 0; DECL_INITIAL (*fieldlistp) = 0;
} }
else else
......
...@@ -5215,7 +5215,21 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, ...@@ -5215,7 +5215,21 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST
&& compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0)) && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0))
{ {
rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0); rtx temp;
/* If EXP is a NOP_EXPR of precision less than its mode, then that
implies a mask operation. If the precision is the same size as
the field we're storing into, that mask is redundant. This is
particularly common with bit field assignments generated by the
C front end. */
if (TREE_CODE (exp) == NOP_EXPR
&& INTEGRAL_TYPE_P (TREE_TYPE (exp))
&& (TYPE_PRECISION (TREE_TYPE (exp))
< GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp))))
&& bitsize == TYPE_PRECISION (TREE_TYPE (exp)))
exp = TREE_OPERAND (exp, 0);
temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
/* If BITSIZE is narrower than the size of the type of EXP /* If BITSIZE is narrower than the size of the type of EXP
we will be narrowing TEMP. Normally, what's wanted are the we will be narrowing TEMP. Normally, what's wanted are the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment