re PR middle-end/50266 (ICE in decode_addr_const)
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 6 Sep 2011 21:17:46 +0000 (21:17 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 6 Sep 2011 21:17:46 +0000 (21:17 +0000)
PR middle-end/50266
* c-common.c (c_fully_fold_internal) <ADDR_EXPR>: Fold offsetof-like
computations.

From-SVN: r178611

gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20110906-1.c [new file with mode: 0644]

index 95abde6b7fc35133faee19fb810312ecd0671db1..347d904205f026f806e6758b2b967a20c5acfd88 100644 (file)
@@ -1,3 +1,9 @@
+2011-09-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR middle-end/50266
+       * c-common.c (c_fully_fold_internal) <ADDR_EXPR>: Fold offsetof-like
+       computations.
+
 2011-09-05  Richard Guenther  <rguenther@suse.de>
 
        * c-common.c (complete_array_type): Use ssize_int (-1) instead
index 9c42d5944da862ef6d8aa044cd8466910ee5b96f..d8028d34878b38daafab0b9a97c6a839243646c8 100644 (file)
@@ -1264,7 +1264,20 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       STRIP_TYPE_NOPS (op0);
       if (code != ADDR_EXPR && code != REALPART_EXPR && code != IMAGPART_EXPR)
        op0 = decl_constant_value_for_optimization (op0);
-      if (op0 != orig_op0 || in_init)
+      /* ??? Cope with user tricks that amount to offsetof.  The middle-end is
+        not prepared to deal with them if they occur in initializers.  */
+      if (op0 != orig_op0
+         && code == ADDR_EXPR
+         && (op1 = get_base_address (op0)) != NULL_TREE
+         && TREE_CODE (op1) == INDIRECT_REF
+         && TREE_CONSTANT (TREE_OPERAND (op1, 0)))
+       {
+         tree offset = fold_offsetof (op0, op1);
+         op1
+           = fold_convert_loc (loc, TREE_TYPE (expr), TREE_OPERAND (op1, 0));
+         ret = fold_build_pointer_plus_loc (loc, op1, offset);
+       }
+      else if (op0 != orig_op0 || in_init)
        ret = in_init
          ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0)
          : fold_build1_loc (loc, code, TREE_TYPE (expr), op0);
index 802525053a8b3b8793dc8e03f0203c62f97f9640..269cdffefc265bb3d670ee790c104db0e6341c6b 100644 (file)
@@ -1,3 +1,7 @@
+2011-09-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+        * gcc.c-torture/compile/20110906-1.c: New test.
+
 2011-09-06  Uros Bizjak  <ubizjak@gmail.com>
 
        * gcc.target/i386/builtin-apply-mmx.c: Require ia32 effective target.
diff --git a/gcc/testsuite/gcc.c-torture/compile/20110906-1.c b/gcc/testsuite/gcc.c-torture/compile/20110906-1.c
new file mode 100644 (file)
index 0000000..50ea9e2
--- /dev/null
@@ -0,0 +1,22 @@
+/* PR middle-end/50266 */
+/* Testcase by <bero@arklinux.org> */
+
+struct a {
+ unsigned int a;
+ unsigned int b;
+};
+
+struct a *const p = (struct a *)0x4A004100;
+
+void foo(void)
+{
+ unsigned int i = 0;
+ unsigned int *const x[] = {
+  &p->a,
+  &p->b,
+  0
+ };
+
+ (*(volatile unsigned int *)((x[i]))
+   = (unsigned int)((unsigned int)((*(volatile unsigned int *)(x[i])))));
+}