aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2011-09-06 21:17:46 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2011-09-06 21:17:46 +0000
commit693ddb1be71474a9777ac330d2d1cb5db3e800fb (patch)
treef8ec4e3a49cb94b3bcb4c9ae1b5f59900b37958c /gcc
parent8092dd900b9483f1f8ec716c5d94a5686e669b0d (diff)
downloadgcc-693ddb1be71474a9777ac330d2d1cb5db3e800fb.zip
gcc-693ddb1be71474a9777ac330d2d1cb5db3e800fb.tar.gz
gcc-693ddb1be71474a9777ac330d2d1cb5db3e800fb.tar.bz2
re PR middle-end/50266 (ICE in decode_addr_const)
PR middle-end/50266 * c-common.c (c_fully_fold_internal) <ADDR_EXPR>: Fold offsetof-like computations. From-SVN: r178611
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c15
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20110906-1.c22
4 files changed, 46 insertions, 1 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 95abde6..347d904 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 9c42d594..d8028d3 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8025250..269cdff 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..50ea9e2
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20110906-1.c
@@ -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])))));
+}