8058511: StackOverflowError at com.sun.tools.javac.code.Types.lub

Tue, 28 Oct 2014 14:59:42 +0000

author
mcimadamore
date
Tue, 28 Oct 2014 14:59:42 +0000
changeset 2597
ac75605c22f6
parent 2596
fa8be3ce18fc
child 2598
88ce114c6adc

8058511: StackOverflowError at com.sun.tools.javac.code.Types.lub
Summary: Lub crashes when handling typevar with array bound
Reviewed-by: vromero, dlsmith

src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/8058511/T8058511a.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/8058511/T8058511b.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/8058511/T8058511c.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Tue Oct 28 08:56:23 2014 +0100
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Tue Oct 28 14:59:42 2014 +0000
     1.3 @@ -1892,7 +1892,12 @@
     1.4       * Mapping to take element type of an arraytype
     1.5       */
     1.6      private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
     1.7 -        public Type apply(Type t) { return elemtype(t); }
     1.8 +        public Type apply(Type t) {
     1.9 +            while (t.hasTag(TYPEVAR)) {
    1.10 +                t = t.getUpperBound();
    1.11 +            }
    1.12 +            return elemtype(t);
    1.13 +        }
    1.14      };
    1.15  
    1.16      /**
    1.17 @@ -3521,40 +3526,46 @@
    1.18      }
    1.19  
    1.20      /**
    1.21 -     * Return the least upper bound of pair of types.  if the lub does
    1.22 +     * Return the least upper bound of list of types.  if the lub does
    1.23       * not exist return null.
    1.24       */
    1.25 -    public Type lub(Type t1, Type t2) {
    1.26 -        return lub(List.of(t1, t2));
    1.27 +    public Type lub(List<Type> ts) {
    1.28 +        return lub(ts.toArray(new Type[ts.length()]));
    1.29      }
    1.30  
    1.31      /**
    1.32       * Return the least upper bound (lub) of set of types.  If the lub
    1.33       * does not exist return the type of null (bottom).
    1.34       */
    1.35 -    public Type lub(List<Type> ts) {
    1.36 +    public Type lub(Type... ts) {
    1.37 +        final int UNKNOWN_BOUND = 0;
    1.38          final int ARRAY_BOUND = 1;
    1.39          final int CLASS_BOUND = 2;
    1.40 -        int boundkind = 0;
    1.41 -        for (Type t : ts) {
    1.42 +
    1.43 +        int[] kinds = new int[ts.length];
    1.44 +
    1.45 +        int boundkind = UNKNOWN_BOUND;
    1.46 +        for (int i = 0 ; i < ts.length ; i++) {
    1.47 +            Type t = ts[i];
    1.48              switch (t.getTag()) {
    1.49              case CLASS:
    1.50 -                boundkind |= CLASS_BOUND;
    1.51 +                boundkind |= kinds[i] = CLASS_BOUND;
    1.52                  break;
    1.53              case ARRAY:
    1.54 -                boundkind |= ARRAY_BOUND;
    1.55 +                boundkind |= kinds[i] = ARRAY_BOUND;
    1.56                  break;
    1.57              case  TYPEVAR:
    1.58                  do {
    1.59                      t = t.getUpperBound();
    1.60                  } while (t.hasTag(TYPEVAR));
    1.61                  if (t.hasTag(ARRAY)) {
    1.62 -                    boundkind |= ARRAY_BOUND;
    1.63 +                    boundkind |= kinds[i] = ARRAY_BOUND;
    1.64                  } else {
    1.65 -                    boundkind |= CLASS_BOUND;
    1.66 +                    boundkind |= kinds[i] = CLASS_BOUND;
    1.67                  }
    1.68                  break;
    1.69              default:
    1.70 +                kinds[i] = UNKNOWN_BOUND;
    1.71                  if (t.isPrimitive())
    1.72                      return syms.errType;
    1.73              }
    1.74 @@ -3565,15 +3576,16 @@
    1.75  
    1.76          case ARRAY_BOUND:
    1.77              // calculate lub(A[], B[])
    1.78 -            List<Type> elements = Type.map(ts, elemTypeFun);
    1.79 -            for (Type t : elements) {
    1.80 -                if (t.isPrimitive()) {
    1.81 +            Type[] elements = new Type[ts.length];
    1.82 +            for (int i = 0 ; i < ts.length ; i++) {
    1.83 +                Type elem = elements[i] = elemTypeFun.apply(ts[i]);
    1.84 +                if (elem.isPrimitive()) {
    1.85                      // if a primitive type is found, then return
    1.86                      // arraySuperType unless all the types are the
    1.87                      // same
    1.88 -                    Type first = ts.head;
    1.89 -                    for (Type s : ts.tail) {
    1.90 -                        if (!isSameType(first, s)) {
    1.91 +                    Type first = ts[0];
    1.92 +                    for (int j = 1 ; j < ts.length ; j++) {
    1.93 +                        if (!isSameType(first, ts[j])) {
    1.94                               // lub(int[], B[]) is Cloneable & Serializable
    1.95                              return arraySuperType();
    1.96                          }
    1.97 @@ -3588,13 +3600,20 @@
    1.98  
    1.99          case CLASS_BOUND:
   1.100              // calculate lub(A, B)
   1.101 -            while (!ts.head.hasTag(CLASS) && !ts.head.hasTag(TYPEVAR)) {
   1.102 -                ts = ts.tail;
   1.103 +            int startIdx = 0;
   1.104 +            for (int i = 0; i < ts.length ; i++) {
   1.105 +                Type t = ts[i];
   1.106 +                if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) {
   1.107 +                    break;
   1.108 +                } else {
   1.109 +                    startIdx++;
   1.110 +                }
   1.111              }
   1.112 -            Assert.check(!ts.isEmpty());
   1.113 +            Assert.check(startIdx < ts.length);
   1.114              //step 1 - compute erased candidate set (EC)
   1.115 -            List<Type> cl = erasedSupertypes(ts.head);
   1.116 -            for (Type t : ts.tail) {
   1.117 +            List<Type> cl = erasedSupertypes(ts[startIdx]);
   1.118 +            for (int i = startIdx + 1 ; i < ts.length ; i++) {
   1.119 +                Type t = ts[i];
   1.120                  if (t.hasTag(CLASS) || t.hasTag(TYPEVAR))
   1.121                      cl = intersect(cl, erasedSupertypes(t));
   1.122              }
   1.123 @@ -3603,9 +3622,9 @@
   1.124              //step 3 - for each element G in MEC, compute lci(Inv(G))
   1.125              List<Type> candidates = List.nil();
   1.126              for (Type erasedSupertype : mec) {
   1.127 -                List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
   1.128 -                for (Type t : ts) {
   1.129 -                    lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
   1.130 +                List<Type> lci = List.of(asSuper(ts[startIdx], erasedSupertype.tsym));
   1.131 +                for (int i = startIdx + 1 ; i < ts.length ; i++) {
   1.132 +                    lci = intersect(lci, List.of(asSuper(ts[i], erasedSupertype.tsym)));
   1.133                  }
   1.134                  candidates = candidates.appendList(lci);
   1.135              }
   1.136 @@ -3616,9 +3635,9 @@
   1.137          default:
   1.138              // calculate lub(A, B[])
   1.139              List<Type> classes = List.of(arraySuperType());
   1.140 -            for (Type t : ts) {
   1.141 -                if (!t.hasTag(ARRAY)) // Filter out any arrays
   1.142 -                    classes = classes.prepend(t);
   1.143 +            for (int i = 0 ; i < ts.length ; i++) {
   1.144 +                if (kinds[i] != ARRAY_BOUND) // Filter out any arrays
   1.145 +                    classes = classes.prepend(ts[i]);
   1.146              }
   1.147              // lub(A, B[]) is lub(A, arraySuperType)
   1.148              return lub(classes);
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/test/tools/javac/generics/inference/8058511/T8058511a.java	Tue Oct 28 14:59:42 2014 +0000
     2.3 @@ -0,0 +1,38 @@
     2.4 +/*
     2.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.  Oracle designates this
    2.11 + * particular file as subject to the "Classpath" exception as provided
    2.12 + * by Oracle in the LICENSE file that accompanied this code.
    2.13 + *
    2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.17 + * version 2 for more details (a copy is included in the LICENSE file that
    2.18 + * accompanied this code).
    2.19 + *
    2.20 + * You should have received a copy of the GNU General Public License version
    2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.23 + *
    2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.25 + * or visit www.oracle.com if you need additional information or have any
    2.26 + * questions.
    2.27 + */
    2.28 +
    2.29 +/**
    2.30 + * @test
    2.31 + * @bug 8058511
    2.32 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
    2.33 + * @compile T8058511a.java
    2.34 + */
    2.35 +class T8058511a {
    2.36 +    <Z> void choose(Z z1, Z z2) { }
    2.37 +
    2.38 +    void test(Class<Double> cd, Class<? extends double[]> cdarr) {
    2.39 +        choose(cd, cdarr);
    2.40 +    }
    2.41 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/tools/javac/generics/inference/8058511/T8058511b.java	Tue Oct 28 14:59:42 2014 +0000
     3.3 @@ -0,0 +1,36 @@
     3.4 +/*
     3.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.  Oracle designates this
    3.11 + * particular file as subject to the "Classpath" exception as provided
    3.12 + * by Oracle in the LICENSE file that accompanied this code.
    3.13 + *
    3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.17 + * version 2 for more details (a copy is included in the LICENSE file that
    3.18 + * accompanied this code).
    3.19 + *
    3.20 + * You should have received a copy of the GNU General Public License version
    3.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.23 + *
    3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.25 + * or visit www.oracle.com if you need additional information or have any
    3.26 + * questions.
    3.27 + */
    3.28 +
    3.29 +/**
    3.30 + * @test
    3.31 + * @bug 8058511
    3.32 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
    3.33 + * @compile T8058511b.java
    3.34 + */
    3.35 +class T8058511b {
    3.36 +    void test(Class<Double> cd, Class<? extends double[]> cdarr) {
    3.37 +        ((false) ? cd : cdarr).toString();
    3.38 +    }
    3.39 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/tools/javac/generics/inference/8058511/T8058511c.java	Tue Oct 28 14:59:42 2014 +0000
     4.3 @@ -0,0 +1,38 @@
     4.4 +/*
     4.5 + * Copyright (c) 2014, Oracle and/or its affiliates. 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.  Oracle designates this
    4.11 + * particular file as subject to the "Classpath" exception as provided
    4.12 + * by Oracle in the LICENSE file that accompanied this code.
    4.13 + *
    4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 + * version 2 for more details (a copy is included in the LICENSE file that
    4.18 + * accompanied this code).
    4.19 + *
    4.20 + * You should have received a copy of the GNU General Public License version
    4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 + *
    4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.25 + * or visit www.oracle.com if you need additional information or have any
    4.26 + * questions.
    4.27 + */
    4.28 +
    4.29 +/**
    4.30 + * @test
    4.31 + * @bug 8058511
    4.32 + * @summary StackOverflowError at com.sun.tools.javac.code.Types.lub
    4.33 + * @compile T8058511c.java
    4.34 + */
    4.35 +import java.util.List;
    4.36 +
    4.37 +class T8058511c {
    4.38 +    void test(List<? extends double[]> l) {
    4.39 +        (true ? l.get(0) : l.get(0)).toString();
    4.40 +    }
    4.41 +}

mercurial