Commit 1870a43b by Tom Tromey Committed by Tom Tromey

re PR java/20056 ('verification failed: incompatible type on stack' with --indirect-dispatch)

	PR java/20056:
	* verify-glue.c (vfy_class_has_field): New function.
	* verify.h (vfy_class_has_field): Declare.
	* verify-impl.c (check_field_constant): Added 'putfield'
	argument.
	(verify_instructions_0): Updated.
	(types_equal): New function.

From-SVN: r95258
parent 4c334b37
2005-02-18 Tom Tromey <tromey@redhat.com>
PR java/20056:
* verify-glue.c (vfy_class_has_field): New function.
* verify.h (vfy_class_has_field): Declare.
* verify-impl.c (check_field_constant): Added 'putfield'
argument.
(verify_instructions_0): Updated.
(types_equal): New function.
2005-02-14 Tom Tromey <tromey@redhat.com>
PR java/19921:
......
/* Glue to interface gcj with bytecode verifier.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -385,6 +385,21 @@ vfy_null_type (void)
return TYPE_NULL;
}
bool
vfy_class_has_field (vfy_jclass klass, vfy_string name,
vfy_string signature)
{
tree field = TYPE_FIELDS (klass);
while (field != NULL_TREE)
{
if (DECL_NAME (field) == name
&& build_java_signature (TREE_TYPE (field)) == signature)
return true;
field = TREE_CHAIN (field);
}
return false;
}
int
vfy_fail (const char *message, int pc, vfy_jclass ignore1 ATTRIBUTE_UNUSED,
vfy_method *ignore2 ATTRIBUTE_UNUSED)
......
......@@ -738,6 +738,20 @@ types_compatible (type *t, type *k)
return ref_compatible (t->klass, k->klass);
}
/* Return true if two types are equal. Only valid for reference
types. */
static bool
types_equal (type *t1, type *t2)
{
if (t1->key != reference_type || t1->key != uninitialized_reference_type
|| t2->key != reference_type || t2->key != uninitialized_reference_type)
return false;
/* Only single-ref types are allowed. */
if (t1->klass->ref_next || t2->klass->ref_next)
return false;
return refs_equal (t1->klass, t2->klass);
}
static bool
type_isvoid (type *t)
{
......@@ -2117,9 +2131,10 @@ handle_field_or_method (int index, int expected,
return check_class_constant (class_index);
}
/* Return field's type, compute class' type if requested. */
/* Return field's type, compute class' type if requested. If
PUTFIELD is true, use the special 'putfield' semantics. */
static type
check_field_constant (int index, type *class_type)
check_field_constant (int index, type *class_type, bool putfield)
{
vfy_string name, field_type;
const char *typec;
......@@ -2137,6 +2152,17 @@ check_field_constant (int index, type *class_type)
init_type_from_string (&t, field_type);
else
init_type_from_tag (&t, get_type_val_for_signature (typec[0]));
/* We have an obscure special case here: we can use `putfield' on a
field declared in this class, even if `this' has not yet been
initialized. */
if (putfield
&& ! type_initialized (&vfr->current_state->this_type)
&& 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);
return t;
}
......@@ -2971,15 +2997,15 @@ verify_instructions_0 (void)
invalidate_pc ();
break;
case op_getstatic:
push_type_t (check_field_constant (get_ushort (), NULL));
push_type_t (check_field_constant (get_ushort (), NULL, false));
break;
case op_putstatic:
pop_type_t (check_field_constant (get_ushort (), NULL));
pop_type_t (check_field_constant (get_ushort (), NULL, false));
break;
case op_getfield:
{
type klass;
type field = check_field_constant (get_ushort (), &klass);
type field = check_field_constant (get_ushort (), &klass, false);
pop_type_t (klass);
push_type_t (field);
}
......@@ -2987,15 +3013,8 @@ verify_instructions_0 (void)
case op_putfield:
{
type klass;
type field = check_field_constant (get_ushort (), &klass);
type field = check_field_constant (get_ushort (), &klass, true);
pop_type_t (field);
/* We have an obscure special case here: we can use
`putfield' on a field declared in this class, even if
`this' has not yet been initialized. */
if (! type_initialized (&vfr->current_state->this_type)
&& vfr->current_state->this_type.pc == SELF)
type_set_uninitialized (&klass, SELF);
pop_type_t (klass);
}
break;
......
/* Declarations to interface gcj with bytecode verifier.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -126,6 +126,8 @@ void vfy_note_stack_type (vfy_method *method, int pc, int slot,
void vfy_note_local_type (vfy_method *method, int pc, int slot,
vfy_jclass type);
void vfy_note_instruction_seen (int pc);
bool vfy_class_has_field (vfy_jclass klass, vfy_string name,
vfy_string signature);
#define GLOM(name, stuff) name ## stuff
#define VFY_PRIMITIVE_CLASS(name) \
......
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