+2009-08-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/41123
+ * expr.c (expand_expr_real_1) <normal_inner_ref>: Handle all kinds
+ of CONCAT, not just bitpos 0 bitsize size of the whole CONCAT.
+
2009-08-19 Jason Merrill <jason@redhat.com>
* doc/invoke.texi (C++ Dialect Options): Note change of minimum
|| mode1 == BLKmode
|| bitpos + bitsize > GET_MODE_BITSIZE (mode2));
+ /* Handle CONCAT first. */
+ if (GET_CODE (op0) == CONCAT && !must_force_mem)
+ {
+ if (bitpos == 0
+ && bitsize == GET_MODE_BITSIZE (GET_MODE (op0)))
+ return op0;
+ if (bitpos == 0
+ && bitsize == GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
+ && bitsize)
+ {
+ op0 = XEXP (op0, 0);
+ mode2 = GET_MODE (op0);
+ }
+ else if (bitpos == GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0)))
+ && bitsize == GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1)))
+ && bitpos
+ && bitsize)
+ {
+ op0 = XEXP (op0, 1);
+ bitpos = 0;
+ mode2 = GET_MODE (op0);
+ }
+ else
+ /* Otherwise force into memory. */
+ must_force_mem = 1;
+ }
+
/* If this is a constant, put it in a register if it is a legitimate
constant and we don't need a memory reference. */
if (CONSTANT_P (op0)
MEM_VOLATILE_P (op0) = 1;
}
- /* The following code doesn't handle CONCAT.
- Assume only bitpos == 0 can be used for CONCAT, due to
- one element arrays having the same mode as its element. */
- if (GET_CODE (op0) == CONCAT)
- {
- gcc_assert (bitpos == 0
- && bitsize == GET_MODE_BITSIZE (GET_MODE (op0)));
- return op0;
- }
-
/* In cases where an aligned union has an unaligned object
as a field, we might be extracting a BLKmode value from
an integer-mode (e.g., SImode) object. Handle this case
--- /dev/null
+/* PR middle-end/41123 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-strict-aliasing" } */
+
+struct S { char a, b, c, d, e, f, g, h; };
+struct T { int a, b; };
+
+struct S
+f1 (float _Complex x)
+{
+ return *(struct S *) & x;
+}
+
+int
+f2 (float _Complex x)
+{
+ struct S f = f1 (x);
+ return f.b;
+}
+
+struct T
+f3 (float _Complex x)
+{
+ return *(struct T *) & x;
+}
+
+int
+f4 (float _Complex x)
+{
+ struct T f = f3 (x);
+ return f.a;
+}
+
+int
+f5 (float _Complex x)
+{
+ struct T f = f3 (x);
+ return f.b;
+}
+
+struct T
+f6 (float _Complex x)
+{
+ struct T f = f3 (x);
+ return f;
+}