6521805: Regression: JDK5/JDK6 javac allows write access to outer class reference
authormcimadamore
Tue, 11 Aug 2009 01:13:14 +0100
changeset 3557 a803afefa115
parent 3556 08a404c6ff0f
child 3558 56be54d60f36
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
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/test/tools/javac/6521805/T6521805a.java
langtools/test/tools/javac/6521805/T6521805a_1.out
langtools/test/tools/javac/6521805/T6521805a_2.out
langtools/test/tools/javac/6521805/T6521805b.java
langtools/test/tools/javac/6521805/T6521805c.java
langtools/test/tools/javac/6521805/T6521805d.java
langtools/test/tools/javac/6521805/T6521805d.out
langtools/test/tools/javac/6521805/T6521805e.java
langtools/test/tools/javac/6521805/T6521805e.out
langtools/test/tools/javac/6521805/p/Outer.java
langtools/test/tools/javac/6521805/p/Sub.java
langtools/test/tools/javac/6734819/T6734819a.out
langtools/test/tools/javac/6734819/T6734819b.out
langtools/test/tools/javac/policy/test2/byfile.AB.out
langtools/test/tools/javac/policy/test2/bytodo.AB.out
--- 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]