Comments
Patch
@@ -846,11 +846,10 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
if (dump_file)
fprintf (dump_file, "Redirecting jump %i from %i to %i.\n",
INSN_UID (insn), e->dest->index, target->index);
- if (!redirect_jump (insn, block_label (target), 0))
- {
- gcc_assert (target == EXIT_BLOCK_PTR);
- return NULL;
- }
+ if (target == EXIT_BLOCK_PTR)
+ return NULL;
+ if (! redirect_jump (insn, block_label (target), 0))
+ gcc_unreachable ();
}
/* Cannot do anything for target exit block. */
@@ -1030,11 +1029,10 @@ patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb)
/* If the substitution doesn't succeed, die. This can happen
if the back end emitted unrecognizable instructions or if
target is exit block on some arches. */
- if (!redirect_jump (insn, block_label (new_bb), 0))
- {
- gcc_assert (new_bb == EXIT_BLOCK_PTR);
- return false;
- }
+ if (new_bb == EXIT_BLOCK_PTR)
+ return false;
+ if (! redirect_jump (insn, block_label (new_bb), 0))
+ gcc_unreachable ();
}
}
return true;
Consider this testcase: $ cat test.cpp class GCAlloc { }; class BaseAlloc { }; class String; class Base { public: virtual void destroy( String *str ) const =0; }; class String: public GCAlloc { const Base *m_class; public: enum constants { }; String( const char *data ); ~String() { m_class->destroy( this ); } void copy( const String &other ); String & operator=( const char *other ) { copy( String( other ) ); } }; class ListElement: public BaseAlloc { }; class List: public BaseAlloc { ListElement *m_head; void (*m_deletor)( void *); public: List(): m_deletor(0) { } const void *back() const { } bool empty() const { return m_head == 0; } void popBack(); }; class FalconData: public BaseAlloc { public: virtual ~FalconData() { } }; class Stream: public FalconData { }; class SrcLexer: public BaseAlloc { List m_streams; String m_whiteLead; void reset(); }; void SrcLexer::reset() { m_whiteLead = ""; while( ! m_streams.empty() ) { Stream *s = (Stream *) m_streams.back(); m_streams.popBack(); if ( !m_streams.empty() ) delete s; } } % g++ -O2 test.cpp test.cpp: In member function ‘void SrcLexer::reset()’: test.cpp:59:1: internal compiler error: in redirect_jump, at jump.c:1497 It hits the following assertion: gcc_assert (nlabel != NULL_RTX); In this case target(or new_bb)=EXIT_BLOCK_PTR and block_label(EXIT_BLOCK_PTR)==NULL_RTX. Fix this by treating the target=EXIT_BLOCK_PTR case before calling redirect_jump in gcc/cfgrtl.c. PR middle-end/50496 * cfgrtl.c (try_redirect_by_replacing_jump): Treat EXIT_BLOCK_PTR case separately before call to redirect_jump(). Add assertion. (patch_jump_insn): Same.