aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/gimple-fold.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr89698.C29
4 files changed, 53 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 65df011..5973192 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
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.
+
+2019-05-03 Richard Biener <rguenther@suse.de>
+
* passes.c (execute_function_todo): Remove dead code.
2019-05-02 Segher Boessenkool <segher@kernel.crashing.org>
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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ad12005..660110d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-05-03 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/89698
+ * g++.dg/tree-ssa/pr89698.C: New testcase.
+
2019-05-02 Iain Sandoe <iain@sandoe.co.uk>
* g++.dg/ext/instantiate2.C: Remove special-casing for Darwin.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr89698.C b/gcc/testsuite/g++.dg/tree-ssa/pr89698.C
new file mode 100644
index 0000000..9d3b408
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr89698.C
@@ -0,0 +1,29 @@
+// { dg-do compile }
+// { dg-options "-O -fdump-tree-fre1" }
+
+class A {
+ virtual void f(){};
+public:
+ int x;
+ A(int in): x(in) {};
+};
+
+class B: public A {
+public:
+ int y;
+ B(int in):A(in-1), y(in) {};
+};
+
+void bar(void *);
+void test()
+{
+ B b(2);
+ A* bp = &b;
+ void* vp = dynamic_cast<void*>(bp);
+ bar (vp);
+}
+
+// We should be able to constant fold from the virtual table
+// the offset added to bp for the dynamic cast and forward
+// &b to the argument of bar
+// { dg-final { scan-tree-dump "bar \\\(&b" "fre1" } }