United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4368664 : VerifyError when using array of arrays

Details
Type:
Bug
Submit Date:
2000-09-06
Status:
Resolved
Updated Date:
2002-11-07
Project Name:
JDK
Resolved Date:
2002-11-07
Component:
tools
OS:
windows_nt,windows_98
Sub-Component:
javac
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
1.2.2,1.3.0
Fixed Versions:
1.4.2 (mantis)

Related Reports
Relates:

Sub Tasks

Description

Name: tb29552			Date: 09/06/2000


/*
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

The "javac" compiler accept the following code, but "java" throws a VerifyError:

*/
public class ArrayTest {
    public static void main(final String[] args) {
    }

    private static void neverCalled() {
        float[][] channels = null;
        channels[0] = resize(channels[0]);
    }

    private static float[] resize(final float[] array) {
        return null;
    }
}
/*

When I try to run this code (with "java Test"), I get the following message:

Exception in thread "main" java.lang.VerifyError: (class: Test, method:
neverCalled signature: ()V) Incompatible types for storing into array of arrays
or objects

A work around is to replace "float[][] channels=null" by "float[][]
channels=float[0][]". The problem is that in my complete class, "channels" was
lazily created only when needed.

Thanks,

*/

(Review ID: 106837) 
======================================================================

                                    

Comments
WORK AROUND



Name: tb29552			Date: 09/06/2000


Do not use "float[][] x=null". Use "float[][] x=new float[0][]" instead.
======================================================================

An alternative workaround:

Do not use "channels[0] = resize(channels[0]);". 
Use "float[] temp = resize(channels[0]);" or "channels[0] = null;" instead.

###@###.###    2001-7-10
                                     
2001-07-10
EVALUATION

Looks like a verifier issue.

Both javac and oldjavac produce the same code for this example, which
appears to be correct.  Note that the code does attempt to subscript
an array variable that contains null, which should result in an
exception at runtime.  The generated code is as follows:

super public class ArrayTest
{


public Method "<init>":"()V"
	stack 1 locals 1
{
		aload_0;
		invokespecial	Method java/lang/Object."<init>":"()V";
		return;
}

public static Method main:"([Ljava/lang/String;)V"
	stack 0 locals 1
{
		return;
}

private static Method neverCalled:"()V"
	stack 4 locals 1
{
		aconst_null;
		astore_0;
		aload_0;
		iconst_0;
		aload_0;
		iconst_0;
		aaload;
		invokestatic	Method resize:"([F)[F";
		aastore;
		return;
}

private static Method resize:"([F)[F"
	stack 1 locals 1
{
		aconst_null;
		areturn;
}

} // end Class ArrayTest


william.maddox@Eng 2000-10-24

=======================================================

This is not a verifier bug. The byte code in method neverCalled() as shown above has a type error in aastore.  

The compiled byte code has lost the declaration information in the source code.
Therefore local variable 0 does not has [[F type. Instead, both local variable 0 and its value pushed on operand stack have null type. Their component types are null as well.

After method 'resize' is invoked, the verifier pushes type [F (return type of 'resize') on the operand stack. Note that each method is verified separately. So method 'neverCalled' does not know that 'resize' returns null. It only knows that 'resize' returns [F from its signature. 

According to JVM Spec 2nd edition P. 176 (aastore), the top of current operand stack type (the return type of 'resize') must be assignment compatible with the type of the components of the array type on the third of operand stack (it is null here). Because type [F is not assignable to null, the verifier detects a type error. 

Another workaround is to assign resize(channels[0]) to another variable instead of channels[0], or directly assign null to channels[0] without calling resize.

This bug will be closed as not a bug.

###@###.###    2001-7-10

I'm reopening this report, because our toolchain still doesn't function.
Yes, the verifier is behaving as specified, but nevertheless a correct
Java program fails to run.

This is an unfortunate mismatch between the compikler (javac) and the
verifier.  I'm keeping this bug open until the program runs fine
on the product.

Note that it would be possible to "fix" the compiler by emitting casts into
the code whenever null is used as a value of a multidimensional array type.

###@###.### 2002-09-26
                                     
2002-09-26
PUBLIC COMMENTS

We expect to modify the verifier spec and implementation by JDK 1.5 so that 
this will not be an issue.
                                     
2004-06-10
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mantis

FIXED IN:
mantis

INTEGRATED IN:
mantis
mantis-b07


                                     
2004-06-14



Hardware and Software, Engineered to Work Together