提交 1098e2b6 编写于 作者: V vromero

8022053: javac generates unverifiable initializer for nested subclass of local class

Reviewed-by: jjg, mcimadamore
上级 d50fd747
......@@ -356,22 +356,44 @@ public class Lower extends TreeTranslator {
}
}
ClassSymbol ownerToCopyFreeVarsFrom(ClassSymbol c) {
if (!c.isLocal()) {
return null;
}
Symbol currentOwner = c.owner;
while ((currentOwner.owner.kind & TYP) != 0 && currentOwner.isLocal()) {
currentOwner = currentOwner.owner;
}
if ((currentOwner.owner.kind & (VAR | MTH)) != 0 && c.isSubClass(currentOwner, types)) {
return (ClassSymbol)currentOwner;
}
return null;
}
/** Return the variables accessed from within a local class, which
* are declared in the local class' owner.
* (in reverse order of first access).
*/
List<VarSymbol> freevars(ClassSymbol c) {
List<VarSymbol> fvs = freevarCache.get(c);
if (fvs != null) {
return fvs;
}
if ((c.owner.kind & (VAR | MTH)) != 0) {
List<VarSymbol> fvs = freevarCache.get(c);
if (fvs == null) {
FreeVarCollector collector = new FreeVarCollector(c);
collector.scan(classDef(c));
fvs = collector.fvs;
freevarCache.put(c, fvs);
}
FreeVarCollector collector = new FreeVarCollector(c);
collector.scan(classDef(c));
fvs = collector.fvs;
freevarCache.put(c, fvs);
return fvs;
} else {
return List.nil();
ClassSymbol owner = ownerToCopyFreeVarsFrom(c);
if (owner != null) {
fvs = freevarCache.get(owner);
freevarCache.put(c, fvs);
return fvs;
} else {
return List.nil();
}
}
}
......@@ -1046,7 +1068,7 @@ public class Lower extends TreeTranslator {
boolean needsPrivateAccess(Symbol sym) {
if ((sym.flags() & PRIVATE) == 0 || sym.owner == currentClass) {
return false;
} else if (sym.name == names.init && (sym.owner.owner.kind & (VAR | MTH)) != 0) {
} else if (sym.name == names.init && sym.owner.isLocal()) {
// private constructor in local class: relax protection
sym.flags_field &= ~PRIVATE;
return false;
......@@ -2448,6 +2470,7 @@ public class Lower extends TreeTranslator {
tree.name = Convert.shortName(currentClass.flatName());
// Add this$n and free variables proxy definitions to class.
for (List<JCVariableDecl> l = fvdefs; l.nonEmpty(); l = l.tail) {
tree.defs = tree.defs.prepend(l.head);
enterSynthetic(tree.pos(), l.head.sym, currentClass.members());
......@@ -2670,8 +2693,7 @@ public class Lower extends TreeTranslator {
//where
private void visitMethodDefInternal(JCMethodDecl tree) {
if (tree.name == names.init &&
(currentClass.isInner() ||
(currentClass.owner.kind & (VAR | MTH)) != 0)) {
(currentClass.isInner() || currentClass.isLocal())) {
// We are seeing a constructor of an inner class.
MethodSymbol m = tree.sym;
......@@ -2818,7 +2840,7 @@ public class Lower extends TreeTranslator {
// If created class is local, add free variables after
// explicit constructor arguments.
if ((c.owner.kind & (VAR | MTH)) != 0) {
if (c.isLocal()) {
tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
}
......@@ -2837,7 +2859,7 @@ public class Lower extends TreeTranslator {
if (tree.encl != null) {
thisArg = attr.makeNullCheck(translate(tree.encl));
thisArg.type = tree.encl.type;
} else if ((c.owner.kind & (MTH | VAR)) != 0) {
} else if (c.isLocal()) {
// local class
thisArg = makeThis(tree.pos(), c.type.getEnclosingType().tsym);
} else {
......@@ -2966,7 +2988,7 @@ public class Lower extends TreeTranslator {
// If we are calling a constructor of a local class, add
// free variables after explicit constructor arguments.
ClassSymbol c = (ClassSymbol)constructor.owner;
if ((c.owner.kind & (VAR | MTH)) != 0) {
if (c.isLocal()) {
tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
}
......@@ -2994,7 +3016,7 @@ public class Lower extends TreeTranslator {
makeNullCheck(translate(((JCFieldAccess) tree.meth).selected));
tree.meth = make.Ident(constructor);
((JCIdent) tree.meth).name = methName;
} else if ((c.owner.kind & (MTH | VAR)) != 0 || methName == names._this){
} else if (c.isLocal() || methName == names._this){
// local class or this() call
thisArg = makeThis(tree.meth.pos(), c.type.getEnclosingType().tsym);
} else {
......
/*
* Copyright (c) 2013, 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 8022053
* @summary 8022053: javac generates unverifiable initializer for nested subclass of local class
* @run main UnverifiableInitForNestedLocalClassTest
*/
public class UnverifiableInitForNestedLocalClassTest {
public static void main(final String[] args) {
test("test");
}
static void test(final String arg) {
final String inlined = " inlined ";
class LocalClass {
String m() {
return "LocalClass " + arg + inlined;
}
class SubClass extends LocalClass {
@Override
String m() {
return "SubClass " + arg + inlined;
}
}
class SubSubClass extends SubClass {
@Override
String m() {
return "SubSubClass " + arg + inlined;
}
}
class AnotherLocal {
class AnotherSub extends LocalClass {
@Override
String m() {
return "AnotherSub " + arg + inlined;
}
}
}
}
System.out.println(new LocalClass().m());
System.out.println(new LocalClass().new SubClass().m());
System.out.println(new LocalClass().new SubSubClass().m());
System.out.println(new LocalClass().new AnotherLocal().new AnotherSub().m());
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册