]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR java/20056 ('verification failed: incompatible type on stack' with --indirect...
authorTom Tromey <tromey@redhat.com>
Tue, 22 Feb 2005 18:14:04 +0000 (18:14 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Tue, 22 Feb 2005 18:14:04 +0000 (18:14 +0000)
PR java/20056:
* verify.cc (type::EITHER): New constant.
(check_field_constant): Use it.
(type::compatible): Handle it.

From-SVN: r95403

libjava/ChangeLog
libjava/verify.cc

index b1fbc96ee2479b45ff2a408f7cb232f19fe694e8..324a5b23b7d0d49d51726fdaeeef5f0397e46ac9 100644 (file)
@@ -1,3 +1,10 @@
+2005-02-22  Tom Tromey  <tromey@redhat.com>
+
+       PR java/20056:
+       * verify.cc (type::EITHER): New constant.
+       (check_field_constant): Use it.
+       (type::compatible): Handle it.
+
 2005-02-22  Michael Koch  <konqueror@gmx.de>
 
        * gnu/java/security/PolicyFile.java,
index a8093070e96bcc92ad292fd3697ae85061a6f217..141f27af7970cd5c7f94e18f10e0e909e5d48179 100644 (file)
@@ -578,9 +578,11 @@ private:
     //
     // 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'.
@@ -588,6 +590,7 @@ private:
 
     static const int UNINIT = -2;
     static const int SELF = -1;
+    static const int EITHER = -3;
 
     // Basic constructor.
     type ()
@@ -734,19 +737,33 @@ private:
       if (k.klass == NULL)
        verifier->verify_fail ("programmer error in type::compatible");
 
-      // An initialized type and an uninitialized type are not
-      // compatible.
-      if (isinitialized () != k.isinitialized ())
-       return false;
-
-      // Two uninitialized objects are compatible if either:
-      // * The PCs are identical, or
-      // * One PC is UNINIT.
-      if (! isinitialized ())
+      // 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 (! isinitialized () && pc == EITHER)
        {
-         if (pc != k.pc && pc != UNINIT && k.pc != UNINIT)
+         // If the RHS is uninitialized, it must be an uninitialized
+         // 'this'.
+         if (! k.isinitialized () && k.pc != SELF)
            return false;
        }
+      else if (isinitialized () != k.isinitialized ())
+       {
+         // 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 (! isinitialized ())
+           {
+             if (pc != k.pc && pc != UNINIT && k.pc != UNINIT)
+               return false;
+           }
+       }
 
       return klass->compatible(k.klass, verifier);
     }
@@ -2003,7 +2020,11 @@ private:
        // We don't look at the signature, figuring that if it is
        // wrong we will fail during linking.  FIXME?
        && _Jv_Linker::has_field_p (current_class, name))
-      class_type->set_uninitialized (type::SELF, this);
+      // 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.
+      class_type->set_uninitialized (type::EITHER, this);
 
     return result;
   }