This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: FYI:
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 15 Feb 2002 00:15:10 -0700
- Subject: Patch: FYI:
- Reply-to: tromey at redhat dot com
I'm checking this in.
This fixes PR 5695, plus another verifier bug.
I'd already written this patch when I saw the PR; I decided to keep my
patch first out of inertia and second because it includes an
explanatory comment.
The second problem has to do with a situation where we merge against
an interface, come up with Object, and then later try to make an
interface call on the Object. Since we don't keep track of the union
of merged types, we have to allow this and then catch the problem in
the interpreter.
This is less than ideal, and it would be possible, I think, to change
the verifier to keep track of the type union. However that is a task
for a later day.
I've added Mauve tests for both these problems.
Tom
2002-02-15 Tom Tromey <tromey@redhat.com>
Fix for PR libgcj/5695:
* verify.cc (is_assignable_from_slow): Check to see if target is
an Object before checking to see if source is an interface.
(verify_instructions_0) [op_invokeinterface]: Handle case where
we're making an interface call on Object.
Index: verify.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/verify.cc,v
retrieving revision 1.37
diff -u -r1.37 verify.cc
--- verify.cc 2002/02/14 17:48:36 1.37
+++ verify.cc 2002/02/15 06:45:46
@@ -259,6 +259,11 @@
if (source == NULL)
return false;
}
+ // We must do this check before we check to see if SOURCE is
+ // an interface. This way we know that any interface is
+ // assignable to an Object.
+ else if (target == &java::lang::Object::class$)
+ return true;
else if (source->isInterface ())
{
for (int i = 0; i < target->interface_count; ++i)
@@ -272,8 +277,6 @@
if (target == NULL)
return false;
}
- else if (target == &java::lang::Object::class$)
- return true;
else if (source == &java::lang::Object::class$)
return false;
else
@@ -2785,10 +2788,29 @@
{
// In this case the PC doesn't matter.
t.set_uninitialized (type::UNINIT, this);
+ }
+ type raw = pop_raw ();
+ bool ok = false;
+ if (t.compatible (raw, this))
+ {
+ ok = true;
+ }
+ else if (opcode == op_invokeinterface)
+ {
+ // This is a hack. We might have merged two
+ // items and gotten `Object'. This can happen
+ // because we don't keep track of where merges
+ // come from. This is safe as long as the
+ // interpreter checks interfaces at runtime.
+ type obj (&java::lang::Object::class$);
+ ok = raw.compatible (obj, this);
}
- t = pop_type (t);
+
+ if (! ok)
+ verify_fail ("incompatible type on stack");
+
if (is_init)
- current_state->set_initialized (t.get_pc (),
+ current_state->set_initialized (raw.get_pc (),
current_method->max_locals);
}