Wed, 18 Jun 2014 12:30:29 -0400
8027886: javac allows illegal receiver parameters
8029042: Receiver parameter not supported on local class constructor
Reviewed-by: jfranck, jlahoda
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Flags.java Tue Jun 17 16:32:18 2014 -0600 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Jun 18 12:30:29 2014 -0400 1.3 @@ -295,7 +295,8 @@ 1.4 ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT, 1.5 InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT, 1.6 AnnotationTypeElementMask = ABSTRACT | PUBLIC, 1.7 - LocalVarFlags = FINAL | PARAMETER; 1.8 + LocalVarFlags = FINAL | PARAMETER, 1.9 + ReceiverParamFlags = PARAMETER; 1.10 1.11 1.12 public static Set<Modifier> asModifierSet(long flags) {
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Jun 17 16:32:18 2014 -0600 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Jun 18 12:30:29 2014 -0400 2.3 @@ -1038,7 +1038,9 @@ 2.4 2.5 switch (sym.kind) { 2.6 case VAR: 2.7 - if (sym.owner.kind != TYP) 2.8 + if (TreeInfo.isReceiverParam(tree)) 2.9 + mask = ReceiverParamFlags; 2.10 + else if (sym.owner.kind != TYP) 2.11 mask = LocalVarFlags; 2.12 else if ((sym.owner.flags_field & INTERFACE) != 0) 2.13 mask = implicit = InterfaceVarFlags;
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Tue Jun 17 16:32:18 2014 -0600 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Jun 18 12:30:29 2014 -0400 3.3 @@ -652,22 +652,8 @@ 3.4 attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); 3.5 } else { 3.6 attr.attribType(tree.vartype, localEnv); 3.7 - if (tree.nameexpr != null) { 3.8 - attr.attribExpr(tree.nameexpr, localEnv); 3.9 - MethodSymbol m = localEnv.enclMethod.sym; 3.10 - if (m.isConstructor()) { 3.11 - Type outertype = m.owner.owner.type; 3.12 - if (outertype.hasTag(TypeTag.CLASS)) { 3.13 - checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type"); 3.14 - checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name"); 3.15 - } else { 3.16 - log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class"); 3.17 - } 3.18 - } else { 3.19 - checkType(tree.vartype, m.owner.type, "incorrect.receiver.type"); 3.20 - checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name"); 3.21 - } 3.22 - } 3.23 + if (TreeInfo.isReceiverParam(tree)) 3.24 + checkReceiver(tree, localEnv); 3.25 } 3.26 } finally { 3.27 deferredLintHandler.setPos(prevLintPos); 3.28 @@ -714,6 +700,26 @@ 3.29 log.error(tree, diag, type, tree.type); 3.30 } 3.31 } 3.32 + void checkReceiver(JCVariableDecl tree, Env<AttrContext> localEnv) { 3.33 + attr.attribExpr(tree.nameexpr, localEnv); 3.34 + MethodSymbol m = localEnv.enclMethod.sym; 3.35 + if (m.isConstructor()) { 3.36 + Type outertype = m.owner.owner.type; 3.37 + if (outertype.hasTag(TypeTag.METHOD)) { 3.38 + // we have a local inner class 3.39 + outertype = m.owner.owner.owner.type; 3.40 + } 3.41 + if (outertype.hasTag(TypeTag.CLASS)) { 3.42 + checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type"); 3.43 + checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name"); 3.44 + } else { 3.45 + log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class"); 3.46 + } 3.47 + } else { 3.48 + checkType(tree.vartype, m.owner.type, "incorrect.receiver.type"); 3.49 + checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name"); 3.50 + } 3.51 + } 3.52 3.53 public boolean needsLazyConstValue(JCTree tree) { 3.54 InitTreeVisitor initTreeVisitor = new InitTreeVisitor();
4.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Tue Jun 17 16:32:18 2014 -0600 4.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Wed Jun 18 12:30:29 2014 -0400 4.3 @@ -135,6 +135,14 @@ 4.4 } 4.5 } 4.6 4.7 + public static boolean isReceiverParam(JCTree tree) { 4.8 + if (tree.hasTag(VARDEF)) { 4.9 + return ((JCVariableDecl)tree).nameexpr != null; 4.10 + } else { 4.11 + return false; 4.12 + } 4.13 + } 4.14 + 4.15 /** Is there a constructor declaration in the given list of trees? 4.16 */ 4.17 public static boolean hasConstructors(List<JCTree> trees) {
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/annotations/FinalReceiverTest.java Wed Jun 18 12:30:29 2014 -0400 5.3 @@ -0,0 +1,14 @@ 5.4 +/* 5.5 + * @test /nodynamiccopyright/ 5.6 + * @bug 8027886 5.7 + * @summary Receiver parameters must not be final 5.8 + * @compile/fail/ref=FinalReceiverTest.out -XDrawDiagnostics FinalReceiverTest.java 5.9 + */ 5.10 + 5.11 +class FinalReceiverTest { 5.12 + void m() { 5.13 + class Inner { 5.14 + Inner(final FinalReceiverTest FinalReceiverTest.this) {} 5.15 + } 5.16 + } 5.17 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/annotations/FinalReceiverTest.out Wed Jun 18 12:30:29 2014 -0400 6.3 @@ -0,0 +1,2 @@ 6.4 +FinalReceiverTest.java:11:43: compiler.err.mod.not.allowed.here: final 6.5 +1 error
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/tools/javac/annotations/LocalInnerReceiverTest.java Wed Jun 18 12:30:29 2014 -0400 7.3 @@ -0,0 +1,37 @@ 7.4 +/* 7.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. 7.11 + * 7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.15 + * version 2 for more details (a copy is included in the LICENSE file that 7.16 + * accompanied this code). 7.17 + * 7.18 + * You should have received a copy of the GNU General Public License version 7.19 + * 2 along with this work; if not, write to the Free Software Foundation, 7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.21 + * 7.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.23 + * or visit www.oracle.com if you need additional information or have any 7.24 + * questions. 7.25 + */ 7.26 + 7.27 +/* 7.28 + * @test 7.29 + * @bug 8029042 7.30 + * @summary Receiver parameter not supported on local class constructor 7.31 + * @compile LocalInnerReceiverTest.java 7.32 + */ 7.33 + 7.34 +class LocalInnerReceiverTest { 7.35 + void m() { 7.36 + class Inner { 7.37 + Inner(LocalInnerReceiverTest LocalInnerReceiverTest.this) {} 7.38 + } 7.39 + } 7.40 +}
8.1 --- a/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java Tue Jun 17 16:32:18 2014 -0600 8.2 +++ b/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java Wed Jun 18 12:30:29 2014 -0400 8.3 @@ -54,14 +54,6 @@ 8.4 <T extends Runnable> void accept(@B("m") WithValue this, T r) throws Exception { } 8.5 } 8.6 8.7 -class WithFinal { 8.8 - void plain(final @B("m") WithFinal this) { } 8.9 - <T> void generic(final @B("m") WithFinal this) { } 8.10 - void withException(final @B("m") WithFinal this) throws Exception { } 8.11 - String nonVoid(final @B("m") WithFinal this) { return null; } 8.12 - <T extends Runnable> void accept(final @B("m") WithFinal this, T r) throws Exception { } 8.13 -} 8.14 - 8.15 class WithBody { 8.16 Object f; 8.17