Wed, 18 Jun 2014 12:06:50 -0400
8038975: Access control in enhanced for
Reviewed-by: vromero, jlahoda
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Jun 18 12:30:29 2014 -0400 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Jun 18 12:06:50 2014 -0400 1.3 @@ -276,6 +276,11 @@ 1.4 */ 1.5 public static final long LAMBDA_METHOD = 1L<<49; 1.6 1.7 + /** 1.8 + * Flag to control recursion in TransTypes 1.9 + */ 1.10 + public static final long TYPE_TRANSLATED = 1L<<50; 1.11 + 1.12 /** Modifier masks. 1.13 */ 1.14 public static final int 1.15 @@ -386,7 +391,8 @@ 1.16 BAD_OVERRIDE(Flags.BAD_OVERRIDE), 1.17 SIGNATURE_POLYMORPHIC(Flags.SIGNATURE_POLYMORPHIC), 1.18 THROWS(Flags.THROWS), 1.19 - LAMBDA_METHOD(Flags.LAMBDA_METHOD); 1.20 + LAMBDA_METHOD(Flags.LAMBDA_METHOD), 1.21 + TYPE_TRANSLATED(Flags.TYPE_TRANSLATED); 1.22 1.23 Flag(long flag) { 1.24 this.value = flag;
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jun 18 12:30:29 2014 -0400 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jun 18 12:06:50 2014 -0400 2.3 @@ -94,6 +94,7 @@ 2.4 final Annotate annotate; 2.5 final TypeAnnotations typeAnnotations; 2.6 final DeferredLintHandler deferredLintHandler; 2.7 + final TypeEnvs typeEnvs; 2.8 2.9 public static Attr instance(Context context) { 2.10 Attr instance = context.get(attrKey); 2.11 @@ -123,6 +124,7 @@ 2.12 annotate = Annotate.instance(context); 2.13 typeAnnotations = TypeAnnotations.instance(context); 2.14 deferredLintHandler = DeferredLintHandler.instance(context); 2.15 + typeEnvs = TypeEnvs.instance(context); 2.16 2.17 Options options = Options.instance(context); 2.18 2.19 @@ -432,7 +434,7 @@ 2.20 } 2.21 2.22 public Type attribType(JCTree node, TypeSymbol sym) { 2.23 - Env<AttrContext> env = enter.typeEnvs.get(sym); 2.24 + Env<AttrContext> env = typeEnvs.get(sym); 2.25 Env<AttrContext> localEnv = env.dup(node, env.info.dup()); 2.26 return attribTree(node, localEnv, unknownTypeInfo); 2.27 } 2.28 @@ -4051,7 +4053,7 @@ 2.29 // ... and attribute the bound class 2.30 c.flags_field |= UNATTRIBUTED; 2.31 Env<AttrContext> cenv = enter.classEnv(cd, env); 2.32 - enter.typeEnvs.put(c, cenv); 2.33 + typeEnvs.put(c, cenv); 2.34 attribClass(c); 2.35 return owntype; 2.36 } 2.37 @@ -4201,9 +4203,9 @@ 2.38 c.flags_field &= ~UNATTRIBUTED; 2.39 2.40 // Get environment current at the point of class definition. 2.41 - Env<AttrContext> env = enter.typeEnvs.get(c); 2.42 - 2.43 - // The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized, 2.44 + Env<AttrContext> env = typeEnvs.get(c); 2.45 + 2.46 + // The info.lint field in the envs stored in typeEnvs is deliberately uninitialized, 2.47 // because the annotations were not available at the time the env was created. Therefore, 2.48 // we look up the environment chain for the first enclosing environment for which the 2.49 // lint value is set. Typically, this is the parent env, but might be further if there
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jun 18 12:30:29 2014 -0400 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jun 18 12:06:50 2014 -0400 3.3 @@ -77,6 +77,7 @@ 3.4 final Types types; 3.5 final Flow flow; 3.6 final Names names; 3.7 + final TypeEnvs typeEnvs; 3.8 3.9 public static DeferredAttr instance(Context context) { 3.10 DeferredAttr instance = context.get(deferredAttrKey); 3.11 @@ -100,6 +101,7 @@ 3.12 flow = Flow.instance(context); 3.13 names = Names.instance(context); 3.14 stuckTree = make.Ident(names.empty).setType(Type.stuckType); 3.15 + typeEnvs = TypeEnvs.instance(context); 3.16 emptyDeferredAttrContext = 3.17 new DeferredAttrContext(AttrMode.CHECK, null, MethodResolutionPhase.BOX, infer.emptyContext, null, null) { 3.18 @Override 3.19 @@ -400,7 +402,7 @@ 3.20 //it is possible that nested expressions inside argument expression 3.21 //are left unchecked - in such cases there's nothing to clean up. 3.22 if (csym == null) return; 3.23 - enter.typeEnvs.remove(csym); 3.24 + typeEnvs.remove(csym); 3.25 chk.compiled.remove(csym.flatname); 3.26 syms.classes.remove(csym.flatname); 3.27 super.visitClassDef(tree);
4.1 --- a/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Jun 18 12:30:29 2014 -0400 4.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java Wed Jun 18 12:06:50 2014 -0400 4.3 @@ -105,6 +105,7 @@ 4.4 Names names; 4.5 JavaFileManager fileManager; 4.6 PkgInfo pkginfoOpt; 4.7 + TypeEnvs typeEnvs; 4.8 4.9 private final Todo todo; 4.10 4.11 @@ -142,14 +143,9 @@ 4.12 4.13 Options options = Options.instance(context); 4.14 pkginfoOpt = PkgInfo.get(options); 4.15 + typeEnvs = TypeEnvs.instance(context); 4.16 } 4.17 4.18 - /** A hashtable mapping classes and packages to the environments current 4.19 - * at the points of their definitions. 4.20 - */ 4.21 - Map<TypeSymbol,Env<AttrContext>> typeEnvs = 4.22 - new HashMap<TypeSymbol,Env<AttrContext>>(); 4.23 - 4.24 /** Accessor for typeEnvs 4.25 */ 4.26 public Env<AttrContext> getEnv(TypeSymbol sym) {
5.1 --- a/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Jun 18 12:30:29 2014 -0400 5.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java Wed Jun 18 12:06:50 2014 -0400 5.3 @@ -82,6 +82,7 @@ 5.4 private ConstFold cfolder; 5.5 private Target target; 5.6 private Source source; 5.7 + private final TypeEnvs typeEnvs; 5.8 private boolean allowEnums; 5.9 private final Name dollarAssertionsDisabled; 5.10 private final Name classDollar; 5.11 @@ -103,6 +104,7 @@ 5.12 cfolder = ConstFold.instance(context); 5.13 target = Target.instance(context); 5.14 source = Source.instance(context); 5.15 + typeEnvs = TypeEnvs.instance(context); 5.16 allowEnums = source.allowEnums(); 5.17 dollarAssertionsDisabled = names. 5.18 fromString(target.syntheticNameChar() + "assertionsDisabled"); 5.19 @@ -2452,10 +2454,16 @@ 5.20 } 5.21 5.22 public void visitClassDef(JCClassDecl tree) { 5.23 + Env<AttrContext> prevEnv = attrEnv; 5.24 ClassSymbol currentClassPrev = currentClass; 5.25 MethodSymbol currentMethodSymPrev = currentMethodSym; 5.26 + 5.27 currentClass = tree.sym; 5.28 currentMethodSym = null; 5.29 + attrEnv = typeEnvs.remove(currentClass); 5.30 + if (attrEnv == null) 5.31 + attrEnv = prevEnv; 5.32 + 5.33 classdefs.put(currentClass, tree); 5.34 5.35 proxies = proxies.dup(currentClass); 5.36 @@ -2527,6 +2535,7 @@ 5.37 // Append translated tree to `translated' queue. 5.38 translated.append(tree); 5.39 5.40 + attrEnv = prevEnv; 5.41 currentClass = currentClassPrev; 5.42 currentMethodSym = currentMethodSymPrev; 5.43
6.1 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Jun 18 12:30:29 2014 -0400 6.2 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Jun 18 12:06:50 2014 -0400 6.3 @@ -86,6 +86,7 @@ 6.4 private final Target target; 6.5 private final DeferredLintHandler deferredLintHandler; 6.6 private final Lint lint; 6.7 + private final TypeEnvs typeEnvs; 6.8 6.9 public static MemberEnter instance(Context context) { 6.10 MemberEnter instance = context.get(memberEnterKey); 6.11 @@ -113,6 +114,7 @@ 6.12 target = Target.instance(context); 6.13 deferredLintHandler = DeferredLintHandler.instance(context); 6.14 lint = Lint.instance(context); 6.15 + typeEnvs = TypeEnvs.instance(context); 6.16 allowTypeAnnos = source.allowTypeAnnotations(); 6.17 allowRepeatedAnnos = source.allowRepeatedAnnotations(); 6.18 } 6.19 @@ -1024,7 +1026,7 @@ 6.20 6.21 ClassSymbol c = (ClassSymbol)sym; 6.22 ClassType ct = (ClassType)c.type; 6.23 - Env<AttrContext> env = enter.typeEnvs.get(c); 6.24 + Env<AttrContext> env = typeEnvs.get(c); 6.25 JCClassDecl tree = (JCClassDecl)env.tree; 6.26 boolean wasFirst = isFirst; 6.27 isFirst = false;
7.1 --- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Wed Jun 18 12:30:29 2014 -0400 7.2 +++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Wed Jun 18 12:06:50 2014 -0400 7.3 @@ -967,10 +967,11 @@ 7.4 translateClass((ClassSymbol)st.tsym); 7.5 } 7.6 7.7 - Env<AttrContext> myEnv = enter.typeEnvs.remove(c); 7.8 - if (myEnv == null) { 7.9 + Env<AttrContext> myEnv = enter.getEnv(c); 7.10 + if (myEnv == null || (c.flags_field & TYPE_TRANSLATED) != 0) { 7.11 return; 7.12 } 7.13 + c.flags_field |= TYPE_TRANSLATED; 7.14 7.15 /* The two assertions below are set for early detection of any attempt 7.16 * to translate a class that:
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/share/classes/com/sun/tools/javac/comp/TypeEnvs.java Wed Jun 18 12:06:50 2014 -0400 8.3 @@ -0,0 +1,63 @@ 8.4 +/* 8.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. Oracle designates this 8.11 + * particular file as subject to the "Classpath" exception as provided 8.12 + * by Oracle in the LICENSE file that accompanied this code. 8.13 + * 8.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.17 + * version 2 for more details (a copy is included in the LICENSE file that 8.18 + * accompanied this code). 8.19 + * 8.20 + * You should have received a copy of the GNU General Public License version 8.21 + * 2 along with this work; if not, write to the Free Software Foundation, 8.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.23 + * 8.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.25 + * or visit www.oracle.com if you need additional information or have any 8.26 + * questions. 8.27 + */ 8.28 + 8.29 +package com.sun.tools.javac.comp; 8.30 + 8.31 +import java.util.Collection; 8.32 +import java.util.HashMap; 8.33 +import com.sun.tools.javac.code.Symbol.TypeSymbol; 8.34 +import com.sun.tools.javac.util.Context; 8.35 + 8.36 +/** This class contains the type environments used by Enter, MemberEnter, 8.37 + * Attr, DeferredAttr, and Lower. 8.38 + * 8.39 + * <p><b>This is NOT part of any supported API. 8.40 + * If you write code that depends on this, you do so at your own risk. 8.41 + * This code and its internal interfaces are subject to change or 8.42 + * deletion without notice.</b> 8.43 + */ 8.44 +class TypeEnvs { 8.45 + private static final long serialVersionUID = 571524752489954631L; 8.46 + 8.47 + protected static final Context.Key<TypeEnvs> typeEnvsKey = new Context.Key<>(); 8.48 + public static TypeEnvs instance(Context context) { 8.49 + TypeEnvs instance = context.get(typeEnvsKey); 8.50 + if (instance == null) 8.51 + instance = new TypeEnvs(context); 8.52 + return instance; 8.53 + } 8.54 + 8.55 + private HashMap<TypeSymbol,Env<AttrContext>> map; 8.56 + protected TypeEnvs(Context context) { 8.57 + map = new HashMap<>(); 8.58 + context.put(typeEnvsKey, this); 8.59 + } 8.60 + 8.61 + Env<AttrContext> get(TypeSymbol sym) { return map.get(sym); } 8.62 + Env<AttrContext> put(TypeSymbol sym, Env<AttrContext> env) { return map.put(sym, env); } 8.63 + Env<AttrContext> remove(TypeSymbol sym) { return map.remove(sym); } 8.64 + Collection<Env<AttrContext>> values() { return map.values(); } 8.65 + void clear() { map.clear(); } 8.66 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/tools/javac/T8038975/AccessTest.java Wed Jun 18 12:06:50 2014 -0400 9.3 @@ -0,0 +1,39 @@ 9.4 +/* 9.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.7 + * 9.8 + * This code is free software; you can redistribute it and/or modify it 9.9 + * under the terms of the GNU General Public License version 2 only, as 9.10 + * published by the Free Software Foundation. 9.11 + * 9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.15 + * version 2 for more details (a copy is included in the LICENSE file that 9.16 + * accompanied this code). 9.17 + * 9.18 + * You should have received a copy of the GNU General Public License version 9.19 + * 2 along with this work; if not, write to the Free Software Foundation, 9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.21 + * 9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 9.23 + * or visit www.oracle.com if you need additional information or have any 9.24 + * questions. 9.25 + */ 9.26 + 9.27 +/* 9.28 + * @test 9.29 + * @bug 8038975 9.30 + * @summary Access control in enhanced for 9.31 + * @compile AccessTest.java 9.32 + */ 9.33 + 9.34 +import a.*; 9.35 +public class AccessTest { 9.36 + private static class Impl extends B { 9.37 + public void method(Inner inner) { 9.38 + for (A a : inner) 9.39 + System.out.println(a); 9.40 + } 9.41 + } 9.42 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/test/tools/javac/T8038975/a/A.java Wed Jun 18 12:06:50 2014 -0400 10.3 @@ -0,0 +1,25 @@ 10.4 +/* 10.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.7 + * 10.8 + * This code is free software; you can redistribute it and/or modify it 10.9 + * under the terms of the GNU General Public License version 2 only, as 10.10 + * published by the Free Software Foundation. 10.11 + * 10.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 10.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.15 + * version 2 for more details (a copy is included in the LICENSE file that 10.16 + * accompanied this code). 10.17 + * 10.18 + * You should have received a copy of the GNU General Public License version 10.19 + * 2 along with this work; if not, write to the Free Software Foundation, 10.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 10.21 + * 10.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 10.23 + * or visit www.oracle.com if you need additional information or have any 10.24 + * questions. 10.25 + */ 10.26 + 10.27 +package a; 10.28 +public class A { }
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/tools/javac/T8038975/a/B.java Wed Jun 18 12:06:50 2014 -0400 11.3 @@ -0,0 +1,27 @@ 11.4 +/* 11.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + */ 11.26 + 11.27 +package a; 11.28 +public class B { 11.29 + protected abstract class Inner implements Iterable<A> { } 11.30 +}