6594284: NPE thrown when calling a method on an intersection type

Thu, 24 Jul 2008 11:12:41 +0100

author
mcimadamore
date
Thu, 24 Jul 2008 11:12:41 +0100
changeset 79
36df13bde238
parent 78
77dba8b57346
child 80
5c9cdeb740f2

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

src/share/classes/com/sun/tools/javac/code/Type.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Check.java file | annotate | diff | comparison | revisions
test/tools/javac/capture/T6594284.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Jul 24 10:35:38 2008 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Thu Jul 24 11:12:41 2008 +0100
     1.3 @@ -979,6 +979,10 @@
     1.4              return TypeKind.TYPEVAR;
     1.5          }
     1.6  
     1.7 +        public boolean isCaptured() {
     1.8 +            return false;
     1.9 +        }
    1.10 +
    1.11          public <R, P> R accept(TypeVisitor<R, P> v, P p) {
    1.12              return v.visitTypeVariable(this, p);
    1.13          }
    1.14 @@ -1015,6 +1019,11 @@
    1.15          }
    1.16  
    1.17          @Override
    1.18 +        public boolean isCaptured() {
    1.19 +            return true;
    1.20 +        }
    1.21 +
    1.22 +        @Override
    1.23          public String toString() {
    1.24              return "capture#"
    1.25                  + (hashCode() & 0xFFFFFFFFL) % PRIME
     2.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 24 10:35:38 2008 +0100
     2.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 24 11:12:41 2008 +0100
     2.3 @@ -835,7 +835,7 @@
     2.4          };
     2.5  
     2.6      public boolean isCaptureOf(Type s, WildcardType t) {
     2.7 -        if (s.tag != TYPEVAR || !(s instanceof CapturedType))
     2.8 +        if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured())
     2.9              return false;
    2.10          return isSameWildcard(t, ((CapturedType)s).wildcard);
    2.11      }
     3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 24 10:35:38 2008 +0100
     3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 24 11:12:41 2008 +0100
     3.3 @@ -422,7 +422,34 @@
     3.4       *  @param bs            The bound.
     3.5       */
     3.6      private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) {
     3.7 -        if (!(a instanceof CapturedType)) {
     3.8 +        if (a.tag == TYPEVAR && ((TypeVar)a).isCaptured()) {
     3.9 +            CapturedType ct = (CapturedType)a;
    3.10 +            boolean ok;
    3.11 +            if (ct.bound.isErroneous()) {//capture doesn't exist
    3.12 +                ok = false;
    3.13 +            }
    3.14 +            else {
    3.15 +                switch (ct.wildcard.kind) {
    3.16 +                    case EXTENDS:
    3.17 +                        ok = types.isCastable(bs.getUpperBound(),
    3.18 +                                types.upperBound(a),
    3.19 +                                Warner.noWarnings);
    3.20 +                        break;
    3.21 +                    case SUPER:
    3.22 +                        ok = !types.notSoftSubtype(types.lowerBound(a),
    3.23 +                                bs.getUpperBound());
    3.24 +                        break;
    3.25 +                    case UNBOUND:
    3.26 +                        ok = true;
    3.27 +                        break;
    3.28 +                    default:
    3.29 +                        throw new AssertionError("Invalid bound kind");
    3.30 +                }
    3.31 +            }
    3.32 +            if (!ok)
    3.33 +                log.error(pos, "not.within.bounds", a);
    3.34 +        }
    3.35 +        else {
    3.36              a = types.upperBound(a);
    3.37              for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
    3.38                  if (!types.isSubtype(a, l.head)) {
    3.39 @@ -431,25 +458,6 @@
    3.40                  }
    3.41              }
    3.42          }
    3.43 -        else {
    3.44 -            CapturedType ct = (CapturedType)a;
    3.45 -            boolean ok = false;
    3.46 -            switch (ct.wildcard.kind) {
    3.47 -                case EXTENDS:
    3.48 -                    ok = types.isCastable(bs.getUpperBound(),
    3.49 -                            types.upperBound(a),
    3.50 -                            Warner.noWarnings);
    3.51 -                    break;
    3.52 -                case SUPER:
    3.53 -                    ok = !types.notSoftSubtype(types.lowerBound(a),
    3.54 -                            bs.getUpperBound());
    3.55 -                    break;
    3.56 -                case UNBOUND:
    3.57 -                    ok = true;
    3.58 -            }
    3.59 -            if (!ok)
    3.60 -                log.error(pos, "not.within.bounds", a);
    3.61 -        }
    3.62      }
    3.63  
    3.64      /** Check that type is different from 'void'.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/tools/javac/capture/T6594284.java	Thu Jul 24 11:12:41 2008 +0100
     4.3 @@ -0,0 +1,43 @@
     4.4 +/*
     4.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.
    4.11 + *
    4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.15 + * version 2 for more details (a copy is included in the LICENSE file that
    4.16 + * accompanied this code).
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License version
    4.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.21 + *
    4.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    4.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    4.24 + * have any questions.
    4.25 + */
    4.26 +
    4.27 +/*
    4.28 + * @test
    4.29 + * @bug 6594284
    4.30 + * @summary NPE thrown when calling a method on an intersection type
    4.31 + * @author Maurizio Cimadamore
    4.32 + *
    4.33 + * @compile/fail T6594284.java
    4.34 + */
    4.35 +
    4.36 +public class T6594284 {
    4.37 +    class A{ public void a(){}}
    4.38 +    class B extends A{ public void b(){}}
    4.39 +    interface I{ void i();}
    4.40 +    interface I1 { void i1(); }
    4.41 +    class E extends B implements I{ public void i(){};}
    4.42 +
    4.43 +    class C<W extends B & I1, T extends W>{
    4.44 +        C<? extends I, ? extends E> arg;
    4.45 +    }
    4.46 +}

mercurial