diff options
author | Tom Tromey <tromey@redhat.com> | 2005-02-22 18:14:04 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2005-02-22 18:14:04 +0000 |
commit | de646917966153fb997aff63928c9f3bfcb613f3 (patch) | |
tree | 37d6f1b819a2aa11dfd4d23abc1246ea6d550777 /libjava | |
parent | 0947959a371305bff4a92fe250948ca684e130ed (diff) | |
download | gcc-de646917966153fb997aff63928c9f3bfcb613f3.zip gcc-de646917966153fb997aff63928c9f3bfcb613f3.tar.gz gcc-de646917966153fb997aff63928c9f3bfcb613f3.tar.bz2 |
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
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 7 | ||||
-rw-r--r-- | libjava/verify.cc | 49 |
2 files changed, 42 insertions, 14 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index b1fbc96..324a5b2 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -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, diff --git a/libjava/verify.cc b/libjava/verify.cc index a809307..141f27a 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; } |