From bed18fbd09667cbaecc3b8a99e05801a24e5324b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 31 Mar 2015 09:34:08 +0000 Subject: [PATCH] re PR c++/65626 (ICE in fixup_noreturn_call called by tree-ssa-forwprop.c:2492) 2015-03-31 Richard Biener PR middle-end/65626 * tree-cfgcleanup.c (fixup_noreturn_call): Only split the block of the noreturn call so it is last and cleanup_control_flow_bb can do the CFG part. * g++.dg/torture/pr65626.C: New testcase. From-SVN: r221790 --- gcc/ChangeLog | 7 +++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/torture/pr65626.C | 19 +++++++++++++++++++ gcc/tree-cfgcleanup.c | 19 ++++++++++++++----- 4 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr65626.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 189c3d8f3aa..36d83706a8d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-03-31 Richard Biener + + PR middle-end/65626 + * tree-cfgcleanup.c (fixup_noreturn_call): Only split the block + of the noreturn call so it is last and cleanup_control_flow_bb + can do the CFG part. + 2015-03-31 Ilya Enkovich PR target/65531 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index de247ed4446..f8adda19553 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-03-31 Richard Biener + + PR middle-end/65626 + * g++.dg/torture/pr65626.C: New testcase. + 2015-03-31 Ilya Enkovich PR target/65531 diff --git a/gcc/testsuite/g++.dg/torture/pr65626.C b/gcc/testsuite/g++.dg/torture/pr65626.C new file mode 100644 index 00000000000..ed85ba93830 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr65626.C @@ -0,0 +1,19 @@ +// { dg-do compile } + +class A { + virtual unsigned long m_fn1() const; + virtual int &m_fn2(unsigned long) const; +}; +class C : A { +public: + int &m_fn2(unsigned long) const; + unsigned long m_fn1() const; +}; +class B { + void m_fn3(const A &, const int &, const C &, int &) const; +}; +void B::m_fn3(const A &, const int &, const C &, int &) const { + C &a(a); + for (long b = 0; a.m_fn1(); b++) + a.m_fn2(0); +} diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index e7122e33c28..26258aad1ef 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -579,13 +579,15 @@ remove_forwarder_block (basic_block bb) return true; } -/* STMT is a call that has been discovered noreturn. Fixup the CFG - and remove LHS. Return true if something changed. */ +/* STMT is a call that has been discovered noreturn. Split the + block to prepare fixing up the CFG and remove LHS. + Return true if cleanup-cfg needs to run. */ bool fixup_noreturn_call (gimple stmt) { basic_block bb = gimple_bb (stmt); + bool changed = false; if (gimple_call_builtin_p (stmt, BUILT_IN_RETURN)) return false; @@ -604,7 +606,10 @@ fixup_noreturn_call (gimple stmt) gsi_remove (&gsi, true); } else - split_block (bb, stmt); + { + split_block (bb, stmt); + changed = true; + } } /* If there is an LHS, remove it. */ @@ -626,9 +631,13 @@ fixup_noreturn_call (gimple stmt) } /* Mark the call as altering control flow. */ - gimple_call_set_ctrl_altering (stmt, true); + if (!gimple_call_ctrl_altering_p (stmt)) + { + gimple_call_set_ctrl_altering (stmt, true); + changed = true; + } - return remove_fallthru_edge (bb->succs); + return changed; } -- 2.30.2