From f05c82363e3363ce256242fa8923224d79fb7711 Mon Sep 17 00:00:00 2001 From: mcimadamore Date: Thu, 25 Jul 2013 14:51:40 +0100 Subject: [PATCH] 8020843: javac crashes on accessibility check with method reference with typevar receiver Summary: method reference overload check doesn't walk through type-variable receivers Reviewed-by: jjg --- .../com/sun/tools/javac/comp/Resolve.java | 66 ++++++++++++++----- .../tools/javac/resources/compiler.properties | 4 ++ .../diags/examples/ReportAccessFragment.java | 32 +++++++++ .../tools/javac/lambda/8020843/T8020843a.java | 16 +++++ test/tools/javac/lambda/8020843/T8020843a.out | 2 + .../tools/javac/lambda/8020843/T8020843b.java | 27 ++++++++ test/tools/javac/lambda/8020843/T8020843b.out | 3 + test/tools/javac/lambda/MethodReference28.out | 2 +- 8 files changed, 136 insertions(+), 16 deletions(-) create mode 100644 test/tools/javac/diags/examples/ReportAccessFragment.java create mode 100644 test/tools/javac/lambda/8020843/T8020843a.java create mode 100644 test/tools/javac/lambda/8020843/T8020843a.out create mode 100644 test/tools/javac/lambda/8020843/T8020843b.java create mode 100644 test/tools/javac/lambda/8020843/T8020843b.out diff --git a/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/share/classes/com/sun/tools/javac/comp/Resolve.java index ff4d048f..897cf210 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -2649,6 +2649,13 @@ public class Resolve { InferenceContext inferenceContext) { MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC; + if (site.hasTag(TYPEVAR)) { + return resolveMemberReference(pos, env, referenceTree, site.getUpperBound(), + name, argtypes, typeargtypes, boxingAllowed, methodCheck, inferenceContext); + } + + site = types.capture(site); + ReferenceLookupHelper boundLookupHelper; if (!name.equals(names.init)) { //method reference @@ -2675,24 +2682,52 @@ public class Resolve { //merge results Pair res; - if (!lookupSuccess(unboundSym)) { - res = new Pair(boundSym, boundLookupHelper); - env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase; - } else if (lookupSuccess(boundSym)) { - res = new Pair(ambiguityError(boundSym, unboundSym), boundLookupHelper); - env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase; - } else { - res = new Pair(unboundSym, unboundLookupHelper); - env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase; - } + Symbol bestSym = choose(boundSym, unboundSym); + res = new Pair(bestSym, + bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper); + env.info.pendingResolutionPhase = bestSym == unboundSym ? + unboundEnv.info.pendingResolutionPhase : + boundEnv.info.pendingResolutionPhase; return res; } - //private - boolean lookupSuccess(Symbol s) { + //where + private Symbol choose(Symbol s1, Symbol s2) { + if (lookupSuccess(s1) && lookupSuccess(s2)) { + return ambiguityError(s1, s2); + } else if (lookupSuccess(s1) || + (canIgnore(s2) && !canIgnore(s1))) { + return s1; + } else if (lookupSuccess(s2) || + (canIgnore(s1) && !canIgnore(s2))) { + return s2; + } else { + return s1; + } + } + + private boolean lookupSuccess(Symbol s) { return s.kind == MTH || s.kind == AMBIGUOUS; } + private boolean canIgnore(Symbol s) { + switch (s.kind) { + case ABSENT_MTH: + return true; + case WRONG_MTH: + InapplicableSymbolError errSym = + (InapplicableSymbolError)s; + return new Template(MethodCheckDiag.ARITY_MISMATCH.regex()) + .matches(errSym.errCandidate().snd); + case WRONG_MTHS: + InapplicableSymbolsError errSyms = + (InapplicableSymbolsError)s; + return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty(); + default: + return false; + } + } + /** * Helper for defining custom method-like lookup logic; a lookup helper * provides hooks for (i) the actual lookup logic and (ii) accessing the @@ -3504,7 +3539,9 @@ public class Resolve { List argtypes, List typeargtypes) { Map candidatesMap = mapCandidates(); - Map filteredCandidates = filterCandidates(candidatesMap); + Map filteredCandidates = compactMethodDiags ? + filterCandidates(candidatesMap) : + mapCandidates(); if (filteredCandidates.isEmpty()) { filteredCandidates = candidatesMap; } @@ -3556,8 +3593,7 @@ public class Resolve { Map candidates = new LinkedHashMap(); for (Map.Entry _entry : candidatesMap.entrySet()) { JCDiagnostic d = _entry.getValue(); - if (!compactMethodDiags || - !new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) { + if (!new Template(MethodCheckDiag.ARITY_MISMATCH.regex()).matches(d)) { candidates.put(_entry.getKey(), d); } } diff --git a/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/share/classes/com/sun/tools/javac/resources/compiler.properties index 40f94c9a..2017a637 100644 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -905,6 +905,10 @@ compiler.err.repeated.modifier=\ compiler.err.report.access=\ {0} has {1} access in {2} +# 0: symbol, 1: set of modifier, 2: symbol +compiler.misc.report.access=\ + {0} has {1} access in {2} + compiler.err.ret.outside.meth=\ return outside method diff --git a/test/tools/javac/diags/examples/ReportAccessFragment.java b/test/tools/javac/diags/examples/ReportAccessFragment.java new file mode 100644 index 00000000..8acba1d6 --- /dev/null +++ b/test/tools/javac/diags/examples/ReportAccessFragment.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.prob.found.req +// key: compiler.misc.invalid.mref +// key: compiler.misc.report.access + +class ReportAccessFragment { + void test(Object o) { + Runnable r = o::clone; + } +} diff --git a/test/tools/javac/lambda/8020843/T8020843a.java b/test/tools/javac/lambda/8020843/T8020843a.java new file mode 100644 index 00000000..1b3e890b --- /dev/null +++ b/test/tools/javac/lambda/8020843/T8020843a.java @@ -0,0 +1,16 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8020843 + * @summary javac crashes on accessibility check with method reference with typevar receiver + * @compile/fail/ref=T8020843a.out -XDrawDiagnostics T8020843a.java + */ + +class T8020843a { + interface Function { + Y m(X x); + } + + void test(T t) { + Function ss = T::clone; + } +} diff --git a/test/tools/javac/lambda/8020843/T8020843a.out b/test/tools/javac/lambda/8020843/T8020843a.out new file mode 100644 index 00000000..8b89eee3 --- /dev/null +++ b/test/tools/javac/lambda/8020843/T8020843a.out @@ -0,0 +1,2 @@ +T8020843a.java:14:34: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.report.access: clone(), protected, java.lang.Object)) +1 error diff --git a/test/tools/javac/lambda/8020843/T8020843b.java b/test/tools/javac/lambda/8020843/T8020843b.java new file mode 100644 index 00000000..727b2cde --- /dev/null +++ b/test/tools/javac/lambda/8020843/T8020843b.java @@ -0,0 +1,27 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8020843 + * @summary javac crashes on accessibility check with method reference with typevar receiver + * @compile/fail/ref=T8020843b.out -XDrawDiagnostics T8020843b.java + */ + +class T8020843b { + interface Function { + Y m(X x); + } + + interface BiFunction { + Z m(X x, Y y); + } + + Object m(int i) { return null; } + static Object m(String t) { return null; } + + Object m2(int i) { return null; } + static Object m2(long t) { return null; } + + static void test() { + Function f1 = T8020843b::m; //show bound case diag + BiFunction f2 = T8020843b::m2; //show unbound case diag + } +} diff --git a/test/tools/javac/lambda/8020843/T8020843b.out b/test/tools/javac/lambda/8020843/T8020843b.out new file mode 100644 index 00000000..41b38c80 --- /dev/null +++ b/test/tools/javac/lambda/8020843/T8020843b.out @@ -0,0 +1,3 @@ +T8020843b.java:24:42: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m, T8020843b,{(compiler.misc.inapplicable.method: kindname.method, T8020843b, m(int), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: T8020843b, int))),(compiler.misc.inapplicable.method: kindname.method, T8020843b, m(java.lang.String), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: T8020843b, java.lang.String)))})) +T8020843b.java:25:52: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m2, T8020843b,java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, T8020843b, m2(int), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, int))),(compiler.misc.inapplicable.method: kindname.method, T8020843b, m2(long), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, long)))})) +2 errors diff --git a/test/tools/javac/lambda/MethodReference28.out b/test/tools/javac/lambda/MethodReference28.out index 123cb517..042ade19 100644 --- a/test/tools/javac/lambda/MethodReference28.out +++ b/test/tools/javac/lambda/MethodReference28.out @@ -9,6 +9,6 @@ MethodReference28.java:45:19: compiler.err.prob.found.req: (compiler.misc.invali MethodReference28.java:46:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))) MethodReference28.java:47:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m4, java.lang.String[], int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: int, java.lang.String)))) MethodReference28.java:52:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m2, java.lang.Integer,java.lang.Integer, MethodReference28,int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: MethodReference28, java.lang.Integer)))) -MethodReference28.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, MethodReference28,int, kindname.class, MethodReference28, (compiler.misc.arg.length.mismatch))) +MethodReference28.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m3, java.lang.String, MethodReference28,int, kindname.class, MethodReference28, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: int, java.lang.String)))) MethodReference28.java:54:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, m4, java.lang.String[], MethodReference28,int, kindname.class, MethodReference28, (compiler.misc.varargs.argument.mismatch: (compiler.misc.inconvertible.types: MethodReference28, java.lang.String)))) 13 errors -- GitLab