8166108: VerifyError passing anonymous inner class to supertype constructor
Summary: Anonymous classes instantitated in explicit constructor calls cannot have enclosing instance
Reviewed-by: vromero
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java Wed Jul 05 22:14:30 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java Tue Sep 20 05:28:54 2016 +0530
@@ -134,7 +134,7 @@
/** Flag is set for nested classes that do not access instance members
* or `this' of an outer class and therefore don't need to be passed
* a this$n reference. This value is currently set only for anonymous
- * classes in superclass constructor calls and only for pre 1.4 targets.
+ * classes in superclass constructor calls.
* todo: use this value for optimizing away this$n parameters in
* other cases.
*/
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jul 05 22:14:30 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Tue Sep 20 05:28:54 2016 +0530
@@ -921,13 +921,11 @@
c.complete();
// If this class appears as an anonymous class
- // in a superclass constructor call where
- // no explicit outer instance is given,
+ // in a superclass constructor call
// disable implicit outer instance from being passed.
// (This would be an illegal access to "this before super").
if (env.info.isSelfCall &&
- env.tree.hasTag(NEWCLASS) &&
- ((JCNewClass)env.tree).encl == null) {
+ env.tree.hasTag(NEWCLASS)) {
c.flags_field |= NOOUTERTHIS;
}
attribClass(tree.pos(), c);
@@ -2329,6 +2327,9 @@
/** Make an attributed null check tree.
*/
public JCExpression makeNullCheck(JCExpression arg) {
+ // optimization: new Outer() can never be null; skip null check
+ if (arg.getTag() == NEWCLASS)
+ return arg;
// optimization: X.this is never null; skip null check
Name name = TreeInfo.name(arg);
if (name == names._this || name == names._super) return arg;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.java Tue Sep 20 05:28:54 2016 +0530
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8166108
+ * @summary Verify that a program cannot access instance state before construction
+ * @compile/fail/ref=AnonymousInSuperCallNegTest.out -XDrawDiagnostics AnonymousInSuperCallNegTest.java
+ */
+
+public class AnonymousInSuperCallNegTest {
+
+ static class Base {
+ Base(Object o) {}
+ }
+
+ static class Outer {
+ class Inner {}
+ }
+
+ public static class JavacBug extends Base {
+ int x;
+ JavacBug() {
+ super(new Outer().new Inner() {
+ void foo() {
+ System.out.println("x = " + x);
+ }
+ }); }
+ }
+
+ public static void main(String[] args) {
+ new JavacBug();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/AnonymousClass/AnonymousInSuperCallNegTest.out Tue Sep 20 05:28:54 2016 +0530
@@ -0,0 +1,2 @@
+AnonymousInSuperCallNegTest.java:23:49: compiler.err.cant.ref.before.ctor.called: x
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/AnonymousClass/AnonymousInSuperCallTest.java Tue Sep 20 05:28:54 2016 +0530
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, 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 8166108
+ * @summary Verify that javac skips outer this to anonymous inner classes in super type constructor calls
+ *
+ */
+
+public class AnonymousInSuperCallTest {
+
+ static class Base {
+ Base(Object o) {}
+ }
+
+ static class Outer {
+ class Inner {}
+ }
+
+ public static class JavacBug extends Base {
+ JavacBug() { super(new Outer().new Inner() {}); }
+ }
+
+ public static void main(String[] args) {
+ new JavacBug();
+ }
+}
\ No newline at end of file