Fri, 24 May 2013 15:27:12 +0100
8014649: Regression: bug in Resolve.resolveOperator
Summary: Missing curly braces causes Resolve.findMethod to be called spuriously
Reviewed-by: jjg, vromero
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri May 24 15:26:57 2013 +0100 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri May 24 15:27:12 2013 +0100 1.3 @@ -1343,7 +1343,7 @@ 1.4 try { 1.5 Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes, 1.6 allowBoxing, useVarargs, types.noWarnings); 1.7 - if (!operator) 1.8 + if (!operator || verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) 1.9 currentResolutionContext.addApplicableCandidate(sym, mt); 1.10 } catch (InapplicableMethodException ex) { 1.11 if (!operator) 1.12 @@ -2500,17 +2500,21 @@ 1.13 try { 1.14 currentResolutionContext = new MethodResolutionContext(); 1.15 Name name = treeinfo.operatorName(optag); 1.16 - env.info.pendingResolutionPhase = currentResolutionContext.step = BASIC; 1.17 - Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.18 - null, false, false, true); 1.19 - if (boxingEnabled && sym.kind >= WRONG_MTHS) 1.20 - env.info.pendingResolutionPhase = currentResolutionContext.step = BOX; 1.21 - sym = findMethod(env, syms.predefClass.type, name, argtypes, 1.22 - null, true, false, true); 1.23 - return accessMethod(sym, pos, env.enclClass.sym.type, name, 1.24 + return lookupMethod(env, pos, syms.predefClass, currentResolutionContext, 1.25 + new BasicLookupHelper(name, syms.predefClass.type, argtypes, null, BOX) { 1.26 + @Override 1.27 + Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { 1.28 + return findMethod(env, site, name, argtypes, typeargtypes, 1.29 + phase.isBoxingRequired(), 1.30 + phase.isVarargsRequired(), true); 1.31 + } 1.32 + @Override 1.33 + Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) { 1.34 + return accessMethod(sym, pos, env.enclClass.sym.type, name, 1.35 false, argtypes, null); 1.36 - } 1.37 - finally { 1.38 + } 1.39 + }); 1.40 + } finally { 1.41 currentResolutionContext = prevResolutionContext; 1.42 } 1.43 } 1.44 @@ -2673,7 +2677,11 @@ 1.45 abstract class BasicLookupHelper extends LookupHelper { 1.46 1.47 BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes) { 1.48 - super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY); 1.49 + this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY); 1.50 + } 1.51 + 1.52 + BasicLookupHelper(Name name, Type site, List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) { 1.53 + super(name, site, argtypes, typeargtypes, maxPhase); 1.54 } 1.55 1.56 @Override
2.1 --- a/test/tools/javac/resolve/ResolveHarness.java Fri May 24 15:26:57 2013 +0100 2.2 +++ b/test/tools/javac/resolve/ResolveHarness.java Fri May 24 15:27:12 2013 +0100 2.3 @@ -43,6 +43,7 @@ 2.4 import java.util.HashMap; 2.5 import java.util.HashSet; 2.6 import java.util.List; 2.7 +import java.util.Locale; 2.8 import java.util.Map; 2.9 2.10 import javax.annotation.processing.AbstractProcessor; 2.11 @@ -85,6 +86,7 @@ 2.12 Set<String> declaredKeys = new HashSet<>(); 2.13 List<Diagnostic<? extends JavaFileObject>> diags = new ArrayList<>(); 2.14 List<ElementKey> seenCandidates = new ArrayList<>(); 2.15 + Map<String, String> predefTranslationMap = new HashMap<>(); 2.16 2.17 protected ResolveHarness(JavaFileObject jfo) { 2.18 this.jfo = jfo; 2.19 @@ -93,12 +95,36 @@ 2.20 new VerboseDeferredInferenceNoteProcessor(), 2.21 new ErrorProcessor() 2.22 }; 2.23 + predefTranslationMap.put("+", "_plus"); 2.24 + predefTranslationMap.put("-", "_minus"); 2.25 + predefTranslationMap.put("~", "_not"); 2.26 + predefTranslationMap.put("++", "_plusplus"); 2.27 + predefTranslationMap.put("--", "_minusminus"); 2.28 + predefTranslationMap.put("!", "_bang"); 2.29 + predefTranslationMap.put("*", "_mul"); 2.30 + predefTranslationMap.put("/", "_div"); 2.31 + predefTranslationMap.put("%", "_mod"); 2.32 + predefTranslationMap.put("&", "_and"); 2.33 + predefTranslationMap.put("|", "_or"); 2.34 + predefTranslationMap.put("^", "_xor"); 2.35 + predefTranslationMap.put("<<", "_lshift"); 2.36 + predefTranslationMap.put(">>", "_rshift"); 2.37 + predefTranslationMap.put("<<<", "_lshiftshift"); 2.38 + predefTranslationMap.put(">>>", "_rshiftshift"); 2.39 + predefTranslationMap.put("<", "_lt"); 2.40 + predefTranslationMap.put(">", "_gt"); 2.41 + predefTranslationMap.put("<=", "_lteq"); 2.42 + predefTranslationMap.put(">=", "_gteq"); 2.43 + predefTranslationMap.put("==", "_eq"); 2.44 + predefTranslationMap.put("!=", "_neq"); 2.45 + predefTranslationMap.put("&&", "_andand"); 2.46 + predefTranslationMap.put("||", "_oror"); 2.47 } 2.48 2.49 protected void check() throws Exception { 2.50 String[] options = { 2.51 "-XDshouldStopPolicy=ATTR", 2.52 - "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference" 2.53 + "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference,predef" 2.54 }; 2.55 2.56 AbstractProcessor[] processors = { new ResolveCandidateFinder(), null }; 2.57 @@ -223,7 +249,8 @@ 2.58 @Override 2.59 void process(Diagnostic<? extends JavaFileObject> diagnostic) { 2.60 Element siteSym = getSiteSym(diagnostic); 2.61 - if (siteSym.getAnnotation(TraceResolve.class) == null) { 2.62 + if (siteSym.getSimpleName().length() != 0 && 2.63 + siteSym.getAnnotation(TraceResolve.class) == null) { 2.64 return; 2.65 } 2.66 int candidateIdx = 0; 2.67 @@ -307,7 +334,7 @@ 2.68 2.69 if (Arrays.asList(c.applicable()).contains(phase)) { //applicable 2.70 if (c.mostSpecific() != mostSpecific) { 2.71 - error("Invalid most specific value for method " + methodSym); 2.72 + error("Invalid most specific value for method " + methodSym + " " + new ElementKey(methodSym).key); 2.73 } 2.74 MethodType mtype = getSig(diagnostic); 2.75 if (mtype != null) { 2.76 @@ -444,11 +471,21 @@ 2.77 2.78 String computeKey(Element e) { 2.79 StringBuilder buf = new StringBuilder(); 2.80 - while (e != null) { 2.81 + if (predefTranslationMap.containsKey(e.getSimpleName().toString())) { 2.82 + //predef element 2.83 + buf.append("<predef>."); 2.84 + String replacedName = predefTranslationMap.get(e.getSimpleName().toString()); 2.85 + buf.append(e.toString().replace(e.getSimpleName().toString(), replacedName)); 2.86 + } else if (e.getSimpleName().toString().startsWith("_")) { 2.87 + buf.append("<predef>."); 2.88 buf.append(e.toString()); 2.89 - e = e.getEnclosingElement(); 2.90 + } else { 2.91 + while (e != null) { 2.92 + buf.append(e.toString()); 2.93 + e = e.getEnclosingElement(); 2.94 + } 2.95 + buf.append(jfo.getName()); 2.96 } 2.97 - buf.append(jfo.getName()); 2.98 return buf.toString(); 2.99 } 2.100
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java Fri May 24 15:27:12 2013 +0100 3.3 @@ -0,0 +1,71 @@ 3.4 +/* 3.5 + * Copyright (c) 2013, 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. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +@TraceResolve 3.28 +class PrimitiveBinopOverload { 3.29 + 3.30 + @Candidate(applicable=Phase.BASIC, mostSpecific=true) 3.31 + int _plus(int x, int y) { return -1; } 3.32 + @Candidate(applicable=Phase.BASIC) 3.33 + long _plus(long x, long y) { return -1; } 3.34 + @Candidate(applicable=Phase.BASIC) 3.35 + float _plus(float x, float y) { return -1; } 3.36 + @Candidate(applicable=Phase.BASIC) 3.37 + double _plus(double x, double y) { return -1; } 3.38 + //not a candidate 3.39 + Object _plus(Object x, Object y) { return -1; } 3.40 + 3.41 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true) 3.42 + int _minus(int x, int y) { return -1; } 3.43 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.44 + long _minus(long x, long y) { return -1; } 3.45 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.46 + float _minus(float x, float y) { return -1; } 3.47 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.48 + double _minus(double x, double y) { return -1; } 3.49 + 3.50 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true) 3.51 + int _mul(int x, int y) { return -1; } 3.52 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.53 + long _mul(long x, long y) { return -1; } 3.54 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.55 + float _mul(float x, float y) { return -1; } 3.56 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.57 + double _mul(double x, double y) { return -1; } 3.58 + 3.59 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true) 3.60 + int _div(int x, int y) { return -1; } 3.61 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.62 + long _div(long x, long y) { return -1; } 3.63 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.64 + float _div(float x, float y) { return -1; } 3.65 + @Candidate(applicable= { Phase.BASIC, Phase.BOX }) 3.66 + double _div(double x, double y) { return -1; } 3.67 + 3.68 + { 3.69 + int i1 = 1 + 1; 3.70 + int i2 = 5 - new Integer(3); 3.71 + int i3 = new Integer(5) * 3; 3.72 + int i4 = new Integer(6) / new Integer(2); 3.73 + } 3.74 +}