8014649: Regression: bug in Resolve.resolveOperator
authormcimadamore
Fri, 24 May 2013 15:27:12 +0100
changeset 17804 6bed8a263318
parent 17803 d73ddda4575f
child 17805 b87d5c2f1df8
8014649: Regression: bug in Resolve.resolveOperator Summary: Missing curly braces causes Resolve.findMethod to be called spuriously Reviewed-by: jjg, vromero
langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
langtools/test/tools/javac/resolve/ResolveHarness.java
langtools/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java
--- 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);
+    }
+}