8038975: Access control in enhanced for
authorpgovereau
Tue, 17 Jun 2014 11:11:59 -0400
changeset 25007 eb097d3a68f5
parent 25006 5d5fa4abab27
child 25008 969bfaae5bce
8038975: Access control in enhanced for Reviewed-by: vromero, jlahoda
langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java
langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
langtools/src/share/classes/com/sun/tools/javac/comp/TypeEnvs.java
langtools/test/tools/javac/T8038975/AccessTest.java
langtools/test/tools/javac/T8038975/a/A.java
langtools/test/tools/javac/T8038975/a/B.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Jun 16 11:30:31 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java	Tue Jun 17 11:11:59 2014 -0400
@@ -277,6 +277,11 @@
      */
     public static final long LAMBDA_METHOD = 1L<<49;
 
+    /**
+     * Flag to control recursion in TransTypes
+     */
+    public static final long TYPE_TRANSLATED = 1L<<50;
+
     /** Modifier masks.
      */
     public static final int
@@ -386,7 +391,8 @@
         BAD_OVERRIDE(Flags.BAD_OVERRIDE),
         SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC),
         THROWS(Flags.THROWS),
-        LAMBDA_METHOD(Flags.LAMBDA_METHOD);
+        LAMBDA_METHOD(Flags.LAMBDA_METHOD),
+        TYPE_TRANSLATED(Flags.TYPE_TRANSLATED);
 
         Flag(long flag) {
             this.value = flag;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jun 16 11:30:31 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Jun 17 11:11:59 2014 -0400
@@ -92,6 +92,7 @@
     final JCDiagnostic.Factory diags;
     final Annotate annotate;
     final DeferredLintHandler deferredLintHandler;
+    final TypeEnvs typeEnvs;
 
     public static Attr instance(Context context) {
         Attr instance = context.get(attrKey);
@@ -120,6 +121,7 @@
         diags = JCDiagnostic.Factory.instance(context);
         annotate = Annotate.instance(context);
         deferredLintHandler = DeferredLintHandler.instance(context);
+        typeEnvs = TypeEnvs.instance(context);
 
         Options options = Options.instance(context);
 
@@ -429,7 +431,7 @@
     }
 
     public Type attribType(JCTree node, TypeSymbol sym) {
-        Env<AttrContext> env = enter.typeEnvs.get(sym);
+        Env<AttrContext> env = typeEnvs.get(sym);
         Env<AttrContext> localEnv = env.dup(node, env.info.dup());
         return attribTree(node, localEnv, unknownTypeInfo);
     }
@@ -4252,7 +4254,7 @@
             // ... and attribute the bound class
             c.flags_field |= UNATTRIBUTED;
             Env<AttrContext> cenv = enter.classEnv(cd, env);
-            enter.typeEnvs.put(c, cenv);
+            typeEnvs.put(c, cenv);
             attribClass(c);
             return owntype;
         }
@@ -4398,9 +4400,9 @@
             c.flags_field &= ~UNATTRIBUTED;
 
             // Get environment current at the point of class definition.
-            Env<AttrContext> env = enter.typeEnvs.get(c);
-
-            // The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized,
+            Env<AttrContext> env = typeEnvs.get(c);
+
+            // The info.lint field in the envs stored in typeEnvs is deliberately uninitialized,
             // because the annotations were not available at the time the env was created. Therefore,
             // we look up the environment chain for the first enclosing environment for which the
             // lint value is set. Typically, this is the parent env, but might be further if there
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Mon Jun 16 11:30:31 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Tue Jun 17 11:11:59 2014 -0400
@@ -78,6 +78,7 @@
     final Flow flow;
     final Names names;
     final Annotate annotate;
+    final TypeEnvs typeEnvs;
 
     public static DeferredAttr instance(Context context) {
         DeferredAttr instance = context.get(deferredAttrKey);
@@ -102,6 +103,7 @@
         names = Names.instance(context);
         stuckTree = make.Ident(names.empty).setType(Type.stuckType);
         annotate = Annotate.instance(context);
+        typeEnvs = TypeEnvs.instance(context);
         emptyDeferredAttrContext =
             new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) {
                 @Override
@@ -420,7 +422,7 @@
                 //it is possible that nested expressions inside argument expression
                 //are left unchecked - in such cases there's nothing to clean up.
                 if (csym == null) return;
-                enter.typeEnvs.remove(csym);
+                typeEnvs.remove(csym);
                 chk.compiled.remove(csym.flatname);
                 syms.classes.remove(csym.flatname);
                 super.visitClassDef(tree);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Mon Jun 16 11:30:31 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Tue Jun 17 11:11:59 2014 -0400
@@ -103,6 +103,7 @@
     Names names;
     JavaFileManager fileManager;
     PkgInfo pkginfoOpt;
+    TypeEnvs typeEnvs;
 
     private final Todo todo;
 
@@ -139,13 +140,9 @@
 
         Options options = Options.instance(context);
         pkginfoOpt = PkgInfo.get(options);
+        typeEnvs = TypeEnvs.instance(context);
     }
 
-    /** A hashtable mapping classes and packages to the environments current
-     *  at the points of their definitions.
-     */
-    Map<TypeSymbol,Env<AttrContext>> typeEnvs = new HashMap<>();
-
     /** Accessor for typeEnvs
      */
     public Env<AttrContext> getEnv(TypeSymbol sym) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Mon Jun 16 11:30:31 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Tue Jun 17 11:11:59 2014 -0400
