diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2012-11-05 21:39:02 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2012-11-05 21:39:02 +0000 |
commit | 506190022dd74e36ec77214ad1959ed2dbc93c89 (patch) | |
tree | f22745b7cebb6afab88b205621100bdc82746322 /gcc | |
parent | 511d31d856ee3ecf3296f46aed7c8e15611793fb (diff) | |
download | gcc-506190022dd74e36ec77214ad1959ed2dbc93c89.zip gcc-506190022dd74e36ec77214ad1959ed2dbc93c89.tar.gz gcc-506190022dd74e36ec77214ad1959ed2dbc93c89.tar.bz2 |
re PR tree-optimization/54986 (segfault on constant initialized to object address at -O)
PR tree-optimization/54986
* gimple-fold.c (canonicalize_constructor_val): Strip again all no-op
conversions on entry but add them back on exit if needed.
From-SVN: r193188
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/20121105-1.C | 42 |
4 files changed, 59 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d0ba942..5fab821 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-11-05 Eric Botcazou <ebotcazou@adacore.com> + + PR tree-optimization/54986 + * gimple-fold.c (canonicalize_constructor_val): Strip again all no-op + conversions on entry but add them back on exit if needed. + 2012-11-05 Andreas Schwab <schwab@linux-m68k.org> * final.c (final_scan_insn) [HAVE_cc0]: Handle all comparison diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 66d0766..969cfeb 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -139,7 +139,8 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl) tree canonicalize_constructor_val (tree cval, tree from_decl) { - STRIP_USELESS_TYPE_CONVERSION (cval); + tree orig_cval = cval; + STRIP_NOPS (cval); if (TREE_CODE (cval) == POINTER_PLUS_EXPR && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST) { @@ -182,8 +183,12 @@ canonicalize_constructor_val (tree cval, tree from_decl) /* Fixup types in global initializers. */ if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0))) cval = build_fold_addr_expr (TREE_OPERAND (cval, 0)); + + if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval))) + cval = fold_convert (TREE_TYPE (orig_cval), cval); + return cval; } - return cval; + return orig_cval; } /* If SYM is a constant variable with known value, return the value. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af92ce4..e870aa5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-11-05 Eric Botcazou <ebotcazou@adacore.com> + + * g++.dg/torture/20121105-1.C: New test. + 2012-11-05 Andreas Schwab <schwab@linux-m68k.org> * gcc.dg/torture/fp-compare.c: New testcase. diff --git a/gcc/testsuite/g++.dg/torture/20121105-1.C b/gcc/testsuite/g++.dg/torture/20121105-1.C new file mode 100644 index 0000000..0332342 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/20121105-1.C @@ -0,0 +1,42 @@ +// PR tree-optimization/54986 +// Reported by Remi Vanicat <vanicat@debian.org> +// Reduced testcase by Markus Trippelsdorf <markus@trippelsdorf.de> + +struct A; +struct B +{ + int *_ptr; + bool operator==(B *p1) + { + return p1->_ptr; + } +}; +struct C { + A* ref_SYMBptr(); +}; +struct A +{ + B sommet; +}; +typedef C *gen_op_context; +struct D +{ + D(gen_op_context) {} +}; + +D c(0); +const long d = (long)&c; +B *const e = (B *)&d; + +static bool +fn1(C& p1) +{ + return p1.ref_SYMBptr()->sommet == e; +} + +void +fn2() +{ + C b; + fn1(b); +} |