OSDN Git Service

PR java/20056:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 19 Feb 2005 01:14:17 +0000 (01:14 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 19 Feb 2005 01:14:17 +0000 (01:14 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@95258 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/java/ChangeLog
gcc/java/verify-glue.c
gcc/java/verify-impl.c
gcc/java/verify.h

index 02d12c1..84a0e78 100644 (file)
@@ -1,3 +1,13 @@
+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:
index b2cd915..5d480e8 100644 (file)
@@ -1,5 +1,5 @@
 /* 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)
index ee8f426..376f749 100644 (file)
@@ -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;
index 3553d35..b23a08a 100644 (file)
@@ -1,5 +1,5 @@
 /* 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) \