@@ -79,6 +79,7 @@
     private final ConstFold cfolder;
     private final Target target;
     private final Source source;
+    private final TypeEnvs typeEnvs;
     private final boolean allowEnums;
     private final Name dollarAssertionsDisabled;
     private final Name classDollar;
@@ -99,6 +100,7 @@
         cfolder = ConstFold.instance(context);
         target = Target.instance(context);
         source = Source.instance(context);
+        typeEnvs = TypeEnvs.instance(context);
         allowEnums = source.allowEnums();
         dollarAssertionsDisabled = names.
             fromString(target.syntheticNameChar() + "assertionsDisabled");
@@ -2450,10 +2452,16 @@
     }
 
     public void visitClassDef(JCClassDecl tree) {
+        Env<AttrContext> prevEnv = attrEnv;
         ClassSymbol currentClassPrev = currentClass;
         MethodSymbol currentMethodSymPrev = currentMethodSym;
+
         currentClass = tree.sym;
         currentMethodSym = null;
+        attrEnv = typeEnvs.remove(currentClass);
+        if (attrEnv == null)
+            attrEnv = prevEnv;
+
         classdefs.put(currentClass, tree);
 
         proxies = proxies.dup(currentClass);
@@ -2525,6 +2533,7 @@
         // Append translated tree to `translated' queue.
         translated.append(tree);
 
+        attrEnv = prevEnv;
         currentClass = currentClassPrev;
         currentMethodSym = currentMethodSymPrev;
 
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Mon Jun 16 11:30:31 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Tue Jun 17 11:11:59 2014 -0400
@@ -82,6 +82,7 @@
     private final Target target;
     private final DeferredLintHandler deferredLintHandler;
     private final Lint lint;
+    private final TypeEnvs typeEnvs;
 
     public static MemberEnter instance(Context context) {
         MemberEnter instance = context.get(memberEnterKey);
@@ -107,6 +108,7 @@
         target = Target.instance(context);
         deferredLintHandler = DeferredLintHandler.instance(context);
         lint = Lint.instance(context);
+        typeEnvs = TypeEnvs.instance(context);
         allowTypeAnnos = source.allowTypeAnnotations();
     }
 
@@ -1000,7 +1002,7 @@
 
         ClassSymbol c = (ClassSymbol)sym;
         ClassType ct = (ClassType)c.type;
-        Env<AttrContext> env = enter.typeEnvs.get(c);
+        Env<AttrContext> env = typeEnvs.get(c);
         JCClassDecl tree = (JCClassDecl)env.tree;
         boolean wasFirst = isFirst;
         isFirst = false;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Mon Jun 16 11:30:31 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Tue Jun 17 11:11:59 2014 -0400
@@ -966,10 +966,11 @@
             translateClass((ClassSymbol)st.tsym);
         }
 
-        Env<AttrContext> myEnv = enter.typeEnvs.remove(c);
-        if (myEnv == null) {
+        Env<AttrContext> myEnv = enter.getEnv(c);
+        if (myEnv == null || (c.flags_field & TYPE_TRANSLATED) != 0) {
             return;
         }
+        c.flags_field |= TYPE_TRANSLATED;
 
         /*  The two assertions below are set for early detection of any attempt
          *  to translate a class that:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TypeEnvs.java	Tue Jun 17 11:11:59 2014 -0400
@@ -0,0 +1,63 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.tools.javac.comp;
+
+import java.util.Collection;
+import java.util.HashMap;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.util.Context;
+
+/** This class contains the type environments used by Enter, MemberEnter,
+ *  Attr, DeferredAttr, and Lower.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+class TypeEnvs {
+    private static final long serialVersionUID = 571524752489954631L;
+
+    protected static final Context.Key<TypeEnvs> typeEnvsKey = new Context.Key<>();
+    public static TypeEnvs instance(Context context) {
+        TypeEnvs instance = context.get(typeEnvsKey);
+        if (instance == null)
+            instance = new TypeEnvs(context);
+        return instance;
+    }
+
+    private HashMap<TypeSymbol,Env<AttrContext>> map;
+    protected TypeEnvs(Context context) {
+        map = new HashMap<>();
+        context.put(typeEnvsKey, this);
+    }
+
+    Env<AttrContext> get(TypeSymbol sym) { return map.get(sym); }
+    Env<AttrContext> put(TypeSymbol sym, Env<AttrContext> env) { return map.put(sym, env); }
+    Env<AttrContext> remove(TypeSymbol sym) { return map.remove(sym); }
+    Collection<Env<AttrContext>> values() { return map.values(); }
+    void clear() { map.clear(); }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8038975/AccessTest.java	Tue Jun 17 11:11:59 2014 -0400
@@ -0,0 +1,39 @@
+/*
+ * 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 8038975
+ * @summary Access control in enhanced for
+ * @compile AccessTest.java
+ */
+
+import a.*;
+public class AccessTest {
+    private static class Impl extends B {
+        public void method(Inner inner) {
+            for (A a : inner)
+                System.out.println(a);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8038975/a/A.java	Tue Jun 17 11:11:59 2014 -0400
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package a;
+public class A { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8038975/a/B.java	Tue Jun 17 11:11:59 2014 -0400
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package a;
+public class B {
+    protected abstract class Inner implements Iterable<A> { }
+}