Community
Participate
Working Groups
Using 1119, we do compile the following test case, but we end up with a VerifyError. Exception in thread "main" java.lang.VerifyError: (class: A, method: main signature: ([Ljava/lang/String;)V) Incompatible types for storing into array of arrays or objects [class A { public static void main(String[] args) { try { int[][] tab = (int[][]) null; tab[0] = new int[1]; } catch (NullPointerException e) { System.out.print("OK"); } } }] The fix for this one seems to be in the CastExpression, in the method: areTypeCastCompatible.... if (expressionType == NullBinding) { /**/ if (castType.isArrayType()) { needRuntimeCheckcast = true; }/**/ return; //null is compatible with every thing } Adding the code between the two /**/ fixes the problem. It forces a checkcast to be generated even if the expression is null. Jikes 1.17 has the bug too and javac 1.4.1 compiles the code with a checkcast and therefore doesn't have a VerifyError.
Almost the same pattern: class A { public static void main(String[] args) { try { int[][] tab; tab = null; tab[0] = new int[1]; } catch (NullPointerException e) { System.out.print("OK"); } } } With this code, all compilers (jikes, javac and eclipse) compile fine, but get a VerifyError at runtime.
This second bug seems to be in SingleNameReference when generating the code for a local variable. We might want to add before the store call: if (assignment.expression.resolvedType == NullBinding && assignment.lhs.resolvedType.isArrayType()) { codeStream.checkcast(assignment.lhs.resolvedType); } // normal local assignment (since cannot store in outer local which are final locations) codeStream.store(localBinding, valueRequired);
All kind of references would be affected by the same bug. Need to investigate.
The problem is that these extra cast are only relevant when using local variables, not fields.
Also, the first scenario is a read herring. The real issue is the second one. Solving the second will make the first one work fine as well.
Fixed
Verified.