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
This commit is contained in:
parent
de64691796
commit
84b6a4d217
@ -1,3 +1,10 @@
|
||||
2005-02-22 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR java/20056:
|
||||
* verify-impl.c (EITHER): New define.
|
||||
(types_compatible): Handle it.
|
||||
(check_field_constant): Use it.
|
||||
|
||||
2005-02-18 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR java/20056:
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user