summaryrefslogtreecommitdiff
path: root/libjava/verify.cc
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2005-02-22 18:14:04 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2005-02-22 18:14:04 +0000
commitb54a9a9832ba0f41b24dd94dae5c1d1c1e2b9173 (patch)
tree37d6f1b819a2aa11dfd4d23abc1246ea6d550777 /libjava/verify.cc
parent9f3aa06cd756745f863bb5384a7e86a1ebd214b7 (diff)
downloadgcc-b54a9a9832ba0f41b24dd94dae5c1d1c1e2b9173.tar.gz
PR java/20056:
* verify.cc (type::EITHER): New constant. (check_field_constant): Use it. (type::compatible): Handle it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@95403 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/verify.cc')
-rw-r--r--libjava/verify.cc49
1 files changed, 35 insertions, 14 deletions
diff --git a/libjava/verify.cc b/libjava/verify.cc
index a8093070e96..141f27af797 100644
--- a/libjava/verify.cc
+++ b/libjava/verify.cc
@@ -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;
}