# HG changeset patch # User pgovereau # Date 1403017919 14400 # Node ID eb097d3a68f55385bd102108113913cd8775ee48 # Parent 5d5fa4abab2796486c14fa946797de5ed90ec396 8038975: Access control in enhanced for Reviewed-by: vromero, jlahoda diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/src/share/classes/com/sun/tools/javac/code/Flags.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; diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- 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 env = enter.typeEnvs.get(sym); + Env env = typeEnvs.get(sym); Env 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 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 env = enter.typeEnvs.get(c); - - // The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized, + Env 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 diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- 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); diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java --- 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> typeEnvs = new HashMap<>(); - /** Accessor for typeEnvs */ public Env getEnv(TypeSymbol sym) { diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java --- 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 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; diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- 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 env = enter.typeEnvs.get(c); + Env env = typeEnvs.get(c); JCClassDecl tree = (JCClassDecl)env.tree; boolean wasFirst = isFirst; isFirst = false; diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java --- 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 myEnv = enter.typeEnvs.remove(c); - if (myEnv == null) { + Env 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: diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/src/share/classes/com/sun/tools/javac/comp/TypeEnvs.java --- /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. + * + *

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. + */ +class TypeEnvs { + private static final long serialVersionUID = 571524752489954631L; + + protected static final Context.Key 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> map; + protected TypeEnvs(Context context) { + map = new HashMap<>(); + context.put(typeEnvsKey, this); + } + + Env get(TypeSymbol sym) { return map.get(sym); } + Env put(TypeSymbol sym, Env env) { return map.put(sym, env); } + Env remove(TypeSymbol sym) { return map.remove(sym); } + Collection> values() { return map.values(); } + void clear() { map.clear(); } +} diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/test/tools/javac/T8038975/AccessTest.java --- /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); + } + } +} diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/test/tools/javac/T8038975/a/A.java --- /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 { } diff -r 5d5fa4abab27 -r eb097d3a68f5 langtools/test/tools/javac/T8038975/a/B.java --- /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 { } +}