The following fixes the SSA_NAME_OCCURS_IN_ABNORMAL_PHI flag when we propagate the virtual operand during clobber sinking.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2013-06-07 Richard Biener <rguent...@suse.de> PR middle-end/57190 * tree-eh.c (sink_clobbers): Properly propagate SSA_NAME_OCCURS_IN_ABNORMAL_PHI. * g++.dg/torture/pr57190.C: New testcase. Index: gcc/tree-eh.c =================================================================== *** gcc/tree-eh.c (revision 198667) --- gcc/tree-eh.c (working copy) *************** sink_clobbers (basic_block bb) *** 3401,3406 **** --- 3401,3411 ---- FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse) FOR_EACH_IMM_USE_ON_STMT (use_p, iter) SET_USE (use_p, gimple_vdef (stmt)); + if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse)) + { + SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_vdef (stmt)) = 1; + SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse) = 0; + } /* Adjust the incoming virtual operand. */ SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (vphi, succe), gimple_vuse (stmt)); SET_USE (gimple_vuse_op (stmt), vuse); Index: gcc/testsuite/g++.dg/torture/pr57190.C =================================================================== *** gcc/testsuite/g++.dg/torture/pr57190.C (revision 0) --- gcc/testsuite/g++.dg/torture/pr57190.C (working copy) *************** *** 0 **** --- 1,42 ---- + // { dg-do compile } + + namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) { + template<typename _Tp> class new_allocator { + }; + } + namespace std { + template<typename> class allocator; + template<class _CharT> struct char_traits; + template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > class basic_string; + typedef basic_string<char> string; + template<typename _Tp> class allocator: public __gnu_cxx::new_allocator<_Tp> { + }; + template<typename _CharT, typename _Traits, typename _Alloc> class basic_string { + public: + basic_string(const _CharT* __s, const _Alloc& __a = _Alloc()); + }; + } + class UIException { + }; + class PasswordDialog { + void run() throw (UIException); + }; + class MessageBox { + public: + MessageBox (std::string t) throw (UIException); + virtual int run() throw (UIException) ; + }; + extern "C" { + struct __jmp_buf_tag { + }; + extern int __sigsetjmp (struct __jmp_buf_tag __env[1], int __savemask) throw (); + typedef struct __jmp_buf_tag sigjmp_buf[1]; + } + sigjmp_buf password_dialog_sig_jmp_buf; + void PasswordDialog::run() throw (UIException) + { + __sigsetjmp (password_dialog_sig_jmp_buf, 1); + MessageBox* errmsg = __null; + errmsg = new MessageBox ("E R R O R"); + errmsg->run(); + }