From 693ddb1be71474a9777ac330d2d1cb5db3e800fb Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 6 Sep 2011 21:17:46 +0000 Subject: [PATCH] re PR middle-end/50266 (ICE in decode_addr_const) PR middle-end/50266 * c-common.c (c_fully_fold_internal) : Fold offsetof-like computations. From-SVN: r178611 --- gcc/c-family/ChangeLog | 6 +++++ gcc/c-family/c-common.c | 15 ++++++++++++- gcc/testsuite/ChangeLog | 4 ++++ .../gcc.c-torture/compile/20110906-1.c | 22 +++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20110906-1.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 95abde6b7fc..347d904205f 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2011-09-06 Eric Botcazou + + PR middle-end/50266 + * c-common.c (c_fully_fold_internal) : Fold offsetof-like + computations. + 2011-09-05 Richard Guenther * 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 9c42d5944da..d8028d34878 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 802525053a8..269cdffefc2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-09-06 Eric Botcazou + +        * gcc.c-torture/compile/20110906-1.c: New test. + 2011-09-06 Uros Bizjak * 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 00000000000..50ea9e241b4 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20110906-1.c @@ -0,0 +1,22 @@ +/* PR middle-end/50266 */ +/* Testcase by */ + +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]))))); +} -- 2.30.2