8038975: Access control in enhanced for

Reviewed-by: vromero, jlahoda
This commit is contained in:
Paul Govereau 2014-06-17 11:11:59 -04:00
parent 2613fffb87
commit f2e2245e7b
11 changed files with 187 additions and 14 deletions

View File

@ -277,6 +277,11 @@ public class Flags {
*/
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 @@ public class Flags {
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;

View File

@ -92,6 +92,7 @@ public class Attr extends JCTree.Visitor {
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 @@ public class Attr extends JCTree.Visitor {
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 class Attr extends JCTree.Visitor {
}
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 @@ public class Attr extends JCTree.Visitor {
// ... 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 @@ public class Attr extends JCTree.Visitor {
c.flags_field &= ~UNATTRIBUTED;
// Get environment current at the point of class definition.
Env<AttrContext> env = enter.typeEnvs.get(c);
Env<AttrContext> env = typeEnvs.get(c);
// The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized,
// 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

View File

@ -78,6 +78,7 @@ public class DeferredAttr extends JCTree.Visitor {
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 @@ public class DeferredAttr extends JCTree.Visitor {
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 @@ public class DeferredAttr extends JCTree.Visitor {
//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);

View File

@ -103,6 +103,7 @@ public class Enter extends JCTree.Visitor {
Names names;
JavaFileManager fileManager;
PkgInfo pkginfoOpt;
TypeEnvs typeEnvs;
private final Todo todo;
@ -139,13 +140,9 @@ public class Enter extends JCTree.Visitor {
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) {

View File

@ -79,6 +79,7 @@ public class Lower extends TreeTranslator {
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 @@ public class Lower extends TreeTranslator {
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 class Lower extends TreeTranslator {
}
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 @@ public class Lower extends TreeTranslator {
// Append translated tree to `translated' queue.
translated.append(tree);
attrEnv = prevEnv;
currentClass = currentClassPrev;
currentMethodSym = currentMethodSymPrev;

View File

@ -82,6 +82,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
target = Target.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
lint = Lint.instance(context);
typeEnvs = TypeEnvs.instance(context);
allowTypeAnnos = source.allowTypeAnnotations();
}
@ -1000,7 +1002,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
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;

View File

@ -966,10 +966,11 @@ public class TransTypes extends TreeTranslator {
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:

View File

@ -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(); }
}

View File

@ -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);
}
}
}

View File

@ -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 { }

View File

@ -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> { }
}