8182401: Verification error for enclosing instance capture inside super constructor invocation

Reviewed-by: vromero
This commit is contained in:
Srikanth Adayapalam 2017-12-11 06:58:14 +05:30
parent 71a866fe0c
commit 18e476899c
4 changed files with 230 additions and 0 deletions

View File

@ -510,6 +510,28 @@ public class LambdaToMethod extends TreeTranslator {
}
}
/**
* Translate instance creation expressions with implicit enclosing instances
* @param tree
*/
@Override
public void visitNewClass(JCNewClass tree) {
if (context == null || !analyzer.lambdaNewClassFilter(context, tree)) {
super.visitNewClass(tree);
} else {
int prevPos = make.pos;
try {
make.at(tree);
LambdaTranslationContext lambdaContext = (LambdaTranslationContext) context;
tree = lambdaContext.translate(tree);
super.visitNewClass(tree);
} finally {
make.at(prevPos);
}
}
}
@Override
public void visitVarDef(JCVariableDecl tree) {
LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context;
@ -984,6 +1006,7 @@ public class LambdaToMethod extends TreeTranslator {
//create the instance creation expression
//note that method reference syntax does not allow an explicit
//enclosing class (so the enclosing class is null)
// but this may need to be patched up later with the proxy for the outer this
JCNewClass newClass = make.NewClass(null,
List.nil(),
make.Type(tree.getQualifierExpression().type),
@ -2129,6 +2152,21 @@ public class LambdaToMethod extends TreeTranslator {
return null;
}
/* Translate away naked new instance creation expressions with implicit enclosing instances,
anchoring them to synthetic parameters that stand proxy for the qualified outer this handle.
*/
public JCNewClass translate(JCNewClass newClass) {
Assert.check(newClass.clazz.type.tsym.hasOuterInstance() && newClass.encl == null);
Map<Symbol, Symbol> m = translatedSymbols.get(LambdaSymbolKind.CAPTURED_OUTER_THIS);
final Type enclosingType = newClass.clazz.type.getEnclosingType();
if (m.containsKey(enclosingType.tsym)) {
Symbol tSym = m.get(enclosingType.tsym);
JCExpression encl = make.Ident(tSym).setType(enclosingType);
newClass.encl = encl;
}
return newClass;
}
/**
* The translatedSym is not complete/accurate until the analysis is
* finished. Once the analysis is finished, the translatedSym is

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2017, 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 8182401
* @summary Verification error for enclosing instance capture inside super constructor invocation
* @run main ImplicitEnclosingInstanceTest
*/
import java.util.function.Function;
public class ImplicitEnclosingInstanceTest {
static String cookie = "deadbeef";
static Object f(Function<String, Object> f) {
return f.apply("feed");
}
class S {
S(Object s) {
cookie += "face";
}
}
class A {
A(String s) {
cookie = s;
}
}
class B extends S {
B() {
super(f(s->new A(s)));
}
}
public static void main(String[] args) {
new ImplicitEnclosingInstanceTest().new B();
if (!cookie.equals("feedface"))
throw new AssertionError("Incorrect cookie!");
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2017, 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 8182401 8178444
* @summary Verification error for enclosing instance capture inside super constructor invocation
* @run main InnerInstanceCreationTest
*/
import java.util.function.Supplier;
public class InnerInstanceCreationTest {
static String cookie = "";
public static void main(String[] args) {
new InnerInstanceCreationTest().new Producer();
new InnerInstanceCreationTest().new Producer(0);
new InnerInstanceCreationTest().new Producer("");
if (!cookie.equals("BlahBlahBlah"))
throw new AssertionError("Unexpected cookie");
}
class Inner {
Inner() {
cookie += "Blah";
}
}
class Producer {
Producer() {
this(Inner::new);
}
Producer(int x) {
this(() -> new Inner());
}
Producer(String s) {
this(() -> InnerInstanceCreationTest.this.new Inner());
}
Producer(Supplier<Object> supplier) {
supplier.get();
}
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2017, 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 8182401
* @summary Verification error for enclosing instance capture inside super constructor invocation
* @run main ImplicitEnclosingInstanceTest
*/
import java.util.function.Function;
public class ImplicitEnclosingInstanceTest {
static String cookie = "deadbeef";
static Object f(Function<String, Object> f) {
return f.apply("feed");
}
class S {
S(Object s) {
cookie += "face";
}
}
class A {
A(String s) {
cookie = s;
}
}
class B extends S {
B() {
super(f(A::new));
}
}
public static void main(String[] args) {
new ImplicitEnclosingInstanceTest().new B();
if (!cookie.equals("feedface"))
throw new AssertionError("Incorrect cookie!");
}
}