6521805: Regression: JDK5/JDK6 javac allows write access to outer class reference
Summary: javac should warn/complain about identifiers with the same name as synthetic symbol
Reviewed-by: jjg
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Aug 11 01:12:40 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Aug 11 01:13:14 2009 +0100
@@ -65,6 +65,7 @@
private final Types types;
private final JCDiagnostic.Factory diags;
private final boolean skipAnnotations;
+ private boolean warnOnSyntheticConflicts;
private final TreeInfo treeinfo;
// The set of lint options currently in effect. It is initialized
@@ -99,6 +100,7 @@
allowAnnotations = source.allowAnnotations();
complexInference = options.get("-complexinference") != null;
skipAnnotations = options.get("skipAnnotations") != null;
+ warnOnSyntheticConflicts = options.get("warnOnSyntheticConflicts") != null;
boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
@@ -1709,6 +1711,35 @@
checkCompatibleConcretes(pos, c);
}
+ void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
+ for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
+ for (Scope.Entry e = ct.tsym.members().lookup(sym.name); e.scope == ct.tsym.members(); e = e.next()) {
+ // VM allows methods and variables with differing types
+ if (sym.kind == e.sym.kind &&
+ types.isSameType(types.erasure(sym.type), types.erasure(e.sym.type)) &&
+ sym != e.sym &&
+ (sym.flags() & Flags.SYNTHETIC) != (e.sym.flags() & Flags.SYNTHETIC) &&
+ (sym.flags() & BRIDGE) == 0 && (e.sym.flags() & BRIDGE) == 0) {
+ syntheticError(pos, (e.sym.flags() & SYNTHETIC) == 0 ? e.sym : sym);
+ return;
+ }
+ }
+ }
+ }
+
+ /** Report a conflict between a user symbol and a synthetic symbol.
+ */
+ private void syntheticError(DiagnosticPosition pos, Symbol sym) {
+ if (!sym.type.isErroneous()) {
+ if (warnOnSyntheticConflicts) {
+ log.warning(pos, "synthetic.name.conflict", sym, sym.location());
+ }
+ else {
+ log.error(pos, "synthetic.name.conflict", sym, sym.location());
+ }
+ }
+ }
+
/** Check that class c does not implement directly or indirectly
* the same parameterized interface with two different argument lists.
* @param pos Position to be used for error reporting.
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Aug 11 01:12:40 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Tue Aug 11 01:13:14 2009 +0100
@@ -596,34 +596,56 @@
* Symbol manipulation utilities
*************************************************************************/
- /** Report a conflict between a user symbol and a synthetic symbol.
- */
- private void duplicateError(DiagnosticPosition pos, Symbol sym) {
- if (!sym.type.isErroneous()) {
- log.error(pos, "synthetic.name.conflict", sym, sym.location());
- }
- }
-
/** Enter a synthetic symbol in a given scope, but complain if there was already one there.
* @param pos Position for error reporting.
* @param sym The symbol.
* @param s The scope.
*/
private void enterSynthetic(DiagnosticPosition pos, Symbol sym, Scope s) {
- if (sym.name != names.error && sym.name != names.empty) {
- for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
- if (sym != e.sym && sym.kind == e.sym.kind) {
- // VM allows methods and variables with differing types
- if ((sym.kind & (MTH|VAR)) != 0 &&
- !types.erasure(sym.type).equals(types.erasure(e.sym.type)))
- continue;
- duplicateError(pos, e.sym);
- break;
- }
+ s.enter(sym);
+ }
+
+ /** Check whether synthetic symbols generated during lowering conflict
+ * with user-defined symbols.
+ *
+ * @param translatedTrees lowered class trees
+ */
+ void checkConflicts(List<JCTree> translatedTrees) {
+ for (JCTree t : translatedTrees) {
+ t.accept(conflictsChecker);
+ }
+ }
+
+ JCTree.Visitor conflictsChecker = new TreeScanner() {
+
+ TypeSymbol currentClass;
+
+ @Override
+ public void visitMethodDef(JCMethodDecl that) {
+ chk.checkConflicts(that.pos(), that.sym, currentClass);
+ super.visitMethodDef(that);
+ }
+
+ @Override
+ public void visitVarDef(JCVariableDecl that) {
+ if (that.sym.owner.kind == TYP) {
+ chk.checkConflicts(that.pos(), that.sym, currentClass);
+ }
+ super.visitVarDef(that);
+ }
+
+ @Override
+ public void visitClassDef(JCClassDecl that) {
+ TypeSymbol prevCurrentClass = currentClass;
+ currentClass = that.sym;
+ try {
+ super.visitClassDef(that);
+ }
+ finally {
+ currentClass = prevCurrentClass;
}
}
- s.enter(sym);
- }
+ };
/** Look up a synthetic name in a given scope.
* @param scope The scope.
@@ -3192,6 +3214,7 @@
makeAccessible(l.head);
for (EnumMapping map : enumSwitchMap.values())
map.translate();
+ checkConflicts(this.translated.toList());
translated = this.translated;
} finally {
// note that recursive invocations of this method fail hard
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Aug 11 01:12:40 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Aug 11 01:13:14 2009 +0100
@@ -1207,6 +1207,9 @@
return stopIfError(CompileState.FLOW, results);
}
+ HashMap<Env<AttrContext>, Queue<Pair<Env<AttrContext>, JCClassDecl>>> desugaredEnvs =
+ new HashMap<Env<AttrContext>, Queue<Pair<Env<AttrContext>, JCClassDecl>>>();
+
/**
* Prepare attributed parse trees, in conjunction with their attribution contexts,
* for source or code generation. If the file was not listed on the command line,
@@ -1222,10 +1225,17 @@
return;
}
+ if (compileStates.isDone(env, CompileState.LOWER)) {
+ results.addAll(desugaredEnvs.get(env));
+ return;
+ }
+
/**
- * As erasure (TransTypes) destroys information needed in flow analysis,
- * including information in supertypes, we need to ensure that supertypes
- * are processed through attribute and flow before subtypes are translated.
+ * Ensure that superclasses of C are desugared before C itself. This is
+ * required for two reasons: (i) as erasure (TransTypes) destroys
+ * information needed in flow analysis and (ii) as some checks carried
+ * out during lowering require that all synthetic fields/methods have
+ * already been added to C and its superclasses.
*/
class ScanNested extends TreeScanner {
Set<Env<AttrContext>> dependencies = new LinkedHashSet<Env<AttrContext>>();
@@ -1246,8 +1256,8 @@
ScanNested scanner = new ScanNested();
scanner.scan(env.tree);
for (Env<AttrContext> dep: scanner.dependencies) {
- if (!compileStates.isDone(dep, CompileState.FLOW))
- flow(attribute(dep));
+ if (!compileStates.isDone(dep, CompileState.FLOW))
+ desugaredEnvs.put(dep, desugar(flow(attribute(dep))));
}
//We need to check for error another time as more classes might
@@ -1298,6 +1308,7 @@
return;
env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
+ compileStates.put(env, CompileState.TRANSTYPES);
if (shouldStop(CompileState.LOWER))
return;
@@ -1315,6 +1326,7 @@
//translate out inner classes
List<JCTree> cdefs = lower.translateTopLevelClass(env, env.tree, localMake);
+ compileStates.put(env, CompileState.LOWER);
if (shouldStop(CompileState.LOWER))
return;
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Aug 11 01:12:40 2009 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Tue Aug 11 01:13:14 2009 +0100
@@ -431,6 +431,8 @@
static import only from classes and interfaces
compiler.err.synthetic.name.conflict=\
the symbol {0} conflicts with a compiler-synthesized symbol in {1}
+compiler.warn.synthetic.name.conflict=\
+ the symbol {0} conflicts with a compiler-synthesized symbol in {1}
compiler.err.throws.not.allowed.in.intf.annotation=\
throws clause not allowed in @interface members
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805a.java Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6521805
+ * @summary Regression: JDK5/JDK6 javac allows write access to outer class reference
+ * @author mcimadamore
+ *
+ * @compile/fail/ref=T6521805a_1.out T6521805a.java -XDrawDiagnostics
+ * @compile/ref=T6521805a_2.out T6521805a.java -XDwarnOnSyntheticConflicts -XDrawDiagnostics
+ */
+
+class T6521805a {
+
+ static class Outer {
+ T6521805a this$0 = null;
+ }
+
+ public class Inner extends Outer {
+ public void foo() {
+ this$0 = new T6521805a();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805a_1.out Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,2 @@
+T6521805a.java:40:12: compiler.err.synthetic.name.conflict: this$0, T6521805a.Outer
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805a_2.out Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,2 @@
+T6521805a.java:40:12: compiler.warn.synthetic.name.conflict: this$0, T6521805a.Outer
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805b.java Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6521805
+ * @summary Regression: JDK5/JDK6 javac allows write access to outer class reference
+ * @author mcimadamore
+ *
+ * @compile T6521805b.java
+ */
+
+class T6521805b {
+
+ static class Outer {
+ String this$0 = null;
+ }
+
+ public class Inner extends Outer {
+ public void foo() {
+ this$0 = "Hello!";
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805c.java Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6521805
+ * @summary Regression: JDK5/JDK6 javac allows write access to outer class reference
+ * @author mcimadamore
+ *
+ * @compile T6521805c.java
+ */
+
+class T6521805c {
+
+ static class Outer {
+ T6521805c this$0() { return null;}
+ }
+
+ public class Inner extends Outer {
+ public void foo() {
+ this$0();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805d.java Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6521805
+ * @summary Regression: JDK5/JDK6 javac allows write access to outer class reference
+ * @author mcimadamore
+ *
+ * @compile/fail/ref=T6521805d.out T6521805d.java -XDrawDiagnostics
+ */
+
+class T6521805 {
+
+ static class Inner extends T6521805.Outer {
+
+ Inner(T6521805 t) {
+ t.super();
+ }
+
+ T6521805 this$0 = null;
+
+ public void foo() {
+ this$0 = new T6521805();
+ }
+ }
+
+ class Outer {}
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805d.out Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,2 @@
+T6521805d.java:41:18: compiler.err.synthetic.name.conflict: this$0, T6521805.Inner
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805e.java Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6521805
+ * @summary Regression: JDK5/JDK6 javac allows write access to outer class reference
+ * @author mcimadamore
+ *
+ * @compile/fail/ref=T6521805e.out p/Outer.java p/Sub.java -XDrawDiagnostics
+ * @compile/fail/ref=T6521805e.out p/Sub.java p/Outer.java -XDrawDiagnostics
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/T6521805e.out Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,2 @@
+Sub.java:8:11: compiler.err.synthetic.name.conflict: this$0, p.Inner
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/p/Outer.java Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,5 @@
+package p;
+
+class Outer {
+ class Super {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6521805/p/Sub.java Tue Aug 11 01:13:14 2009 +0100
@@ -0,0 +1,13 @@
+package p;
+
+class Inner extends Outer.Super {
+ Inner(Outer t) {
+ t.super();
+ }
+
+ Outer this$0 = null;
+
+ public void foo() {
+ this$0 = new Outer();
+ }
+}
--- a/langtools/test/tools/javac/6734819/T6734819a.out Tue Aug 11 01:12:40 2009 +0100
+++ b/langtools/test/tools/javac/6734819/T6734819a.out Tue Aug 11 01:13:14 2009 +0100
@@ -4,9 +4,9 @@
[flow W]
[attribute Z]
[flow Z]
+[desugar Z]
+[desugar W]
[desugar Y]
[generate code Y]
-[desugar W]
[generate code W]
-[desugar Z]
[generate code Z]
--- a/langtools/test/tools/javac/6734819/T6734819b.out Tue Aug 11 01:12:40 2009 +0100
+++ b/langtools/test/tools/javac/6734819/T6734819b.out Tue Aug 11 01:13:14 2009 +0100
@@ -2,8 +2,8 @@
[flow A]
[attribute B]
[flow B]
+[desugar B]
[desugar A]
[generate code A]
-[desugar B]
[generate code B.C]
[generate code B]
--- a/langtools/test/tools/javac/policy/test2/byfile.AB.out Tue Aug 11 01:12:40 2009 +0100
+++ b/langtools/test/tools/javac/policy/test2/byfile.AB.out Tue Aug 11 01:13:14 2009 +0100
@@ -2,6 +2,7 @@
[flow A]
[attribute B]
[flow B]
+[desugar B]
[desugar A]
[generate code A.A1]
[generate code A.A2]
@@ -10,6 +11,5 @@
[generate code <anonymous A$A4$1>]
[generate code A.A4]
[generate code A]
-[desugar B]
[generate code B.Inner]
[generate code B]
--- a/langtools/test/tools/javac/policy/test2/bytodo.AB.out Tue Aug 11 01:12:40 2009 +0100
+++ b/langtools/test/tools/javac/policy/test2/bytodo.AB.out Tue Aug 11 01:13:14 2009 +0100
@@ -2,6 +2,7 @@
[flow A]
[attribute B]
[flow B]
+[desugar B]
[desugar A]
[generate code A.A1]
[generate code A.A2]
@@ -10,6 +11,5 @@
[generate code <anonymous A$A4$1>]
[generate code A.A4]
[generate code A]
-[desugar B]
[generate code B.Inner]
[generate code B]