re PR libgcj/5695 (verify.cc test that target is an object before running down interf...
authorTom Tromey <tromey@redhat.com>
Fri, 15 Feb 2002 06:55:42 +0000 (06:55 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Fri, 15 Feb 2002 06:55:42 +0000 (06:55 +0000)
Fix for PR libgcj/5695:
* verify.cc (is_assignable_from_slow): Check to see if target is
an Object before checking to see if source is an interface.
(verify_instructions_0) [op_invokeinterface]: Handle case where
we're making an interface call on Object.

From-SVN: r49783

libjava/ChangeLog
libjava/verify.cc

index 02ded31b2670221bb4b71ecad8c49aef4a8bc89b..24e87e6fdea82b533f22ca7bf0e1763feb6acf2f 100644 (file)
@@ -1,3 +1,11 @@
+2002-02-15  Tom Tromey  <tromey@redhat.com>
+
+       Fix for PR libgcj/5695:
+       * verify.cc (is_assignable_from_slow): Check to see if target is
+       an Object before checking to see if source is an interface.
+       (verify_instructions_0) [op_invokeinterface]: Handle case where
+       we're making an interface call on Object.
+
 2002-02-15  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>
 
        * Makefile.in: Rebuilt with Eric's change below.
index ed734eab8f6f2972fe88c067a281b3c40bff8d64..cbadd9f2f2f96d7d29ad4d9734ce7d989e66d5f0 100644 (file)
@@ -259,6 +259,11 @@ private:
            if (source == NULL)
              return false;
          }
+       // We must do this check before we check to see if SOURCE is
+       // an interface.  This way we know that any interface is
+       // assignable to an Object.
+       else if (target == &java::lang::Object::class$)
+         return true;
        else if (source->isInterface ())
          {
            for (int i = 0; i < target->interface_count; ++i)
@@ -272,8 +277,6 @@ private:
            if (target == NULL)
              return false;
          }
-       else if (target == &java::lang::Object::class$)
-         return true;
        else if (source == &java::lang::Object::class$)
          return false;
        else
@@ -2786,9 +2789,28 @@ private:
                      // In this case the PC doesn't matter.
                      t.set_uninitialized (type::UNINIT, this);
                    }
-                 t = pop_type (t);
+                 type raw = pop_raw ();
+                 bool ok = false;
+                 if (t.compatible (raw, this))
+                   {
+                     ok = true;
+                   }
+                 else if (opcode == op_invokeinterface)
+                   {
+                     // This is a hack.  We might have merged two
+                     // items and gotten `Object'.  This can happen
+                     // because we don't keep track of where merges
+                     // come from.  This is safe as long as the
+                     // interpreter checks interfaces at runtime.
+                     type obj (&java::lang::Object::class$);
+                     ok = raw.compatible (obj, this);
+                   }
+
+                 if (! ok)
+                   verify_fail ("incompatible type on stack");
+
                  if (is_init)
-                   current_state->set_initialized (t.get_pc (),
+                   current_state->set_initialized (raw.get_pc (),
                                                    current_method->max_locals);
                }