6594284: NPE thrown when calling a method on an intersection type
authormcimadamore
Thu, 24 Jul 2008 11:12:41 +0100
changeset 938 13aae74ca013
parent 937 457a11ae2e84
child 939 38e24969c7e9
6594284: NPE thrown when calling a method on an intersection type Summary: javac should report an error when the capture of an actual type parameter does not exist Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/code/Type.java
langtools/src/share/classes/com/sun/tools/javac/code/Types.java
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/test/tools/javac/capture/T6594284.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Jul 24 10:35:38 2008 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Jul 24 11:12:41 2008 +0100
@@ -979,6 +979,10 @@
             return TypeKind.TYPEVAR;
         }
 
+        public boolean isCaptured() {
+            return false;
+        }
+
         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
             return v.visitTypeVariable(this, p);
         }
@@ -1015,6 +1019,11 @@
         }
 
         @Override
+        public boolean isCaptured() {
+            return true;
+        }
+
+        @Override
         public String toString() {
             return "capture#"
                 + (hashCode() & 0xFFFFFFFFL) % PRIME
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 24 10:35:38 2008 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 24 11:12:41 2008 +0100
@@ -835,7 +835,7 @@
         };
 
     public boolean isCaptureOf(Type s, WildcardType t) {
-        if (s.tag != TYPEVAR || !(s instanceof CapturedType))
+        if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured())
             return false;
         return isSameWildcard(t, ((CapturedType)s).wildcard);
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 24 10:35:38 2008 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 24 11:12:41 2008 +0100
@@ -422,7 +422,34 @@
      *  @param bs            The bound.
      */
     private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) {
-        if (!(a instanceof CapturedType)) {
+        if (a.tag == TYPEVAR && ((TypeVar)a).isCaptured()) {
+            CapturedType ct = (CapturedType)a;
+            boolean ok;
+            if (ct.bound.isErroneous()) {//capture doesn't exist
+                ok = false;
+            }
+            else {
+                switch (ct.wildcard.kind) {
+                    case EXTENDS:
+                        ok = types.isCastable(bs.getUpperBound(),
+                                types.upperBound(a),
+                                Warner.noWarnings);
+                        break;
+                    case SUPER:
+                        ok = !types.notSoftSubtype(types.lowerBound(a),
+                                bs.getUpperBound());
+                        break;
+                    case UNBOUND:
+                        ok = true;
+                        break;
+                    default:
+                        throw new AssertionError("Invalid bound kind");
+                }
+            }
+            if (!ok)
+                log.error(pos, "not.within.bounds", a);
+        }
+        else {
             a = types.upperBound(a);
             for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
                 if (!types.isSubtype(a, l.head)) {
@@ -431,25 +458,6 @@
                 }
             }
         }
-        else {
-            CapturedType ct = (CapturedType)a;
-            boolean ok = false;
-            switch (ct.wildcard.kind) {
-                case EXTENDS:
-                    ok = types.isCastable(bs.getUpperBound(),
-                            types.upperBound(a),
-                            Warner.noWarnings);
-                    break;
-                case SUPER:
-                    ok = !types.notSoftSubtype(types.lowerBound(a),
-                            bs.getUpperBound());
-                    break;
-                case UNBOUND:
-                    ok = true;
-            }
-            if (!ok)
-                log.error(pos, "not.within.bounds", a);
-        }
     }
 
     /** Check that type is different from 'void'.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/capture/T6594284.java	Thu Jul 24 11:12:41 2008 +0100
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6594284
+ * @summary NPE thrown when calling a method on an intersection type
+ * @author Maurizio Cimadamore
+ *
+ * @compile/fail T6594284.java
+ */
+
+public class T6594284 {
+    class A{ public void a(){}}
+    class B extends A{ public void b(){}}
+    interface I{ void i();}
+    interface I1 { void i1(); }
+    class E extends B implements I{ public void i(){};}
+
+    class C<W extends B & I1, T extends W>{
+        C<? extends I, ? extends E> arg;
+    }
+}