This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: verification error in 3.3


>>>>> "Per" == Per Bothner <per@bothner.com> writes:

Per> I tried building latest Kawa (from CVS) using the GCJ in the 3.3
Per> branch of CVS.  I get a Exception in thread "main"
Per> java.lang.VerifyError: verification failed at PC 24 in
Per> gnu.expr.Interpreter:eval((Ljava.lang.String;Ljava.io.Writer;)V):
Per> incompatible type on stack

My fault.  I missed some tricky code in is_assignable_from_slow when I
removed it.

Mark, this is important for 3.3.  This patch is low risk since it
reverts the questionable change to a known-working state (while
leaving the correct part of the fix in place).

Test case included.  Regression tested on x86 RHL 9, including Mauve,
Jacks, the new test, and also Per's kawa test.  Ok?


is_assignable_from_slow is bogus -- the source->isInterface() branch
is plainly incorrect.  Still, in my opinion, it is too late to really
fix this for the branch.  I'll find a better fix for the trunk.


Per, is Kawa ordinarily ok to build and check from cvs?  I could add
it to my nightly build pretty easily.  I'm already doing this for
rhug, classpath, and crypto; one more won't hurt and will help find
regressions.

Tom

Index: libjava/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* verify.cc: Reverted previous patch.

Index: libjava/verify.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/verify.cc,v
retrieving revision 1.48.2.5
diff -u -r1.48.2.5 verify.cc
--- libjava/verify.cc 1 May 2003 21:52:35 -0000 1.48.2.5
+++ libjava/verify.cc 6 May 2003 19:20:39 -0000
@@ -240,6 +240,64 @@
     return get_type_val_for_signature ((jchar) k->method_count);
   }
 
+  // This is like _Jv_IsAssignableFrom, but it works even if SOURCE or
+  // TARGET haven't been prepared.
+  static bool is_assignable_from_slow (jclass target, jclass source)
+  {
+    // This will terminate when SOURCE==Object.
+    while (true)
+      {
+	if (source == target)
+	  return true;
+
+	if (target->isPrimitive () || source->isPrimitive ())
+	  return false;
+
+	if (target->isArray ())
+	  {
+	    if (! source->isArray ())
+	      return false;
+	    target = target->getComponentType ();
+	    source = source->getComponentType ();
+	  }
+	else if (target->isInterface ())
+	  {
+	    for (int i = 0; i < source->interface_count; ++i)
+	      {
+		// We use a recursive call because we also need to
+		// check superinterfaces.
+		if (is_assignable_from_slow (target, source->interfaces[i]))
+		    return true;
+	      }
+	    source = source->getSuperclass ();
+	    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)
+	      {
+		// We use a recursive call because we also need to
+		// check superinterfaces.
+		if (is_assignable_from_slow (target->interfaces[i], source))
+		  return true;
+	      }
+	    target = target->getSuperclass ();
+	    if (target == NULL)
+	      return false;
+	  }
+	else if (source == &java::lang::Object::class$)
+	  return false;
+	else
+	  source = source->getSuperclass ();
+      }
+  }
+
   // This is used to keep track of which `jsr's correspond to a given
   // jsr target.
   struct subr_info
@@ -462,7 +520,7 @@
       // We must resolve both types and check assignability.
       resolve (verifier);
       k.resolve (verifier);
-      return _Jv_IsAssignableFrom (data.klass, k.data.klass);
+      return is_assignable_from_slow (data.klass, k.data.klass);
     }
 
     bool isvoid () const
@@ -649,7 +707,7 @@
 		  // Ordinarily this terminates when we hit Object...
 		  while (k != NULL)
 		    {
-		      if (_Jv_IsAssignableFrom (k, oldk))
+		      if (is_assignable_from_slow (k, oldk))
 			break;
 		      k = k->getSuperclass ();
 		      changed = true;
Index: libjava/testsuite/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* libjava.lang/verify.java: New file.
	* libjava.lang/verify.out: New file.

Index: libjava/testsuite/libjava.lang/verify.java
===================================================================
RCS file: libjava/testsuite/libjava.lang/verify.java
diff -N libjava/testsuite/libjava.lang/verify.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libjava/testsuite/libjava.lang/verify.java 6 May 2003 19:20:44 -0000
@@ -0,0 +1,20 @@
+// Test for a verification regression.
+
+interface I { }
+class D implements I { }
+class E extends D { }
+
+public class verify
+{
+  static void call(I v) { }
+
+  static void doit (Object x)
+  {
+    call ((x instanceof I) ? (I) x : new E ());
+  }
+
+  public static void main(String[] args)
+  {
+    doit(null);
+  }
+}
Index: libjava/testsuite/libjava.lang/verify.out
===================================================================
RCS file: libjava/testsuite/libjava.lang/verify.out
diff -N libjava/testsuite/libjava.lang/verify.out


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]