Patchwork resent2 [PATCH] Fix ICE in redirect_jump, at jump.c:1497 PR50496

login
register
mail settings
Submitter Markus Trippelsdorf
Date Oct. 14, 2011, 11:59 a.m.
Message ID <20111014115943.GB1662@x4.trippels.de>
Download mbox | patch
Permalink /patch/119770/
State New
Headers show

Comments

Markus Trippelsdorf - Oct. 14, 2011, 11:59 a.m.
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.

Patch

diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index b3f045b..57f561f 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -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;