This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: FYI: PR 5696
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 19 Feb 2002 20:40:51 -0700
- Subject: Patch: FYI: PR 5696
- Reply-to: tromey at redhat dot com
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);