re PR java/20056 ('verification failed: incompatible type on stack' with --indirect-dispatch)

PR java/20056:
	* verify.cc (type::EITHER): New constant.
	(check_field_constant): Use it.
	(type::compatible): Handle it.

From-SVN: r95403
This commit is contained in:
Tom Tromey 2005-02-22 18:14:04 +00:00 committed by Tom Tromey
parent 0947959a37
commit de64691796
2 changed files with 42 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2005-02-22 Tom Tromey <tromey@redhat.com>
PR java/20056:
* verify.cc (type::EITHER): New constant.
(check_field_constant): Use it.
(type::compatible): Handle it.
2005-02-22 Michael Koch <konqueror@gmx.de>
* gnu/java/security/PolicyFile.java,

View File

@ -578,9 +578,11 @@ private:
//
// First, when constructing a new object, it is the PC of the
// `new' instruction which created the object. We use the special
// value UNINIT to mean that this is uninitialized, and the
// special value SELF for the case where the current method is
// itself the <init> method.
// value UNINIT to mean that this is uninitialized. The special
// value SELF is used for the case where the current method is
// itself the <init> method. the special value EITHER is used
// when we may optionally allow either an uninitialized or
// initialized reference to match.
//
// Second, when the key is return_address_type, this holds the PC
// of the instruction following the `jsr'.
@ -588,6 +590,7 @@ private:
static const int UNINIT = -2;
static const int SELF = -1;
static const int EITHER = -3;
// Basic constructor.
type ()
@ -734,19 +737,33 @@ private:
if (k.klass == NULL)
verifier->verify_fail ("programmer error in type::compatible");
// An initialized type and an uninitialized type are not
// compatible.
if (isinitialized () != k.isinitialized ())
return false;
// Two uninitialized objects are compatible if either:
// * The PCs are identical, or
// * One PC is UNINIT.
if (! isinitialized ())
// Handle the special 'EITHER' case, which is only used in a
// special case of 'putfield'. Note that we only need to handle
// this on the LHS of a check.
if (! isinitialized () && pc == EITHER)
{
if (pc != k.pc && pc != UNINIT && k.pc != UNINIT)
// If the RHS is uninitialized, it must be an uninitialized
// 'this'.
if (! k.isinitialized () && k.pc != SELF)
return false;
}
else if (isinitialized () != k.isinitialized ())
{
// An initialized type and an uninitialized type are not
// otherwise compatible.
return false;
}
else
{
// Two uninitialized objects are compatible if either:
// * The PCs are identical, or
// * One PC is UNINIT.
if (! isinitialized ())
{
if (pc != k.pc && pc != UNINIT && k.pc != UNINIT)
return false;
}
}
return klass->compatible(k.klass, verifier);
}
@ -2003,7 +2020,11 @@ private:
// We don't look at the signature, figuring that if it is
// wrong we will fail during linking. FIXME?
&& _Jv_Linker::has_field_p (current_class, name))
class_type->set_uninitialized (type::SELF, this);
// Note that we don't actually know whether we're going to match
// against 'this' or some other object of the same type. So,
// here we set things up so that it doesn't matter. This relies
// on knowing what our caller is up to.
class_type->set_uninitialized (type::EITHER, this);
return result;
}