This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: PR libgcj/10582
- From: Tom Tromey <tromey at redhat dot com>
- To: GCC libjava patches <java-patches at gcc dot gnu dot org>
- Cc: Mark Mitchell <mitchell at mail dot codesourcery dot com>
- Date: 01 May 2003 15:21:37 -0600
- Subject: Patch: PR libgcj/10582
- Reply-to: tromey at redhat dot com
This patch fixes PR libgcj/10582. This is a regression from 3.2 -> 3.3.
This is an important fix since the problem is that things like
"instanceof" fail in some situations. Test case included.
Tested on x86 Red Hat Linux 9. No regressions, including Mauve and
Jacks.
I'm going to check this in on the trunk. Mark, can you approve for 3.3?
Tom
Index: libjava/ChangeLog
from Tom Tromey <tromey@redhat.com>
PR libgcj/10582:
* verify.cc (_Jv_BytecodeVerifier::is_assignable_from_slow):
Removed.
(type::compatible): Use _Jv_IsAssignableFrom.
* java/lang/natClass.cc (iindex_mutex_initialized): Now static.
(_Jv_IsAssignableFrom): Work even when source or target class is
not prepared.
Index: libjava/verify.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/verify.cc,v
retrieving revision 1.48.2.4
diff -u -r1.48.2.4 verify.cc
--- libjava/verify.cc 11 Apr 2003 01:57:20 -0000 1.48.2.4
+++ libjava/verify.cc 1 May 2003 16:59:24 -0000
@@ -240,64 +240,6 @@
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
@@ -520,7 +462,7 @@
// We must resolve both types and check assignability.
resolve (verifier);
k.resolve (verifier);
- return is_assignable_from_slow (data.klass, k.data.klass);
+ return _Jv_IsAssignableFrom (data.klass, k.data.klass);
}
bool isvoid () const
@@ -707,7 +649,7 @@
// Ordinarily this terminates when we hit Object...
while (k != NULL)
{
- if (is_assignable_from_slow (k, oldk))
+ if (_Jv_IsAssignableFrom (k, oldk))
break;
k = k->getSuperclass ();
changed = true;
Index: libjava/java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.57.2.1
diff -u -r1.57.2.1 natClass.cc
--- libjava/java/lang/natClass.cc 19 Dec 2002 19:32:17 -0000 1.57.2.1
+++ libjava/java/lang/natClass.cc 1 May 2003 16:59:25 -0000
@@ -964,14 +964,14 @@
{
if (source == target)
return true;
-
+
// If target is array, so must source be.
- if (target->isArray ())
+ while (target->isArray ())
{
if (! source->isArray())
return false;
- return _Jv_IsAssignableFrom(target->getComponentType(),
- source->getComponentType());
+ target = target->getComponentType();
+ source = source->getComponentType();
}
if (target->isInterface())
@@ -981,7 +981,7 @@
if (__builtin_expect
(source->idt == NULL || source->isInterface(), false))
return _Jv_InterfaceAssignableFrom (target, source);
-
+
_Jv_IDispatchTable *cl_idt = source->idt;
_Jv_IDispatchTable *if_idt = target->idt;
@@ -997,23 +997,31 @@
}
return false;
}
-
+
// Primitive TYPE classes are only assignable to themselves.
- if (__builtin_expect (target->isPrimitive(), false))
+ if (__builtin_expect (target->isPrimitive() || source->isPrimitive(), false))
return false;
-
+
if (target == &java::lang::Object::class$)
+ return true;
+ else if (source->ancestors == NULL || target->ancestors == NULL)
{
- if (source->isPrimitive())
- return false;
- return true;
- }
- else if (source->ancestors != NULL
- && target->ancestors != NULL
- && source->depth >= target->depth
+ // We need this case when either SOURCE or TARGET has not has
+ // its constant-time tables prepared.
+
+ // At this point we know that TARGET can't be Object, so it is
+ // safe to use that as the termination point.
+ while (source && source != &java::lang::Object::class$)
+ {
+ if (source == target)
+ return true;
+ source = source->getSuperclass();
+ }
+ }
+ else if (source->depth >= target->depth
&& source->ancestors[source->depth - target->depth] == target)
return true;
-
+
return false;
}
@@ -1352,7 +1360,7 @@
}
static _Jv_Mutex_t iindex_mutex;
-bool iindex_mutex_initialized = false;
+static bool iindex_mutex_initialized = false;
// We need to find the correct offset in the Class Interface Dispatch
// Table for a given interface. Once we have that, invoking an interface
Index: libjava/testsuite/ChangeLog
from Tom Tromey <tromey@redhat.com>
PR libgcj/10582:
* libjava.lang/assign.java: New file.
* libjava.lang/assign.out: New file.
Index: libjava/testsuite/libjava.lang/assign.java
===================================================================
RCS file: libjava/testsuite/libjava.lang/assign.java
diff -N libjava/testsuite/libjava.lang/assign.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libjava/testsuite/libjava.lang/assign.java 1 May 2003 16:59:26 -0000
@@ -0,0 +1,19 @@
+// Test for an array assignment bug we've had.
+
+public class assign
+{
+ public static class base
+ {
+ }
+
+ public static class derived extends base
+ {
+ }
+
+ public static void main(String[] args)
+ {
+ base[][] x1 = new base[3][3];
+ derived[] x2 = new derived[3];
+ x1[0] = x2;
+ }
+}
Index: libjava/testsuite/libjava.lang/assign.out
===================================================================
RCS file: libjava/testsuite/libjava.lang/assign.out
diff -N libjava/testsuite/libjava.lang/assign.out