8067886: Inaccessible nested classes can be incorrectly imported
authorjlahoda
Tue, 24 Feb 2015 16:11:59 +0100
changeset 29149 3fa94aad0264
parent 29148 57ca99b88ddb
child 29150 ef280223e694
8067886: Inaccessible nested classes can be incorrectly imported Summary: Check type accessibility at the point of import when importing the type using type-import-on-demand. Reviewed-by: mcimadamore, jfranck
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java
langtools/test/tools/javac/importscope/ImportInaccessible.java
langtools/test/tools/javac/importscope/ImportInaccessible.out
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java	Mon Feb 23 11:42:16 2015 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java	Tue Feb 24 16:11:59 2015 +0100
@@ -798,6 +798,10 @@
             prependSubScope(new FilterImportScope(types, origin, null, filter, staticImport));
         }
 
+        public boolean isFilled() {
+            return subScopes.nonEmpty();
+        }
+
     }
 
     public interface ImportFilter {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Mon Feb 23 11:42:16 2015 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Tue Feb 24 16:11:59 2015 +0100
@@ -3528,7 +3528,7 @@
 
         for (Symbol sym : tsym.members().getSymbolsByName(name)) {
             if (sym.isStatic() &&
-                staticImportAccessible(sym, packge) &&
+                importAccessible(sym, packge) &&
                 sym.isMemberOf(origin, types)) {
                 return true;
             }
@@ -3538,17 +3538,23 @@
     }
 
     // is the sym accessible everywhere in packge?
-    public boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
-        int flags = (int)(sym.flags() & AccessFlags);
-        switch (flags) {
-        default:
-        case PUBLIC:
-            return true;
-        case PRIVATE:
+    public boolean importAccessible(Symbol sym, PackageSymbol packge) {
+        try {
+            int flags = (int)(sym.flags() & AccessFlags);
+            switch (flags) {
+            default:
+            case PUBLIC:
+                return true;
+            case PRIVATE:
+                return false;
+            case 0:
+            case PROTECTED:
+                return sym.packge() == packge;
+            }
+        } catch (ClassFinder.BadClassFile err) {
+            throw err;
+        } catch (CompletionFailure ex) {
             return false;
-        case 0:
-        case PROTECTED:
-            return sym.packge() == packge;
         }
     }
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Feb 23 11:42:16 2015 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Feb 24 16:11:59 2015 +0100
@@ -1667,7 +1667,7 @@
          * This class is used to store important information regarding translation of
          * lambda expression/method references (see subclasses).
          */
-        private abstract class TranslationContext<T extends JCFunctionalExpression> {
+        abstract class TranslationContext<T extends JCFunctionalExpression> {
 
             /** the underlying (untranslated) tree */
             final T tree;
@@ -1746,7 +1746,7 @@
          * and the used by the main translation routines in order to adjust references
          * to captured locals/members, etc.
          */
-        private class LambdaTranslationContext extends TranslationContext<JCLambda> {
+        class LambdaTranslationContext extends TranslationContext<JCLambda> {
 
             /** variable in the enclosing context to which this lambda is assigned */
             final Symbol self;
@@ -2040,7 +2040,7 @@
          * and the used by the main translation routines in order to adjust method
          * references (i.e. in case a bridge is needed)
          */
-        private final class ReferenceTranslationContext extends TranslationContext<JCMemberReference> {
+        final class ReferenceTranslationContext extends TranslationContext<JCMemberReference> {
 
             final boolean isSuper;
             final Symbol sigPolySym;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Mon Feb 23 11:42:16 2015 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Tue Feb 24 16:11:59 2015 +0100
@@ -160,7 +160,7 @@
         // if there remain any unimported toplevels (these must have
         // no classes at all), process their import statements as well.
         for (JCCompilationUnit tree : trees) {
-            if (tree.starImportScope.isEmpty()) {
+            if (!tree.starImportScope.isFilled()) {
                 Env<AttrContext> topEnv = enter.topLevelEnv(tree);
                 finishImports(tree, () -> { completeClass.resolveImports(tree, topEnv); });
             }
@@ -280,12 +280,7 @@
 
         Env<AttrContext> env;
         ImportFilter staticImportFilter;
-        ImportFilter typeImportFilter = new ImportFilter() {
-            @Override
-            public boolean accepts(Scope origin, Symbol t) {
-                return t.kind == TYP;
-            }
-        };
+        ImportFilter typeImportFilter;
 
         @Override
         protected void doRunPhase(Env<AttrContext> env) {
@@ -304,26 +299,26 @@
         }
 
         private void resolveImports(JCCompilationUnit tree, Env<AttrContext> env) {
-            if (!tree.starImportScope.isEmpty()) {
+            if (tree.starImportScope.isFilled()) {
                 // we must have already processed this toplevel
                 return;
             }
 
             ImportFilter prevStaticImportFilter = staticImportFilter;
+            ImportFilter prevTypeImportFilter = typeImportFilter;
             DiagnosticPosition prevLintPos = deferredLintHandler.immediate();
             Lint prevLint = chk.setLint(lint);
             Env<AttrContext> prevEnv = this.env;
             try {
                 this.env = env;
                 final PackageSymbol packge = env.toplevel.packge;
-                this.staticImportFilter = new ImportFilter() {
-                    @Override
-                    public boolean accepts(Scope origin, Symbol sym) {
-                        return sym.isStatic() &&
-                               chk.staticImportAccessible(sym, packge) &&
-                               sym.isMemberOf((TypeSymbol) origin.owner, types);
-                    }
-                };
+                this.staticImportFilter =
+                        (origin, sym) -> sym.isStatic() &&
+                                         chk.importAccessible(sym, packge) &&
+                                         sym.isMemberOf((TypeSymbol) origin.owner, types);
+                this.typeImportFilter =
+                        (origin, sym) -> sym.kind == TYP &&
+                                         chk.importAccessible(sym, packge);
 
                 // Import-on-demand java.lang.
                 importAll(tree.pos, syms.enterPackage(names.java_lang), env);
@@ -340,6 +335,7 @@
                 chk.setLint(prevLint);
                 deferredLintHandler.setPos(prevLintPos);
                 this.staticImportFilter = prevStaticImportFilter;
+                this.typeImportFilter = prevTypeImportFilter;
             }
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/ImportInaccessible.java	Tue Feb 24 16:11:59 2015 +0100
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+/**
+ * @test
+ * @bug 8067886
+ * @summary Verify that type import on demand won't put inaccessible types into the Scope
+ * @compile/fail/ref=ImportInaccessible.out -XDrawDiagnostics ImportInaccessible.java
+ */
+package p;
+import p.ImportInaccessible.Nested.*;
+
+class ImportInaccessible {
+    static class Nested<X extends Inner> {
+        private static class Inner{}
+     }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/ImportInaccessible.out	Tue Feb 24 16:11:59 2015 +0100
@@ -0,0 +1,2 @@
+ImportInaccessible.java:34:35: compiler.err.cant.resolve.location: kindname.class, Inner, , , (compiler.misc.location: kindname.class, p.ImportInaccessible, null)
+1 error