From: Tom Tromey Date: Tue, 22 Feb 2005 18:14:37 +0000 (+0000) Subject: re PR java/20056 ('verification failed: incompatible type on stack' with --indirect... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=84b6a4d217b2762af5b223afc35c56d4c91e9d00;p=gcc.git 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 --- diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index c1d48086be9..54dc009a4b7 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,10 @@ +2005-02-22 Tom Tromey + + PR java/20056: + * verify-impl.c (EITHER): New define. + (types_compatible): Handle it. + (check_field_constant): Use it. + 2005-02-18 Tom Tromey PR java/20056: diff --git a/gcc/java/verify-impl.c b/gcc/java/verify-impl.c index bd681d2bce0..ae585c8d7db 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 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 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; }