This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[BC] Patch: FYI: two linker fixes
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 27 Oct 2004 09:56:59 -0600
- Subject: [BC] Patch: FYI: two linker fixes
- Reply-to: tromey at redhat dot com
I'm checking this in on the BC branch.
This patch adds a better error message when an invalid access is
tried.
It fixes a buglet in add_miranda_methods, by ensuring that an
interface's supers are all installed.
It fixes a bug in ensure_class_linked where we were resolving classes
too early. This caused us to reject valid bytecode in one case.
The case is when a program refers to a field of another class whose
type is inaccessible. If the type in question is a member type, most
Java compilers (gcj has a bug here, you will never see this with
gcj-compiled code) will emit an InnerClasses entry for that type. If
we resolve the constant pool eagerly, this entry will cause an
IllegalAccessError -- even though the entry is not referred to by any
code.
Both of these bugs were found while running Eclipse 3.
This also contains a patch in a commented-out section that is a merge
from a change made on the mainline. I'll probably just delete this
code at some point.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* link.cc (ensure_class_linked): Only resolve classes for
compiled classes.
(add_miranda_methods): Ensure interface supers are installed.
(resolve_pool_entry): Better error message.
Index: link.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Attic/link.cc,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 link.cc
--- link.cc 18 Oct 2004 23:48:57 -0000 1.1.2.6
+++ link.cc 27 Oct 2004 15:50:32 -0000
@@ -112,9 +112,7 @@
found = _Jv_FindClass (name, klass->loader);
if (! found)
- {
- throw new java::lang::NoClassDefFoundError (name->toString());
- }
+ throw new java::lang::NoClassDefFoundError (name->toString());
// Check accessibility, but first strip array types as
// _Jv_ClassNameSamePackage can't handle arrays.
@@ -131,7 +129,13 @@
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
}
else
- throw new java::lang::IllegalAccessError (found->getName());
+ {
+ java::lang::StringBuffer *sb = new java::lang::StringBuffer ();
+ sb->append(klass->getName());
+ sb->append(JvNewStringLatin1(" can't access class "));
+ sb->append(found->getName());
+ throw new java::lang::IllegalAccessError(sb->toString());
+ }
}
break;
@@ -1427,26 +1431,37 @@
_Jv_Constants *pool = &klass->constants;
- // Resolve class constants first, since other constant pool
- // entries may rely on these.
- for (int index = 1; index < pool->size; ++index)
- {
- if (pool->tags[index] == JV_CONSTANT_Class)
- resolve_pool_entry (klass, index);
+ // Compiled classes require that their class constants be
+ // resolved here. However, interpreted classes need their
+ // constants to be resolved lazily. If we resolve an
+ // interpreted class' constants eagerly, we can end up with
+ // spurious IllegalAccessErrors when the constant pool contains
+ // a reference to a class we can't access. This can validly
+ // occur in an obscure case involving the InnerClasses
+ // attribute.
+ if (! _Jv_IsInterpretedClass (klass))
+ {
+ // Resolve class constants first, since other constant pool
+ // entries may rely on these.
+ for (int index = 1; index < pool->size; ++index)
+ {
+ if (pool->tags[index] == JV_CONSTANT_Class)
+ resolve_pool_entry (klass, index);
+ }
}
#if 0 // Should be redundant now
// If superclass looks like a constant pool entry,
// resolve it now.
if ((uaddr) klass->superclass < (uaddr) pool->size)
- klass->superclass = pool->data[(int) klass->superclass].clazz;
+ klass->superclass = pool->data[(uaddr) klass->superclass].clazz;
// Likewise for interfaces.
for (int i = 0; i < klass->interface_count; i++)
{
if ((uaddr) klass->interfaces[i] < (uaddr) pool->size)
klass->interfaces[i]
- = pool->data[(int) klass->interfaces[i]].clazz;
+ = pool->data[(uaddr) klass->interfaces[i]].clazz;
}
#endif
@@ -1556,6 +1571,7 @@
}
}
+ wait_for_state (interface, JV_STATE_LOADED);
add_miranda_methods (base, interface);
}
}