8014649: Regression: bug in Resolve.resolveOperator
Summary: Missing curly braces causes Resolve.findMethod to be called spuriously
Reviewed-by: jjg, vromero
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri May 24 15:26:57 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri May 24 15:27:12 2013 +0100
@@ -1343,7 +1343,7 @@
try {
Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
allowBoxing, useVarargs, types.noWarnings);
- if (!operator)
+ if (!operator || verboseResolutionMode.contains(VerboseResolutionMode.PREDEF))
currentResolutionContext.addApplicableCandidate(sym, mt);
} catch (InapplicableMethodException ex) {
if (!operator)
@@ -2500,17 +2500,21 @@
try {
currentResolutionContext = new MethodResolutionContext();
Name name = treeinfo.operatorName(optag);
- env.info.pendingResolutionPhase = currentResolutionContext.step = BASIC;
- Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
- null, false, false, true);
- if (boxingEnabled && sym.kind >= WRONG_MTHS)
- env.info.pendingResolutionPhase = currentResolutionContext.step = BOX;
- sym = findMethod(env, syms.predefClass.type, name, argtypes,
- null, true, false, true);
- return accessMethod(sym, pos, env.enclClass.sym.type, name,
+ return lookupMethod(env, pos, syms.predefClass, currentResolutionContext,
+ new BasicLookupHelper(name, syms.predefClass.type, argtypes, null, BOX) {
+ @Override
+ Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
+ return findMethod(env, site, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired(), true);
+ }
+ @Override
+ Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ return accessMethod(sym, pos, env.enclClass.sym.type, name,
false, argtypes, null);
- }
- finally {
+ }
+ });
+ } finally {
currentResolutionContext = prevResolutionContext;
}
}
@@ -2673,7 +2677,11 @@
abstract class BasicLookupHelper extends LookupHelper {
BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) {
- super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
+ this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
+ }
+
+ BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
+ super(name, site, argtypes, typeargtypes, maxPhase);
}
@Override
--- a/langtools/test/tools/javac/resolve/ResolveHarness.java Fri May 24 15:26:57 2013 +0100
+++ b/langtools/test/tools/javac/resolve/ResolveHarness.java Fri May 24 15:27:12 2013 +0100
@@ -43,6 +43,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import javax.annotation.processing.AbstractProcessor;
@@ -85,6 +86,7 @@
Set<String> declaredKeys = new HashSet<>();
List<Diagnostic<? extends JavaFileObject>> diags = new ArrayList<>();
List<ElementKey> seenCandidates = new ArrayList<>();
+ Map<String, String> predefTranslationMap = new HashMap<>();
protected ResolveHarness(JavaFileObject jfo) {
this.jfo = jfo;
@@ -93,12 +95,36 @@
new VerboseDeferredInferenceNoteProcessor(),
new ErrorProcessor()
};
+ predefTranslationMap.put("+", "_plus");
+ predefTranslationMap.put("-", "_minus");
+ predefTranslationMap.put("~", "_not");
+ predefTranslationMap.put("++", "_plusplus");
+ predefTranslationMap.put("--", "_minusminus");
+ predefTranslationMap.put("!", "_bang");
+ predefTranslationMap.put("*", "_mul");
+ predefTranslationMap.put("/", "_div");
+ predefTranslationMap.put("%", "_mod");
+ predefTranslationMap.put("&", "_and");
+ predefTranslationMap.put("|", "_or");
+ predefTranslationMap.put("^", "_xor");
+ predefTranslationMap.put("<<", "_lshift");
+ predefTranslationMap.put(">>", "_rshift");
+ predefTranslationMap.put("<<<", "_lshiftshift");
+ predefTranslationMap.put(">>>", "_rshiftshift");
+ predefTranslationMap.put("<", "_lt");
+ predefTranslationMap.put(">", "_gt");
+ predefTranslationMap.put("<=", "_lteq");
+ predefTranslationMap.put(">=", "_gteq");
+ predefTranslationMap.put("==", "_eq");
+ predefTranslationMap.put("!=", "_neq");
+ predefTranslationMap.put("&&", "_andand");
+ predefTranslationMap.put("||", "_oror");
}
protected void check() throws Exception {
String[] options = {
"-XDshouldStopPolicy=ATTR",
- "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference"
+ "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference,predef"
};
AbstractProcessor[] processors = { new ResolveCandidateFinder(), null };
@@ -223,7 +249,8 @@
@Override
void process(Diagnostic<? extends JavaFileObject> diagnostic) {
Element siteSym = getSiteSym(diagnostic);
- if (siteSym.getAnnotation(TraceResolve.class) == null) {
+ if (siteSym.getSimpleName().length() != 0 &&
+ siteSym.getAnnotation(TraceResolve.class) == null) {
return;
}
int candidateIdx = 0;
@@ -307,7 +334,7 @@
if (Arrays.asList(c.applicable()).contains(phase)) { //applicable
if (c.mostSpecific() != mostSpecific) {
- error("Invalid most specific value for method " + methodSym);
+ error("Invalid most specific value for method " + methodSym + " " + new ElementKey(methodSym).key);
}
MethodType mtype = getSig(diagnostic);
if (mtype != null) {
@@ -444,11 +471,21 @@
String computeKey(Element e) {
StringBuilder buf = new StringBuilder();
- while (e != null) {
+ if (predefTranslationMap.containsKey(e.getSimpleName().toString())) {
+ //predef element
+ buf.append("<predef>.");
+ String replacedName = predefTranslationMap.get(e.getSimpleName().toString());
+ buf.append(e.toString().replace(e.getSimpleName().toString(), replacedName));
+ } else if (e.getSimpleName().toString().startsWith("_")) {
+ buf.append("<predef>.");
buf.append(e.toString());
- e = e.getEnclosingElement();
+ } else {
+ while (e != null) {
+ buf.append(e.toString());
+ e = e.getEnclosingElement();
+ }
+ buf.append(jfo.getName());
}
- buf.append(jfo.getName());
return buf.toString();
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java Fri May 24 15:27:12 2013 +0100
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+@TraceResolve
+class PrimitiveBinopOverload {
+
+ @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+ int _plus(int x, int y) { return -1; }
+ @Candidate(applicable=Phase.BASIC)
+ long _plus(long x, long y) { return -1; }
+ @Candidate(applicable=Phase.BASIC)
+ float _plus(float x, float y) { return -1; }
+ @Candidate(applicable=Phase.BASIC)
+ double _plus(double x, double y) { return -1; }
+ //not a candidate
+ Object _plus(Object x, Object y) { return -1; }
+
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
+ int _minus(int x, int y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ long _minus(long x, long y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ float _minus(float x, float y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ double _minus(double x, double y) { return -1; }
+
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
+ int _mul(int x, int y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ long _mul(long x, long y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ float _mul(float x, float y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ double _mul(double x, double y) { return -1; }
+
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
+ int _div(int x, int y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ long _div(long x, long y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ float _div(float x, float y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ double _div(double x, double y) { return -1; }
+
+ {
+ int i1 = 1 + 1;
+ int i2 = 5 - new Integer(3);
+ int i3 = new Integer(5) * 3;
+ int i4 = new Integer(6) / new Integer(2);
+ }
+}