This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java 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]

Patch: FYI: PR 5696


I'm checking this in.

This does 3 things:

* Fixes PR 5696
* Removes the call to _Jv_IsAssignableFrom, which was occasionally
  causing us problems and didn't really help that much
* Adds a bit more debugging output (which I used to help me find the
  problem)

This bug is a bit complicated.  If a subroutine was called from two
places with incompatible types in a local variable slot, then that
variable would be marked as used when it was merged in the subroutine.
This would in turn propagate incorrect information to the callers.
The fix is not to mark a variable as changed simply due to a merge; an
explicit `set' is required.

I've checked a regression test in to Mauve.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	Fix for PR libgcj/5696:
	* verify.cc (is_assignable_from_slow): Never call
	_Jv_IsAssignableFrom.
	(verify_instructions_0): Added new debug statement.
	(state::print): Print information about whether local has
	changed.
	(state::merge): Don't call note_variable when merging locals.
	(state::set_exception): Removed old FIXME comment.

Index: verify.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/verify.cc,v
retrieving revision 1.38
diff -u -r1.38 verify.cc
--- verify.cc 2002/02/15 06:55:42 1.38
+++ verify.cc 2002/02/20 03:10:43
@@ -231,9 +231,6 @@
 	if (target->isPrimitive () || source->isPrimitive ())
 	  return false;
 
-	// Check array case first because we can have an array whose
-	// component type is not prepared; _Jv_IsAssignableFrom
-	// doesn't handle this correctly.
 	if (target->isArray ())
 	  {
 	    if (! source->isArray ())
@@ -241,11 +238,6 @@
 	    target = target->getComponentType ();
 	    source = source->getComponentType ();
 	  }
-	// _Jv_IsAssignableFrom can handle a target which is an
-	// interface even if it hasn't been prepared.
-	else if ((target->state > JV_STATE_LINKED || target->isInterface ())
-		 && source->state > JV_STATE_LINKED)
-	  return _Jv_IsAssignableFrom (target, source);
 	else if (target->isInterface ())
 	  {
 	    for (int i = 0; i < source->interface_count; ++i)
@@ -912,8 +904,6 @@
       stack[0] = t;
       for (int i = stacktop; i < max_stack; ++i)
 	stack[i] = unsuitable_type;
-
-      // FIXME: subroutine handling?
     }
 
     // Modify this state to reflect entry into a subroutine.
@@ -982,8 +972,14 @@
 	    {
 	      if (locals[i].merge (state_old->locals[i], true, verifier))
 		{
+		  // Note that we don't call `note_variable' here.
+		  // This change doesn't represent a real change to a
+		  // local, but rather a merge artifact.  If we're in
+		  // a subroutine which is called with two
+		  // incompatible types in a slot that is unused by
+		  // the subroutine, then we don't want to mark that
+		  // variable as having been modified.
 		  changed = true;
-		  note_variable (i);
 		}
 	    }
 
@@ -1072,7 +1068,10 @@
 	debug_print (".");
       debug_print ("    [local] ");
       for (i = 0; i < max_locals; ++i)
-	locals[i].print ();
+	{
+	  locals[i].print ();
+	  debug_print (local_changed[i] ? "+" : " ");
+	}
       if (subroutine == 0)
 	debug_print ("   | None");
       else
@@ -2055,6 +2054,7 @@
 	      verify_fail ("can't happen: saw state::INVALID");
 	    if (PC == state::NO_NEXT)
 	      break;
+	    debug_print ("== State pop from pending list\n");
 	    // Set up the current state.
 	    current_state->copy (states[PC], current_method->max_stack,
 				 current_method->max_locals);


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