diff options
author | Tom Tromey <tromey@redhat.com> | 2005-02-22 18:14:37 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2005-02-22 18:14:37 +0000 |
commit | 84b6a4d217b2762af5b223afc35c56d4c91e9d00 (patch) | |
tree | 50a948b2042b828a734df573abcc30e89cb95cfc /gcc/java/verify-impl.c | |
parent | de646917966153fb997aff63928c9f3bfcb613f3 (diff) | |
download | gcc-84b6a4d217b2762af5b223afc35c56d4c91e9d00.zip gcc-84b6a4d217b2762af5b223afc35c56d4c91e9d00.tar.gz gcc-84b6a4d217b2762af5b223afc35c56d4c91e9d00.tar.bz2 |
re PR java/20056 ('verification failed: incompatible type on stack' with --indirect-dispatch)
PR java/20056:
* verify-impl.c (EITHER): New define.
(types_compatible): Handle it.
(check_field_constant): Use it.
From-SVN: r95404
Diffstat (limited to 'gcc/java/verify-impl.c')
-rw-r--r-- | gcc/java/verify-impl.c | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/gcc/java/verify-impl.c b/gcc/java/verify-impl.c index bd681d2..ae585c8 100644 --- a/gcc/java/verify-impl.c +++ b/gcc/java/verify-impl.c @@ -539,16 +539,19 @@ struct type 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'. */ int pc; - #define UNINIT -2 - #define SELF -1 +#define UNINIT -2 +#define SELF -1 +#define EITHER -3 }; #if 0 @@ -721,19 +724,33 @@ types_compatible (type *t, type *k) if (k->klass == NULL) verify_fail ("programmer error in type::compatible"); - /* An initialized type and an uninitialized type are not - compatible. */ - if (type_initialized (t) != type_initialized (k)) - return false; - - /* Two uninitialized objects are compatible if either: - * The PCs are identical, or - * One PC is UNINIT. */ - if (type_initialized (t)) + /* 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 (! type_initialized (t) && t->pc == EITHER) { - if (t->pc != k->pc && t->pc != UNINIT && k->pc != UNINIT) + /* If the RHS is uninitialized, it must be an uninitialized + 'this'. */ + if (! type_initialized (k) && k->pc != SELF) return false; } + else if (type_initialized (t) != type_initialized (k)) + { + /* 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 (type_initialized (t)) + { + if (t->pc != k->pc && t->pc != UNINIT && k->pc != UNINIT) + return false; + } + } return ref_compatible (t->klass, k->klass); } @@ -2162,7 +2179,11 @@ check_field_constant (int index, type *class_type, bool putfield) && vfr->current_state->this_type.pc == SELF && types_equal (&vfr->current_state->this_type, &ct) && vfy_class_has_field (vfr->current_class, name, field_type)) - type_set_uninitialized (class_type, SELF); + /* 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. */ + type_set_uninitialized (class_type, EITHER); return t; } |