diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2011-09-06 21:17:46 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-09-06 21:17:46 +0000 |
commit | 693ddb1be71474a9777ac330d2d1cb5db3e800fb (patch) | |
tree | f8ec4e3a49cb94b3bcb4c9ae1b5f59900b37958c /gcc | |
parent | 8092dd900b9483f1f8ec716c5d94a5686e669b0d (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/20110906-1.c | 22 |
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]))))); +} |