JDK-6514483 : Compiler NPE with impossible generic type
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2007-01-18
  • Updated: 2011-02-16
  • Resolved: 2008-07-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7Resolved
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

A DESCRIPTION OF THE PROBLEM :
When dealing with a type for which no instance is possible, where one wildcard parameter indirectly has two separate classes (which aren't a supertype of eachother) as supertype, the compiler can crash with a NPE.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the given code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
An error message about the types, or compiling without errors
ACTUAL -
Compiler crash

ERROR MESSAGES/STACK TRACES THAT OCCUR :
An exception has occurred in the compiler (1.6.0). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport)  after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report.  Thank you.
java.lang.NullPointerException
        at com.sun.tools.javac.comp.TransTypes.retype(TransTypes.java:135)
        at com.sun.tools.javac.comp.TransTypes.visitApply(TransTypes.java:566)
        at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1210)
        at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:44)
        at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:398)
        at com.sun.tools.javac.comp.TransTypes.visitExec(TransTypes.java:529)
        at com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1074)
        at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:44)
        at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:56)
        at com.sun.tools.javac.tree.TreeTranslator.visitBlock(TreeTranslator.java:146)
        at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:739)
        at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:44)
        at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:398)
        at com.sun.tools.javac.comp.TransTypes.visitMethodDef(TransTypes.java:432)
        at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:639)
        at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:44)
        at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:56)
        at com.sun.tools.javac.tree.TreeTranslator.visitClassDef(TreeTranslator.java:120)
        at com.sun.tools.javac.comp.TransTypes.translateClass(TransTypes.java:742)
        at com.sun.tools.javac.comp.TransTypes.visitClassDef(TransTypes.java:419)
        at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:575)
        at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:44)
        at com.sun.tools.javac.comp.TransTypes.translate(TransTypes.java:398)
        at com.sun.tools.javac.comp.TransTypes.translateTopLevelClass(TransTypes.java:765)
        at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1182)
        at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1118)
        at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:765)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:730)
        at com.sun.tools.javac.main.Main.compile(Main.java:353)
        at com.sun.tools.javac.main.Main.compile(Main.java:279)
        at com.sun.tools.javac.main.Main.compile(Main.java:270)
        at com.sun.tools.javac.Main.compile(Main.java:69)
        at com.sun.tools.javac.Main.main(Main.java:54)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class ImpossibleTypeCrash<P extends Double, Q extends P> {
	Q q;
	void m(ImpossibleTypeCrash<? extends Object, ? extends Integer> itp) {
		itp.q.clone();
	}
}

---------- END SOURCE ----------

Release Regression From : 5.0u10
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
EVALUATION This bug can be regarded as a duplicate of 6594284, since the underlying reason is the very same. Also 6651719 is a related CR. Javac does not recognize that a generic type C<? extends Object, ? extends Integer> given the type declaration class C<X extends Double, Y extends X> This is due to the fact that capture conversion is not applied when checking for bound conformance (see 6651719). The first type-parameter (? extends Object) is accepted by javac; this might seem incorrect, but such a situation is also described in the JLS - the only thing that matters is that such a type parameter can be capture-coverted, and this is true (the resulting captured type variable will have an upper bound that is glb(Object, Double) === Double). As far as the second type parameter is concerned (? extends Integer) javac simply checks this type against the (wrong) actual type-parameter bound, ending up with the following subyping test: Integer <: [X:=? extends Object]X Integer <: ? extends Object Integer <= ? extends Object Integer <: Object true The correct subtyping test would have been: Integer <: [X:=#CAP]X, where #CAP is a captured type variable whose upper bound is Double (see above) Integer <: #CAP false (CAP has no supertype/upper bound in common with Integer) Javac thinks that the two parameters are two correct instantiation of the generic class and this causes problems later on, when javac must exploit capture-conversion e.g. for accessing a field, or invoking a method. As a consequence, if the method m() in the original example was empty, javac would have (incorrectly) accepted this program.
21-05-2008

SUGGESTED FIX The proposed fixes for 6594284 and 6651719 solve this problem too.
21-05-2008