Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
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
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang