[PATCH] Fix expansion ICE with VOIDmode MEM (PR middle-end/46388)
Jakub Jelinek
jakub@redhat.com
Wed Nov 10 23:22:00 GMT 2010
Hi!
On IA-64 the attached testcase segfaults, because the DECL_EXTERNAL
var u has incomplete type and during expansion we create VOIDmode MEM
for it (that VAR_DECL is the get_inner_reference result, we of course
have non-VOIDmode mode we are accessing it through in the MEM_REF).
In some versions of the store_field code which happens to be used
on this testcase on ia64 the VOIDmode MEM leads to ICEs.
I think we just should avoid having VOIDmode MEM around whenever possible,
the following patch fixes it by using the MEM_REF access mode instead
(alternatively we could always use BLKmode for it).
Bootstrapped/regtested on x86_64-linux and i686-linux, tested on the
testcase with cross to ia64-linux. Ok for trunk?
2010-11-10 Jakub Jelinek <jakub@redhat.com>
PR middle-end/46388
* expr.c (expand_assignment): If to_rtx is a VOIDmode MEM, use
mode1 mode for it.
(expand_expr_real_1): Similarly for op0.
* gcc.c-torture/compile/pr46388.c: New test.
--- gcc/expr.c.jj 2010-11-09 13:58:30.000000000 +0100
+++ gcc/expr.c 2010-11-10 11:37:53.000000000 +0100
@@ -4260,10 +4260,11 @@ expand_assignment (tree to, tree from, b
to_rtx = expand_normal (tem);
/* If the bitfield is volatile, we want to access it in the
- field's mode, not the computed mode. */
- if (volatilep
- && GET_CODE (to_rtx) == MEM
- && flag_strict_volatile_bitfields > 0)
+ field's mode, not the computed mode.
+ Similarly, if MEM has a VOIDmode (external with incomplete type). */
+ if (MEM_P (to_rtx)
+ && ((volatilep && flag_strict_volatile_bitfields > 0)
+ || GET_MODE (to_rtx) == VOIDmode))
to_rtx = adjust_address (to_rtx, mode1, 0);
if (offset != 0)
@@ -9013,10 +9014,12 @@ expand_expr_real_1 (tree exp, rtx target
/* If the bitfield is volatile, we want to access it in the
- field's mode, not the computed mode. */
- if (volatilep
- && GET_CODE (op0) == MEM
- && flag_strict_volatile_bitfields > 0)
+ field's mode, not the computed mode.
+ Similarly, if MEM has a VOIDmode (external with incomplete
+ type). */
+ if (MEM_P (op0)
+ && ((volatilep && flag_strict_volatile_bitfields > 0)
+ || GET_MODE (op0) == VOIDmode))
op0 = adjust_address (op0, mode1, 0);
mode2
--- gcc/testsuite/gcc.c-torture/compile/pr46388.c.jj 2010-11-10 11:45:52.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr46388.c 2010-11-10 11:45:37.000000000 +0100
@@ -0,0 +1,14 @@
+/* PR middle-end/46388 */
+
+struct S;
+struct T
+{
+ struct S *t;
+};
+extern struct S s, u;
+
+void
+foo (void)
+{
+ ((struct T *) &u)->t = &s;
+}
Jakub
More information about the Gcc-patches
mailing list