aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-05-03 07:07:28 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-05-03 07:07:28 +0000
commit37f808c4a683a7431b7aa6d49f4c2e385cc0d707 (patch)
tree17b318f02a0ab1defcde8d90f4cc17251ff68994 /gcc/gimple-fold.c
parentc0f9d1fd7e54434e4f06b20b9a61a9d35c578223 (diff)
downloadgcc-37f808c4a683a7431b7aa6d49f4c2e385cc0d707.zip
gcc-37f808c4a683a7431b7aa6d49f4c2e385cc0d707.tar.gz
gcc-37f808c4a683a7431b7aa6d49f4c2e385cc0d707.tar.bz2
re PR c++/89698 (Run-time error due to optimization of field access after cast at -Os/-O2 and higher)
2019-05-03 Richard Biener <rguenther@suse.de> PR tree-optimization/89698 * gimple-fold.c (canonicalize_constructor_val): Early out for constants, handle unfolded INTEGER_CSTs as they appear in C++ virtual table ctors. * g++.dg/tree-ssa/pr89698.C: New testcase. From-SVN: r270833
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r--gcc/gimple-fold.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index d3ef05b..1b10bae 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -207,6 +207,9 @@ create_tmp_reg_or_ssa_name (tree type, gimple *stmt)
tree
canonicalize_constructor_val (tree cval, tree from_decl)
{
+ if (CONSTANT_CLASS_P (cval))
+ return cval;
+
tree orig_cval = cval;
STRIP_NOPS (cval);
if (TREE_CODE (cval) == POINTER_PLUS_EXPR
@@ -257,8 +260,15 @@ canonicalize_constructor_val (tree cval, tree from_decl)
cval = fold_convert (TREE_TYPE (orig_cval), cval);
return cval;
}
- if (TREE_OVERFLOW_P (cval))
- return drop_tree_overflow (cval);
+ /* In CONSTRUCTORs we may see unfolded constants like (int (*) ()) 0. */
+ if (TREE_CODE (cval) == INTEGER_CST)
+ {
+ if (TREE_OVERFLOW_P (cval))
+ cval = drop_tree_overflow (cval);
+ if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
+ cval = fold_convert (TREE_TYPE (orig_cval), cval);
+ return cval;
+ }
return orig_cval;
}