]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/41123 (ICE in expand_expr_real_1)
authorJakub Jelinek <jakub@redhat.com>
Wed, 19 Aug 2009 22:51:20 +0000 (00:51 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 19 Aug 2009 22:51:20 +0000 (00:51 +0200)
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.

* gcc.dg/pr41123.c: New test.

From-SVN: r150946

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr41123.c [new file with mode: 0644]

index 76f606046f8ab756be3a8fb5addf0e902d171f16..3a6e261997495f131a9024c5381dac9f093c20cc 100644 (file)
@@ -1,3 +1,9 @@
+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
index 08c747ecffbb7d79119122ffb06c056bfeaab8dd..6805cdc6e6df427ed168567aab7b7dc908cf1e47 100644 (file)
@@ -7871,6 +7871,33 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
                          || 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)
@@ -7944,16 +7971,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
            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
index a29294938c46030ae082785f7baa5ca5616e716d..993f2c3bfecbe3789ed6e628543e8593486e96db 100644 (file)
@@ -1,3 +1,8 @@
+2009-08-19  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/41123
+       * gcc.dg/pr41123.c: New test.
+
 2009-08-19  Jason Merrill  <jason@redhat.com>
 
        PR c++/41120
diff --git a/gcc/testsuite/gcc.dg/pr41123.c b/gcc/testsuite/gcc.dg/pr41123.c
new file mode 100644 (file)
index 0000000..076edb4
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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;
+}