Commit 84b6a4d2 by Tom Tromey Committed by Tom Tromey

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
parent de646917
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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment