8044546: Crash on faulty reduce/lambda

Fri, 20 Jun 2014 20:36:54 +0100

author
vromero
date
Fri, 20 Jun 2014 20:36:54 +0100
changeset 2543
c6d5efccedc3
parent 2542
fa6e91185a27
child 2544
91e9834baff2

8044546: Crash on faulty reduce/lambda
Reviewed-by: mcimadamore, dlsmith
Contributed-by: maurizio.cimadamore@oracle.com, vicente.romero@oracle.com

src/share/classes/com/sun/tools/javac/code/Types.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Attr.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Check.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Infer.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/comp/Resolve.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/T8044546/CrashImplicitLambdaTest.java file | annotate | diff | comparison | revisions
test/tools/javac/generics/inference/T8044546/NestedInvocationsTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Jul 17 10:55:50 2014 -0400
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Jun 20 20:36:54 2014 +0100
     1.3 @@ -2954,6 +2954,12 @@
     1.4          }
     1.5  
     1.6          @Override
     1.7 +        public Type visitUndetVar(UndetVar t, Void ignored) {
     1.8 +            //do nothing - we should not replace inside undet variables
     1.9 +            return t;
    1.10 +        }
    1.11 +
    1.12 +        @Override
    1.13          public Type visitClassType(ClassType t, Void ignored) {
    1.14              if (!t.isCompound()) {
    1.15                  List<Type> typarams = t.getTypeArguments();
     2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Jul 17 10:55:50 2014 -0400
     2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jun 20 20:36:54 2014 +0100
     2.3 @@ -252,36 +252,30 @@
     2.4       */
     2.5      Type check(final JCTree tree, final Type found, final int ownkind, final ResultInfo resultInfo) {
     2.6          InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext();
     2.7 -        Type owntype = found;
     2.8 -        if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
     2.9 -            if (allowPoly && inferenceContext.free(found)) {
    2.10 -                if ((ownkind & ~resultInfo.pkind) == 0) {
    2.11 -                    owntype = resultInfo.check(tree, inferenceContext.asUndetVar(owntype));
    2.12 -                } else {
    2.13 -                    log.error(tree.pos(), "unexpected.type",
    2.14 -                            kindNames(resultInfo.pkind),
    2.15 -                            kindName(ownkind));
    2.16 -                    owntype = types.createErrorType(owntype);
    2.17 -                }
    2.18 +        Type owntype;
    2.19 +        if (!found.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) {
    2.20 +            if ((ownkind & ~resultInfo.pkind) != 0) {
    2.21 +                log.error(tree.pos(), "unexpected.type",
    2.22 +                        kindNames(resultInfo.pkind),
    2.23 +                        kindName(ownkind));
    2.24 +                owntype = types.createErrorType(found);
    2.25 +            } else if (allowPoly && inferenceContext.free(found)) {
    2.26 +                //delay the check if there are inference variables in the found type
    2.27 +                //this means we are dealing with a partially inferred poly expression
    2.28 +                owntype = resultInfo.pt;
    2.29                  inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() {
    2.30                      @Override
    2.31                      public void typesInferred(InferenceContext inferenceContext) {
    2.32                          ResultInfo pendingResult =
    2.33 -                                    resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
    2.34 +                                resultInfo.dup(inferenceContext.asInstType(resultInfo.pt));
    2.35                          check(tree, inferenceContext.asInstType(found), ownkind, pendingResult);
    2.36                      }
    2.37                  });
    2.38 -                return tree.type = resultInfo.pt;
    2.39              } else {
    2.40 -                if ((ownkind & ~resultInfo.pkind) == 0) {
    2.41 -                    owntype = resultInfo.check(tree, owntype);
    2.42 -                } else {
    2.43 -                    log.error(tree.pos(), "unexpected.type",
    2.44 -                            kindNames(resultInfo.pkind),
    2.45 -                            kindName(ownkind));
    2.46 -                    owntype = types.createErrorType(owntype);
    2.47 -                }
    2.48 +                owntype = resultInfo.check(tree, found);
    2.49              }
    2.50 +        } else {
    2.51 +            owntype = found;
    2.52          }
    2.53          tree.type = owntype;
    2.54          return owntype;
    2.55 @@ -2335,6 +2329,7 @@
    2.56                      currentTarget = infer.instantiateFunctionalInterface(that,
    2.57                              currentTarget, explicitParamTypes, resultInfo.checkContext);
    2.58                  }
    2.59 +                currentTarget = types.removeWildcards(currentTarget);
    2.60                  lambdaType = types.findDescriptorType(currentTarget);
    2.61              } else {
    2.62                  currentTarget = Type.recoveryType;
    2.63 @@ -2727,7 +2722,7 @@
    2.64                      resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK &&
    2.65                      isSerializable(currentTarget);
    2.66              if (currentTarget != Type.recoveryType) {
    2.67 -                currentTarget = targetChecker.visit(currentTarget, that);
    2.68 +                currentTarget = types.removeWildcards(targetChecker.visit(currentTarget, that));
    2.69                  desc = types.findDescriptorType(currentTarget);
    2.70              } else {
    2.71                  currentTarget = Type.recoveryType;
     3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Jul 17 10:55:50 2014 -0400
     3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Jun 20 20:36:54 2014 +0100
     3.3 @@ -531,8 +531,8 @@
     3.4  
     3.5      Type checkType(final DiagnosticPosition pos, final Type found, final Type req, final CheckContext checkContext) {
     3.6          final Infer.InferenceContext inferenceContext = checkContext.inferenceContext();
     3.7 -        if (inferenceContext.free(req)) {
     3.8 -            inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() {
     3.9 +        if (inferenceContext.free(req) || inferenceContext.free(found)) {
    3.10 +            inferenceContext.addFreeTypeListener(List.of(req, found), new FreeTypeListener() {
    3.11                  @Override
    3.12                  public void typesInferred(InferenceContext inferenceContext) {
    3.13                      checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext);
     4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Jul 17 10:55:50 2014 -0400
     4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri Jun 20 20:36:54 2014 +0100
     4.3 @@ -353,6 +353,7 @@
     4.4              Type to, Attr.ResultInfo resultInfo,
     4.5              InferenceContext inferenceContext) {
     4.6          inferenceContext.solve(List.of(from.qtype), new Warner());
     4.7 +        inferenceContext.notifyChange();
     4.8          Type capturedType = resultInfo.checkContext.inferenceContext()
     4.9                  .cachedCapture(tree, from.inst, false);
    4.10          if (types.isConvertible(capturedType,
    4.11 @@ -449,7 +450,7 @@
    4.12          class ImplicitArgType extends DeferredAttr.DeferredTypeMap {
    4.13  
    4.14              public ImplicitArgType(Symbol msym, Resolve.MethodResolutionPhase phase) {
    4.15 -                rs.deferredAttr.super(AttrMode.SPECULATIVE, msym, phase);
    4.16 +                (rs.deferredAttr).super(AttrMode.SPECULATIVE, msym, phase);
    4.17              }
    4.18  
    4.19              public Type apply(Type t) {
    4.20 @@ -517,6 +518,8 @@
    4.21                  //or if it's not a subtype of the original target, issue an error
    4.22                  checkContext.report(pos, diags.fragment("no.suitable.functional.intf.inst", funcInterface));
    4.23              }
    4.24 +            //propagate constraints as per JLS 18.2.1
    4.25 +            checkContext.compatible(owntype, funcInterface, types.noWarnings);
    4.26              return owntype;
    4.27          }
    4.28      }
     5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Jul 17 10:55:50 2014 -0400
     5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri Jun 20 20:36:54 2014 +0100
     5.3 @@ -957,9 +957,10 @@
     5.4          }
     5.5  
     5.6          public boolean compatible(Type found, Type req, Warner warn) {
     5.7 +            InferenceContext inferenceContext = deferredAttrContext.inferenceContext;
     5.8              return strict ?
     5.9 -                    types.isSubtypeUnchecked(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn) :
    5.10 -                    types.isConvertible(found, deferredAttrContext.inferenceContext.asUndetVar(req), warn);
    5.11 +                    types.isSubtypeUnchecked(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn) :
    5.12 +                    types.isConvertible(inferenceContext.asUndetVar(found), inferenceContext.asUndetVar(req), warn);
    5.13          }
    5.14  
    5.15          public void report(DiagnosticPosition pos, JCDiagnostic details) {
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/test/tools/javac/generics/inference/T8044546/CrashImplicitLambdaTest.java	Fri Jun 20 20:36:54 2014 +0100
     6.3 @@ -0,0 +1,41 @@
     6.4 +/*
     6.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.
    6.11 + *
    6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.15 + * version 2 for more details (a copy is included in the LICENSE file that
    6.16 + * accompanied this code).
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License version
    6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.21 + *
    6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    6.23 + * or visit www.oracle.com if you need additional information or have any
    6.24 + * questions.
    6.25 + */
    6.26 +
    6.27 +/**
    6.28 + * @test
    6.29 + * @bug 8044546
    6.30 + * @summary Crash on faulty reduce/lambda
    6.31 + * @compile CrashImplicitLambdaTest.java
    6.32 + */
    6.33 +
    6.34 +abstract class CrashImplicitLambdaTest {
    6.35 +    boolean foo() {
    6.36 +        return bar(true, a -> {});
    6.37 +    }
    6.38 +
    6.39 +    abstract <T1> T1 bar(T1 t1, S<T1> s);
    6.40 +
    6.41 +    interface S<S1> {
    6.42 +        void baz(S1 s1);
    6.43 +    }
    6.44 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/tools/javac/generics/inference/T8044546/NestedInvocationsTest.java	Fri Jun 20 20:36:54 2014 +0100
     7.3 @@ -0,0 +1,47 @@
     7.4 +/*
     7.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.7 + *
     7.8 + * This code is free software; you can redistribute it and/or modify it
     7.9 + * under the terms of the GNU General Public License version 2 only, as
    7.10 + * published by the Free Software Foundation.
    7.11 + *
    7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    7.15 + * version 2 for more details (a copy is included in the LICENSE file that
    7.16 + * accompanied this code).
    7.17 + *
    7.18 + * You should have received a copy of the GNU General Public License version
    7.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    7.21 + *
    7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    7.23 + * or visit www.oracle.com if you need additional information or have any
    7.24 + * questions.
    7.25 + */
    7.26 +
    7.27 +/**
    7.28 + * @test
    7.29 + * @bug 8044546
    7.30 + * @summary Crash on faulty reduce/lambda
    7.31 + * @compile NestedInvocationsTest.java
    7.32 + */
    7.33 +
    7.34 +class NestedInvocationsTest<T> {
    7.35 +    boolean foo(I<T> i) {
    7.36 +        return baz(zas(i));
    7.37 +    }
    7.38 +
    7.39 +    <U> J<U, Boolean> zas(I<U> i) {
    7.40 +        return null;
    7.41 +    }
    7.42 +
    7.43 +    <R> R baz(J<T, R> j) {
    7.44 +        return null;
    7.45 +    }
    7.46 +
    7.47 +    interface I<I1> {}
    7.48 +
    7.49 +    interface J<J1, J2> {}
    7.50 +}

mercurial