summaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2002-02-15 06:55:42 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2002-02-15 06:55:42 +0000
commitb06ffad8d5a1aac3918623e93b49cb2c5794b94d (patch)
treebf4df495a5c9b138460a843a0849e987d9305402 /libjava
parentfb450cd518d0b090d797a7a3ee34ddea575fcf79 (diff)
downloadgcc-b06ffad8d5a1aac3918623e93b49cb2c5794b94d.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49783 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog8
-rw-r--r--libjava/verify.cc30
2 files changed, 34 insertions, 4 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 02ded31b267..24e87e6fdea 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,11 @@
+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.
+
2002-02-15 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
* Makefile.in: Rebuilt with Eric's change below.
diff --git a/libjava/verify.cc b/libjava/verify.cc
index ed734eab8f6..cbadd9f2f2f 100644
--- a/libjava/verify.cc
+++ b/libjava/verify.cc
@@ -259,6 +259,11 @@ private:
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 @@ private:
if (target == NULL)
return false;
}
- else if (target == &java::lang::Object::class$)
- return true;
else if (source == &java::lang::Object::class$)
return false;
else
@@ -2786,9 +2789,28 @@ private:
// In this case the PC doesn't matter.
t.set_uninitialized (type::UNINIT, this);
}
- t = pop_type (t);
+ 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);
+ }
+
+ 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);
}