The following fixes PR64280 by properly guarding the assert with whether we are going to change SSA_NAME_OCCURS_IN_ABNORMAL_PHI. Recent changes in what we allow to propagate otherwise happily will trigger it.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2014-12-12 Richard Biener <rguent...@suse.de> PR middle-end/64280 * tree-cfg.c (replace_uses_by): Guard assert properly. * g++.dg/torture/pr64280.C: New testcase. Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 218661) +++ gcc/tree-cfg.c (working copy) @@ -1781,7 +1781,8 @@ replace_uses_by (tree name, tree val) { e = gimple_phi_arg_edge (as_a <gphi *> (stmt), PHI_ARG_INDEX_FROM_USE (use)); - if (e->flags & EDGE_ABNORMAL) + if (e->flags & EDGE_ABNORMAL + && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)) { /* This can only occur for virtual operands, since for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name)) Index: gcc/testsuite/g++.dg/torture/pr64280.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr64280.C (revision 0) +++ gcc/testsuite/g++.dg/torture/pr64280.C (working copy) @@ -0,0 +1,42 @@ +// { dg-do compile } + +class A +{ +public: + A (); +}; +class B +{ +public: + B (int); + operator void *() { return m_fn1 () ? 0 : this; } + int m_fn1 (); +}; +typedef int jmp_buf[]; +struct C +{ + jmp_buf cond_; +}; +class F +{ + C what_; + bool m_fn2 (); +}; +int _setjmp (int[]); +void longjmp (); +class D +{ +public: + D () { longjmp (); } +}; +bool +F::m_fn2 () +{ + B a (0); + if (a) + if (_setjmp (what_.cond_)) + return 0; + else + D (); + A b; +}