This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[tree-ssa] fix edge insertion handling in switch expressions


When creating a new default case for insertion on fallthru edges out of
a switch statement, we were ICEing because the handler wasn't expecting
the insertion to create a new basic block.

The handler for inserting on a fallthru edge inserts an goto out of
every case label that may fall through to the new default label.  But it
doesn't expect that the insertion of the new goto to create a new basic
block.

This may happen if the last statement in the switch() is a call to a
function that may throw an exception:

switch (cond)
{
   case 1:
     s1;
     foo_may_throw ();
}

The call to foo_may_throw() needs to be last in its basic block because
it may throw.  Suppose we want to insert 'X = 0' in the fallthru edge
out of the 'switch (cond)' block.  We want to transform this into:

switch (cond)
{
   case 1:
     s1;
     foo_may_throw ();
     goto out;

   default:
     X = 0;
}

out:


But in tree-cfg.c:handle_switch_fallthru we were insisting that the
'goto out' statement be in the same block as the call to
foo_may_throw().  This is not possible in this case, and it shouldn't
be.  Fixed by first checking if the last statement doesn't need to be in
its block.

I don't know how to add a new Java test without bringing the whole
package in.  This happened while building the xerces package.  I've got
the .java file that used to produce the compiler failure, but I don't
quite know how to isolate it into a self contained program for the java
testsuite.

Bootstrapped and teste d on x86 and amd64.


Diego.


	* tree-cfg.c (handle_switch_fallthru): Do not abort when the last
	statement of the case block needs to be the last statement of the
	block.
	(find_insert_location): Fix typo.

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.141
diff -d -u -p -r1.1.4.141 tree-cfg.c
--- tree-cfg.c	5 Aug 2003 21:07:41 -0000	1.1.4.141
+++ tree-cfg.c	6 Aug 2003 16:50:20 -0000
@@ -3920,8 +3920,10 @@ handle_switch_fallthru (tree sw_stmt, ba
 	    SET_PENDING_STMT (e, NULL_TREE);
 	    bsi_insert_on_edge_immediate (e, goto_stmt, NULL, &tmp_bb);
 	    SET_PENDING_STMT (e, tmp);
-	    /* Insertion should never cause a new block.  */
-	    if (tmp_bb)
+	    /* Insertion should never cause a new block, unless STMT needs
+	       to be the last statement in E->SRC (e.g., STMT is a
+	       CALL_EXPR that may throw).  */
+	    if (tmp_bb && !stmt_ends_bb_p (stmt))
 	      abort ();
 	  }
       }
@@ -4192,7 +4194,7 @@ find_insert_location (basic_block src, b
    stmt is added to the new block.  An iterator to the new stmt is returned.
    If a pointer to a BSI is passed in, and the stmt is inserted before or after
    an existing stmt in a block, old_bsi will be returned with an iterator for
-   that stmt (The equivilent of BSI_SAME_STMT on an insert_before or after.
+   that stmt (The equivalent of BSI_SAME_STMT on an insert_before or after.
    If a created_block is passed in, and the edge is split, the new block is
    returned through this parameter.  */
 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]