diff options
author | Richard Henderson <rth@redhat.com> | 2005-01-29 18:33:27 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-01-29 18:33:27 -0800 |
commit | 8d74033081ff4815c2ff92dd8371c650d7bd1b7c (patch) | |
tree | a17b3c109913e98389dfb0d728464f79bd38a700 /gcc | |
parent | 486e432615e3a3e526044f3002db03a0ddbc04b5 (diff) | |
download | gcc-8d74033081ff4815c2ff92dd8371c650d7bd1b7c.zip gcc-8d74033081ff4815c2ff92dd8371c650d7bd1b7c.tar.gz gcc-8d74033081ff4815c2ff92dd8371c650d7bd1b7c.tar.bz2 |
re PR middle-end/19689 (ICE in store_bit_field, at expmed.c)
PR middle-end/19689
* expr.c (store_field): Don't strip sub-mode cast when the input
data is even smaller.
From-SVN: r94429
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expr.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr19689.c | 19 |
3 files changed, 37 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f3bcde3..c56c728 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2005-01-29 Richard Henderson <rth@redhat.com> + PR middle-end/19689 + * expr.c (store_field): Don't strip sub-mode cast when the input + data is even smaller. + +2005-01-29 Richard Henderson <rth@redhat.com> + PR middle-end/19687 * expr.c (categorize_ctor_elements_1): Check for CONSTRUCTOR of a union being empty. @@ -5226,12 +5226,18 @@ store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, 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); + if (TREE_CODE (exp) == NOP_EXPR) + { + tree type = TREE_TYPE (exp); + if (INTEGRAL_TYPE_P (type) + && TYPE_PRECISION (type) < GET_MODE_BITSIZE (TYPE_MODE (type)) + && bitsize == TYPE_PRECISION (type)) + { + type = TREE_TYPE (TREE_OPERAND (exp, 0)); + if (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) >= bitsize) + exp = TREE_OPERAND (exp, 0); + } + } temp = expand_expr (exp, NULL_RTX, VOIDmode, 0); diff --git a/gcc/testsuite/gcc.c-torture/execute/pr19689.c b/gcc/testsuite/gcc.c-torture/execute/pr19689.c new file mode 100644 index 0000000..608415f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr19689.c @@ -0,0 +1,19 @@ +extern void abort (void); + +struct +{ + int b : 29; +} f; + +void foo (short j) +{ + f.b = j; +} + +int main() +{ + foo (-55); + if (f.b != -55) + abort (); + return 0; +} |