changeset 51204:46783b684636 condy-folding

several fixes, invokedynamic with dynamic args was generating bad code and more avoid issuing the same warning twice plus trust the user intention when defining a method handle regardless of what the symbols in the class path indicates
author vromero
date Tue, 26 Jun 2018 19:17:29 -0700
parents 0a0371f27986
children 952990c8f3c2
files src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstablesVisitor.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound2.java test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound2.out test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.out
diffstat 7 files changed, 50 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Thu Jun 21 09:19:29 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Jun 26 19:17:29 2018 -0700
@@ -1717,6 +1717,10 @@
             return false;
         }
 
+        public boolean isOwnerAnInterface() {
+            return (owner.flags_field & INTERFACE) != 0;
+        }
+
         /** find a symbol that this (proxy method) symbol implements.
          *  @param    c       The class whose members are searched for
          *                    implementations
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstablesVisitor.java	Thu Jun 21 09:19:29 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ConstablesVisitor.java	Tue Jun 26 19:17:29 2018 -0700
@@ -397,6 +397,7 @@
                     // we need to issue a warning if the type of the indy is not assignable to the type of the
                     // tree, same for condy
                     tree.type = mType.restype;
+                    tree.varargsElement = null;
                 }
             }
         }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu Jun 21 09:19:29 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Jun 26 19:17:29 2018 -0700
@@ -404,7 +404,7 @@
             if (value instanceof MethodSymbol) {
                 MethodSymbol m = (MethodSymbol)value;
                 if (!m.isDynamic()) {
-                    poolbuf.appendByte((m.owner.flags_field & INTERFACE) != 0
+                    poolbuf.appendByte(m.isOwnerAnInterface()
                               ? CONSTANT_InterfaceMethodref
                               : CONSTANT_Methodref);
                     poolbuf.appendChar(pool.put(m.owner));
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Thu Jun 21 09:19:29 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Tue Jun 26 19:17:29 2018 -0700
@@ -324,20 +324,20 @@
             String methodTypeDesc = (String)invokeMethodReflectively(methodTypeRefClass, mtConstant, "descriptorString");
             MethodType mType = (MethodType)descriptorToType(methodTypeDesc, currentModule, true);
             // this method generates fake symbols as needed
-            Symbol refSymbol = getReferenceSymbol(tree, refKind, ownerType.tsym, name, mType);
+            Pair<Symbol, Boolean> refSymbolPair = getReferenceSymbol(tree, refKind, ownerType.tsym, name, mType);
             boolean ownerFound = true;
             try {
-                refSymbol.owner.complete();
+                refSymbolPair.fst.owner.complete();
             } catch (CompletionFailure ex) {
-                log.warning(tree, Warnings.ClassNotFound(refSymbol.owner));
+                log.warning(tree, Warnings.ClassNotFound(refSymbolPair.fst.owner));
                 ownerFound = false;
             }
             if (ownerFound) {
-                ownerType = refSymbol.owner.type;
-                checkIfMemberExists(tree, attrEnv, names.fromString(name), ownerType, mType.argtypes, refKind);
+                ownerType = refSymbolPair.fst.owner.type;
+                checkIfMemberExists(tree, attrEnv, names.fromString(name), ownerType, mType.argtypes, refKind, refSymbolPair.snd);
             }
-            Pool.MethodHandle mHandle = new Pool.MethodHandle(refKind, refSymbol, types,
-                    new Pool.MethodHandle.DumbMethodHandleCheckHelper(refKind, refSymbol));
+            Pool.MethodHandle mHandle = new Pool.MethodHandle(refKind, refSymbolPair.fst, types,
+                    new Pool.MethodHandle.DumbMethodHandleCheckHelper(refKind, refSymbolPair.fst));
             return mHandle;
         } else if (methodTypeRefClass.isInstance(constant)) {
             String descriptor = (String)invokeMethodReflectively(methodTypeRefClass, constant, "descriptorString");
@@ -398,14 +398,17 @@
             }
         }
 
-        private void checkIfMemberExists(DiagnosticPosition pos, Env<AttrContext> attrEnv, Name name, Type qual, List<Type> args, int refKind) {
+        private void checkIfMemberExists(DiagnosticPosition pos, Env<AttrContext> attrEnv, Name name, Type qual, List<Type> args, int refKind, boolean warned) {
             Symbol refSym = resolveConstableMethod(pos, attrEnv, qual, name, args, List.nil());
             if (refSym.kind.isResolutionError()) {
                 try {
                     refSym = rs.resolveInternalField(pos, attrEnv, qual, name);
                 } catch (Throwable t) {
-                    log.warning(pos, Warnings.MemberNotFoundAtClass(name,
-                            (qual.tsym.flags_field & INTERFACE) == 0 ? "class" : "interface", qual.tsym));
+                    if (!warned) {
+                        // don't double warn
+                        log.warning(pos, Warnings.MemberNotFoundAtClass(name,
+                                (qual.tsym.flags_field & INTERFACE) == 0 ? "class" : "interface", qual.tsym));
+                    }
                     return;
                 }
             }
@@ -541,9 +544,9 @@
         return !error;
     }
 
-    private Symbol getReferenceSymbol(JCTree tree, int refKind, Symbol owner, String name, MethodType methodType) {
+    private Pair<Symbol, Boolean> getReferenceSymbol(JCTree tree, int refKind, Symbol owner, String name, MethodType methodType) {
         if (!checkMethodTypeShape(tree, refKind, methodType)) {
-            return syms.noSymbol;
+            return new Pair<>(syms.noSymbol, false);
         }
         long flags = refKind == ClassFile.REF_getStatic ||
                 refKind == ClassFile.REF_putStatic ||
@@ -560,68 +563,57 @@
                 if (refKind == ClassFile.REF_invokeInterface && (owner.flags_field & INTERFACE) == 0) {
                     Symbol result = generateMethodSymbolHelper(owner, symbolName, methodType, flags, true);
                     log.warning(tree, Warnings.MemberNotFoundAtClass(symbolName, "interface", result.owner));
-                    return result;
+                    return new Pair<>(result, true);
                 }
                 if (!canHaveInterfaceOwner && (owner.flags_field & INTERFACE) != 0) {
                     Symbol result = generateMethodSymbolHelper(owner, symbolName, methodType, flags, false);
                     log.warning(tree, Warnings.MemberNotFoundAtClass(symbolName, "class", result.owner));
-                    return result;
+                    return new Pair<>(result, true);
                 }
-                return new MethodSymbol(flags, symbolName, methodType, owner);
+                return new Pair<>(new MethodSymbol(flags, symbolName, methodType, owner), false);
             case ClassFile.REF_putField:
                 if ((owner.flags_field & INTERFACE) != 0) {
-                    Symbol result = generateVarSymbolHelper(owner, symbolName, methodType, flags, false);
+                    Symbol result = new VarSymbol(flags, symbolName, methodType.restype, owner);
                     log.warning(tree, Warnings.MemberNotFoundAtClass(symbolName, "class", result.owner));
-                    return result;
+                    return new Pair<>(result, true);
                 }
-                return new VarSymbol(flags, symbolName, methodType.argtypes.tail.head, owner);
+                return new Pair<>(new VarSymbol(flags, symbolName, methodType.argtypes.tail.head, owner), false);
             case ClassFile.REF_putStatic:
-                return new VarSymbol(flags, symbolName, methodType.argtypes.head, owner);
+                return new Pair<>(new VarSymbol(flags, symbolName, methodType.argtypes.head, owner), false);
             case ClassFile.REF_getField:
             case ClassFile.REF_getStatic:
                 if (refKind == ClassFile.REF_getField && (owner.flags_field & INTERFACE) != 0) {
-                    Symbol result = generateVarSymbolHelper(owner, symbolName, methodType, flags, false);
+                    Symbol result = new VarSymbol(flags, symbolName, methodType.restype, owner);
                     log.warning(tree, Warnings.MemberNotFoundAtClass(symbolName, "class", result.owner));
-                    return result;
+                    return new Pair<>(result, true);
                 }
-                return new VarSymbol(flags, symbolName, methodType.restype, owner);
+                return new Pair<>(new VarSymbol(flags, symbolName, methodType.restype, owner), false);
             default:
                 throw new AssertionError("invalid refKind value " + refKind);
         }
     }
 
     private Symbol generateMethodSymbolHelper(
-            Symbol currentOwner,
+            Symbol owner,
             Name symbolName,
             MethodType methodType,
             long flags,
-            boolean shouldBeInterface) {
-        ClassSymbol newOwner = createNewOwner(currentOwner, shouldBeInterface);
-        Symbol newMS = new MethodSymbol(flags, symbolName, methodType, newOwner);
-        newOwner.members_field.enter(newMS);
+            final boolean shouldBeInterface) {
+        Symbol newMS = new MethodSymbol(flags, symbolName, methodType, owner) {
+            @Override
+            public boolean isOwnerAnInterface() {
+                return shouldBeInterface;
+            }
+        };
         return newMS;
     }
 
-    private ClassSymbol createNewOwner(Symbol currentOwner,
-            boolean shouldBeInterface) {
-        long newFlags = shouldBeInterface ?
-                currentOwner.flags_field | Flags.INTERFACE :
-                currentOwner.flags_field & ~Flags.INTERFACE;
-        ClassSymbol newOwner = new ClassSymbol(newFlags,
-                currentOwner.name, currentOwner.owner);
-        newOwner.members_field = WriteableScope.create(newOwner);
-        return newOwner;
-    }
-
     private Symbol generateVarSymbolHelper(
-            Symbol currentOwner,
+            Symbol owner,
             Name symbolName,
             MethodType methodType,
-            long flags,
-            boolean shouldBeInterface) {
-        ClassSymbol newOwner = createNewOwner(currentOwner, shouldBeInterface);
-        Symbol newVS = new VarSymbol(flags, symbolName, methodType.restype, newOwner);
-        newOwner.members_field.enter(newVS);
+            long flags) {
+        Symbol newVS = new VarSymbol(flags, symbolName, methodType.restype, owner);
         return newVS;
     }
 
--- a/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound2.java	Thu Jun 21 09:19:29 2018 -0700
+++ b/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound2.java	Tue Jun 26 19:17:29 2018 -0700
@@ -10,9 +10,12 @@
 public class WarningIfClassOrMemberNotFound2 {
     private static final ClassDesc THIS = ClassDesc.of("WarningIfClassOrMemberNotFound2");
     public int m(int i) { return i; }
+    public int f(int i) { return i; }
 
     public void test() {
         MethodHandleDesc negIMethodRef = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, THIS, "m", MethodTypeDesc.ofDescriptor("(I)I"));
         Intrinsics.ldc(negIMethodRef);
+        MethodHandleDesc negIMethodRef2 = MethodHandleDesc.of(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, THIS, "f", MethodTypeDesc.ofDescriptor("(I)I"));
+        Intrinsics.ldc(negIMethodRef2);
     }
 }
--- a/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound2.out	Thu Jun 21 09:19:29 2018 -0700
+++ b/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound2.out	Tue Jun 26 19:17:29 2018 -0700
@@ -1,4 +1,5 @@
-WarningIfClassOrMemberNotFound2.java:16:23: compiler.warn.member.not.found.at.class: m, interface, WarningIfClassOrMemberNotFound2
+WarningIfClassOrMemberNotFound2.java:17:23: compiler.warn.member.not.found.at.class: m, interface, WarningIfClassOrMemberNotFound2
+WarningIfClassOrMemberNotFound2.java:19:23: compiler.warn.member.not.found.at.class: f, interface, WarningIfClassOrMemberNotFound2
 - compiler.err.warnings.and.werror
 1 error
-1 warning
+2 warnings
--- a/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.out	Thu Jun 21 09:19:29 2018 -0700
+++ b/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.out	Tue Jun 26 19:17:29 2018 -0700
@@ -3,6 +3,7 @@
 WarningIfMemberIncorrect.java:22:31: compiler.warn.unexpected.kind.for.symbol: bar, MTH, VAR
 WarningIfMemberIncorrect.java:25:41: compiler.warn.incorrect.name.for.method: WarningIfMemberIncorrect(), 5
 WarningIfMemberIncorrect.java:28:31: compiler.warn.member.not.found.at.class: foo, class, WarningIfMemberIncorrect.I
+WarningIfMemberIncorrect.java:28:31: compiler.warn.non.interface.owner.expected.for.symbol: foo()
 - compiler.err.warnings.and.werror
 1 error
-5 warnings
+6 warnings