|
Quick Lists
|
|
Bug ID:
|
6614974
|
|
Votes
|
0
|
|
Synopsis
|
javac successfully compiles code that throws java.lang.VerifyError when run
|
|
Category
|
java:compiler
|
|
Reported Against
|
|
|
Release Fixed
|
7(b25)
|
|
State
|
10-Fix Delivered,
bug
|
|
Priority:
|
4-Low
|
|
Related Bugs
|
6355696
|
|
Submit Date
|
10-OCT-2007
|
|
Description
|
FULL PRODUCT VERSION :
java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
customer Windows XP [Version 5.1.2600]
A DESCRIPTION OF THE PROBLEM :
The following code compiles successfully with javac:
public class BugReport<T> {
private T n;
public void error() {
BugReport<Integer> val = new BugReport<Integer>();
val.n = 0;
Integer.toString(val.n++);
}
public static void main(String[] args) {
BugReport.class.getMethods();
}
}
However, when run with `java BugReport', it always throws the following error:
Exception in thread "main" java.lang.VerifyError: (class: BugReport, method: error signature: ()V) Incompatible customer argument for function call
This is likely due to the generics/autoboxing combination that fails in this case at the line Integer.toString(val.n++).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the code from the description and run it.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No error.
ACTUAL -
This error:
Exception in thread "main" java.lang.VerifyError: (class: BugReport, method: error signature: ()V) Incompatible customer argument for function call
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.VerifyError: (class: BugReport, method: error signature: ()V) Incompatible customer argument for function call
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class BugReport<T> {
private T n;
public void error() {
BugReport<Integer> val = new BugReport<Integer>();
val.n = 0;
Integer.toString(val.n++);
}
public static void main(String[] args) {
BugReport.class.getMethods();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
val.n++ can be moved out of the method call and the call itself can be changed to Integer.toString(val.n).
Posted Date : 2007-10-10 01:54:12.0
|
|
Work Around
|
N/A
|
|
Evaluation
|
Cast from Object to Integer is missing before pc=46.
public void error();
Code:
0: new #2; //class BugReport
3: dup
4: invokespecial #3; //Method "<init>":()V
7: astore_1
8: aload_1
9: iconst_0
10: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
13: putfield #5; //Field n:Ljava/lang/Object;
16: aload_1
17: astore_2
18: aload_2
19: getfield #5; //Field n:Ljava/lang/Object;
22: astore_3
23: aload_2
24: aload_2
25: getfield #5; //Field n:Ljava/lang/Object;
28: checkcast #6; //class java/lang/Integer
31: invokevirtual #7; //Method java/lang/Integer.intValue:()I
34: iconst_1
35: iadd
36: invokestatic #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
39: dup_x1
40: putfield #5; //Field n:Ljava/lang/Object;
43: astore 4
45: aload_3
*** aload_3 loads raw type val.n;
*** need checkcast #6 // class java/lang/Integer
46: invokevirtual #7; //Method java/lang/Integer.intValue:()I
49: invokestatic #8; //Method java/lang/Integer.toString:(I)Ljava/lang/String;
52: pop
53: return
Posted Date : 2008-01-04 01:21:55.0
Autoboxing is implemented by javac by means of LetExpr nodes of AST of the kind
let int v = i.intValue in ...; //where i is a variable whose type is Integer
However, when the compiler generates those LetExpr nodes, a synthetic cast should be added if the type of the right handed expression is a type variable as described in the example:
let int v = n.intValue() in v++ ...;
Here, since n is of type T, a type variable whose bound is Object. Since no synthetic cast is added by the compiler, the LetExpr flows into the compiler pipeline, thus causing bad code to be generated since T is erased to Object and Object does not define a method intValue(). The solution to the problem is to force an explicit type conversion to the actual type of T (which is known at compile-time) so that the LetExpr node is generated as follows:
let int v = ((Integer)n).intValue() in v++ ...;
Posted Date : 2008-02-11 11:05:51.0
|
|
Comments
|
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |