PATCH: Fix Java compilation crash

Mark Mitchell mark@codesourcery.com
Thu May 16 10:37:00 GMT 2002


The Java compiler was crashing on this test case:

  public class Y {
    static double d2 = 0.0;

    static Object lockObject = new Object();

    public static double f(double d1) {

      synchronized (lockObject){
        d2 = Math.max(d1, d2);
      }

      return d2;
    }
  }

when compiling with -O2 on i686-pc-linux-gnu.  The reason is that we
had a JUMP_INSN with an outgoing REG_EH edge that we were throwing
away in purge_dead_edges.

Bootstrapped and tested on i686-pc-linux-gnu.

This is a regression from GCC 3.0, so I commited this patch on the
branch.  On the mainline, the test case does not crash, but so far
as I can tell that is only because the compiler generates slightly
different RTL.  So, I've checked in the patch on the mainline too.

Java people, I have no idea how to add a Java regression test.  You
might want to take this test case and stick it in the testsuite
somewhere...

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2002-05-16  Mark Mitchell  <mark@codesourcery.com>

	* cfgrtl.c (purge_dead_edges): Correct handling of EDGE_EH.

Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.29.2.4
diff -c -p -r1.29.2.4 cfgrtl.c
*** cfgrtl.c	9 Apr 2002 20:38:56 -0000	1.29.2.4
--- cfgrtl.c	16 May 2002 16:45:34 -0000
*************** purge_dead_edges (bb)
*** 1954,1970 ****

  	  e->flags &= ~EDGE_ABNORMAL;

! 	  /* Check purposes we can have edge.  */
! 	  if ((e->flags & EDGE_FALLTHRU)
! 	      && any_condjump_p (insn))
  	    continue;
  	  else if (e->dest != EXIT_BLOCK_PTR
  		   && e->dest->head == JUMP_LABEL (insn))
  	    continue;
! 	  else if (e->dest == EXIT_BLOCK_PTR
! 		   && returnjump_p (insn))
  	    continue;

  	  purged = true;
  	  remove_edge (e);
  	}
--- 1954,1979 ----

  	  e->flags &= ~EDGE_ABNORMAL;

! 	  /* See if this edge is one we should keep.  */
! 	  if ((e->flags & EDGE_FALLTHRU) && any_condjump_p (insn))
! 	    /* A conditional jump can fall through into the next
! 	       block, so we should keep the edge.  */
  	    continue;
  	  else if (e->dest != EXIT_BLOCK_PTR
  		   && e->dest->head == JUMP_LABEL (insn))
+ 	    /* If the destination block is the target of the jump,
+ 	       keep the edge.  */
  	    continue;
! 	  else if (e->dest == EXIT_BLOCK_PTR && returnjump_p (insn))
! 	    /* If the destination block is the exit block, and this
! 	       instruction is a return, then keep the edge.  */
! 	    continue;
! 	  else if ((e->flags & EDGE_EH) && can_throw_internal (insn))
! 	    /* Keep the edges that correspond to exceptions thrown by
! 	       this instruction.  */
  	    continue;

+ 	  /* We do not need this edge.  */
  	  purged = true;
  	  remove_edge (e);
  	}



More information about the Gcc-patches mailing list