From 37f808c4a683a7431b7aa6d49f4c2e385cc0d707 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 3 May 2019 07:07:28 +0000 Subject: [PATCH] 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 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 --- gcc/ChangeLog | 7 ++++++ gcc/gimple-fold.c | 14 ++++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/tree-ssa/pr89698.C | 29 +++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr89698.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 65df01190cc..5973192491a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-05-03 Richard Biener + + 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 * passes.c (execute_function_todo): Remove dead code. diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index d3ef05b5243..1b10bae55ca 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 ad12005d18e..660110d0493 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-05-03 Richard Biener + + PR tree-optimization/89698 + * g++.dg/tree-ssa/pr89698.C: New testcase. + 2019-05-02 Iain Sandoe * 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 00000000000..9d3b408afbd --- /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(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" } } -- 2.30.2