problem in gij bytecode verifier
Sonja Krause-Harder
skh@suse.de
Sun Feb 29 05:17:00 GMT 2004
Hi,
I've found a problem in gij's bytecode verifier. Consider the following
(legal) code:
public class Main {
// I is an interface
public static void a (I i) {}
public static void main (String[] argv) {
// A implements I ...
I i = new A ();
if (foo()) {
// ... and so does B.
i = new B ();
}
a (i);
}
public static boolean foo () {
return true;
}
}
resulting in the following bytecode:
Method name:"main" public static Signature: 9=(java.lang.String[])void
Attribute "Code", length:63, max_stack:2, max_locals:2, code_length:27
0: new #11=<Class A>
3: dup
4: invokespecial #15=<Method A.<init> ()void>
7: astore_1
8: invokestatic #19=<Method Main.foo ()boolean>
11: ifeq 22
14: new #21=<Class B>
17: dup
18: invokespecial #22=<Method B.<init> ()void>
21: astore_1
22: aload_1
23: invokestatic #24=<Method Main.a (I)void>
26: return
This fails during verification with:
Exception in thread "main" java.lang.VerifyError: verification failed at PC 23
in Main:main(([Ljava.lang.String;)V): incompatible type on stack
(...)
The error does not occur when A extends B or vice versa.
I suspect that during the state merge at PC 22, the information about the
interface implemented by A and B is lost, leading to an plain Object passed to a().
The following snippet from type->merge() in libjava/verify.cc led to this suspicion:
(...)
// Ordinarily this terminates when we hit Object...
while (k != NULL)
{
if (is_assignable_from_slow (k, oldk))
break;
k = k->getSuperclass ();
changed = true;
}
// ... but K could have been an interface, in which
// case we'll end up here. We just convert this
// into Object.
if (k == NULL)
k = &java::lang::Object::class$;
(...)
but I'm neither sure that my analysis is correct, nor what an appropriate fix
would be.
Any hints would be very welcome. Complete testcase attached.
regards,
Sonja
--
Sonja Krause-Harder (skh@suse.de) SuSE Linux AG
-------------- next part --------------
A non-text attachment was scrubbed...
Name: interface_verify_error.tar.gz
Type: application/x-gunzip
Size: 585 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/java/attachments/20040229/b5056211/attachment.bin>
More information about the Java
mailing list