aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpgovereau <none@none>2014-06-18 12:30:29 -0400
committerpgovereau <none@none>2014-06-18 12:30:29 -0400
commit7cbd2bf15b73def0638af556ce1c6b77393e244d (patch)
treec09caef2b81547db50c0864d2a2b1b3dcec1341f
parent29563410adba74b7d6d64335a6454dc479f5a575 (diff)
8027886: javac allows illegal receiver parameters
8029042: Receiver parameter not supported on local class constructor Reviewed-by: jfranck, jlahoda
-rw-r--r--src/share/classes/com/sun/tools/javac/code/Flags.java3
-rw-r--r--src/share/classes/com/sun/tools/javac/comp/Check.java4
-rw-r--r--src/share/classes/com/sun/tools/javac/comp/MemberEnter.java38
-rw-r--r--src/share/classes/com/sun/tools/javac/tree/TreeInfo.java8
-rw-r--r--test/tools/javac/annotations/FinalReceiverTest.java14
-rw-r--r--test/tools/javac/annotations/FinalReceiverTest.out2
-rw-r--r--test/tools/javac/annotations/LocalInnerReceiverTest.java37
-rw-r--r--test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java8
8 files changed, 88 insertions, 26 deletions
diff --git a/src/share/classes/com/sun/tools/javac/code/Flags.java b/src/share/classes/com/sun/tools/javac/code/Flags.java
index 241b3019..bbe45f80 100644
--- a/src/share/classes/com/sun/tools/javac/code/Flags.java
+++ b/src/share/classes/com/sun/tools/javac/code/Flags.java
@@ -295,7 +295,8 @@ public class Flags {
ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT,
InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
AnnotationTypeElementMask = ABSTRACT | PUBLIC,
- LocalVarFlags = FINAL | PARAMETER;
+ LocalVarFlags = FINAL | PARAMETER,
+ ReceiverParamFlags = PARAMETER;
public static Set<Modifier> asModifierSet(long flags) {
diff --git a/src/share/classes/com/sun/tools/javac/comp/Check.java b/src/share/classes/com/sun/tools/javac/comp/Check.java
index 56033cfe..7511ad54 100644
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -1038,7 +1038,9 @@ public class Check {
switch (sym.kind) {
case VAR:
- if (sym.owner.kind != TYP)
+ if (TreeInfo.isReceiverParam(tree))
+ mask = ReceiverParamFlags;
+ else if (sym.owner.kind != TYP)
mask = LocalVarFlags;
else if ((sym.owner.flags_field & INTERFACE) != 0)
mask = implicit = InterfaceVarFlags;
diff --git a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
index 95f10e43..7fa7fcc4 100644
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
@@ -652,22 +652,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
} else {
attr.attribType(tree.vartype, localEnv);
- if (tree.nameexpr != null) {
- attr.attribExpr(tree.nameexpr, localEnv);
- MethodSymbol m = localEnv.enclMethod.sym;
- if (m.isConstructor()) {
- Type outertype = m.owner.owner.type;
- if (outertype.hasTag(TypeTag.CLASS)) {
- checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type");
- checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name");
- } else {
- log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class");
- }
- } else {
- checkType(tree.vartype, m.owner.type, "incorrect.receiver.type");
- checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name");
- }
- }
+ if (TreeInfo.isReceiverParam(tree))
+ checkReceiver(tree, localEnv);
}
} finally {
deferredLintHandler.setPos(prevLintPos);
@@ -714,6 +700,26 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
log.error(tree, diag, type, tree.type);
}
}
+ void checkReceiver(JCVariableDecl tree, Env<AttrContext> localEnv) {
+ attr.attribExpr(tree.nameexpr, localEnv);
+ MethodSymbol m = localEnv.enclMethod.sym;
+ if (m.isConstructor()) {
+ Type outertype = m.owner.owner.type;
+ if (outertype.hasTag(TypeTag.METHOD)) {
+ // we have a local inner class
+ outertype = m.owner.owner.owner.type;
+ }
+ if (outertype.hasTag(TypeTag.CLASS)) {
+ checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type");
+ checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name");
+ } else {
+ log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class");
+ }
+ } else {
+ checkType(tree.vartype, m.owner.type, "incorrect.receiver.type");
+ checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name");
+ }
+ }
public boolean needsLazyConstValue(JCTree tree) {
InitTreeVisitor initTreeVisitor = new InitTreeVisitor();
diff --git a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
index f871bf66..f8d7d583 100644
--- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
@@ -135,6 +135,14 @@ public class TreeInfo {
}
}
+ public static boolean isReceiverParam(JCTree tree) {
+ if (tree.hasTag(VARDEF)) {
+ return ((JCVariableDecl)tree).nameexpr != null;
+ } else {
+ return false;
+ }
+ }
+
/** Is there a constructor declaration in the given list of trees?
*/
public static boolean hasConstructors(List<JCTree> trees) {
diff --git a/test/tools/javac/annotations/FinalReceiverTest.java b/test/tools/javac/annotations/FinalReceiverTest.java
new file mode 100644
index 00000000..96ef9d98
--- /dev/null
+++ b/test/tools/javac/annotations/FinalReceiverTest.java
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8027886
+ * @summary Receiver parameters must not be final
+ * @compile/fail/ref=FinalReceiverTest.out -XDrawDiagnostics FinalReceiverTest.java
+ */
+
+class FinalReceiverTest {
+ void m() {
+ class Inner {
+ Inner(final FinalReceiverTest FinalReceiverTest.this) {}
+ }
+ }
+}
diff --git a/test/tools/javac/annotations/FinalReceiverTest.out b/test/tools/javac/annotations/FinalReceiverTest.out
new file mode 100644
index 00000000..0aaa9642
--- /dev/null
+++ b/test/tools/javac/annotations/FinalReceiverTest.out
@@ -0,0 +1,2 @@
+FinalReceiverTest.java:11:43: compiler.err.mod.not.allowed.here: final
+1 error
diff --git a/test/tools/javac/annotations/LocalInnerReceiverTest.java b/test/tools/javac/annotations/LocalInnerReceiverTest.java
new file mode 100644
index 00000000..c32ec409
--- /dev/null
+++ b/test/tools/javac/annotations/LocalInnerReceiverTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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 8029042
+ * @summary Receiver parameter not supported on local class constructor
+ * @compile LocalInnerReceiverTest.java
+ */
+
+class LocalInnerReceiverTest {
+ void m() {
+ class Inner {
+ Inner(LocalInnerReceiverTest LocalInnerReceiverTest.this) {}
+ }
+ }
+}
diff --git a/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java b/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java
index 95103ff1..c9d719c5 100644
--- a/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java
+++ b/test/tools/javac/annotations/typeAnnotations/newlocations/Receivers.java
@@ -54,14 +54,6 @@ class WithValue {
<T extends Runnable> void accept(@B("m") WithValue this, T r) throws Exception { }
}
-class WithFinal {
- void plain(final @B("m") WithFinal this) { }
- <T> void generic(final @B("m") WithFinal this) { }
- void withException(final @B("m") WithFinal this) throws Exception { }
- String nonVoid(final @B("m") WithFinal this) { return null; }
- <T extends Runnable> void accept(final @B("m") WithFinal this, T r) throws Exception { }
-}
-
class WithBody {
Object f;