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
This commit is contained in:
Eric Botcazou 2012-11-05 21:39:02 +00:00 committed by Eric Botcazou
parent 511d31d856
commit 506190022d
4 changed files with 59 additions and 2 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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);
}