aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-01-29 18:33:27 -0800
committerRichard Henderson <rth@gcc.gnu.org>2005-01-29 18:33:27 -0800
commit8d74033081ff4815c2ff92dd8371c650d7bd1b7c (patch)
treea17b3c109913e98389dfb0d728464f79bd38a700 /gcc
parent486e432615e3a3e526044f3002db03a0ddbc04b5 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/expr.c18
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr19689.c19
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.
diff --git a/gcc/expr.c b/gcc/expr.c
index 29acbba..ab7cf93 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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;
+}