7160084: javac fails to compile an apparently valid class/interface combination
authormcimadamore
Thu, 31 May 2012 17:44:04 +0100
changeset 12916 021c069e8e27
parent 12915 28cf1e0dafdc
child 12917 0c381f0ac967
7160084: javac fails to compile an apparently valid class/interface combination Summary: javac generates wrong syntetized trees for nested enum constants Reviewed-by: dlsmith, jjg
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
langtools/test/tools/javac/enum/7160084/T7160084a.java
langtools/test/tools/javac/enum/7160084/T7160084b.java
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu May 31 17:42:14 2012 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu May 31 17:44:04 2012 +0100
@@ -702,6 +702,13 @@
         return t;
     }
 
+    Type attribIdentAsEnumType(Env<AttrContext> env, JCIdent id) {
+        Assert.check((env.enclClass.sym.flags() & ENUM) != 0);
+        id.type = env.info.scope.owner.type;
+        id.sym = env.info.scope.owner;
+        return id.type;
+    }
+
     public void visitClassDef(JCClassDecl tree) {
         // Local classes have not been entered yet, so we need to do it now:
         if ((env.info.scope.owner.kind & (VAR | MTH)) != 0)
@@ -1657,7 +1664,10 @@
 
         // Attribute clazz expression and store
         // symbol + type back into the attributed tree.
-        Type clazztype = attribType(clazz, env);
+        Type clazztype = TreeInfo.isEnumInit(env.tree) ?
+            attribIdentAsEnumType(env, (JCIdent)clazz) :
+            attribType(clazz, env);
+
         clazztype = chk.checkDiamond(tree, clazztype);
         chk.validate(clazz, localEnv);
         if (tree.encl != null) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu May 31 17:42:14 2012 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Thu May 31 17:44:04 2012 +0100
@@ -620,7 +620,11 @@
         DeferredLintHandler prevLintHandler =
                 chk.setDeferredLintHandler(deferredLintHandler.setPos(tree.pos()));
         try {
-            attr.attribType(tree.vartype, localEnv);
+            if (TreeInfo.isEnumInit(tree)) {
+                attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
+            } else {
+                attr.attribType(tree.vartype, localEnv);
+            }
         } finally {
             chk.setDeferredLintHandler(prevLintHandler);
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu May 31 17:42:14 2012 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Thu May 31 17:44:04 2012 +0100
@@ -237,6 +237,15 @@
         }
     }
 
+    public static boolean isEnumInit(JCTree tree) {
+        switch (tree.getTag()) {
+            case VARDEF:
+                return (((JCVariableDecl)tree).mods.flags & ENUM) != 0;
+            default:
+                return false;
+        }
+    }
+
     /**
      * Return true if the AST corresponds to a static select of the kind A.B
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/7160084/T7160084a.java	Thu May 31 17:44:04 2012 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 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     7160084
+ * @summary javac fails to compile an apparently valid class/interface combination
+ */
+public class T7160084a {
+
+    static int assertionCount = 0;
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond) {
+            throw new AssertionError();
+        }
+    }
+
+    interface Intf {
+       enum MyEnumA {
+          AA(""),
+          UNUSED("");
+
+          private MyEnumA(String s) { }
+       }
+    }
+
+    enum MyEnumA implements Intf {
+        AA("");
+
+        private MyEnumA(String s) { }
+    }
+
+    public static void main(String... args) {
+        assertTrue(MyEnumA.values().length == 1);
+        assertTrue(Intf.MyEnumA.values().length == 2);
+        assertTrue(assertionCount == 2);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/7160084/T7160084b.java	Thu May 31 17:44:04 2012 +0100
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 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     7160084
+ * @summary javac fails to compile an apparently valid class/interface combination
+ */
+public class T7160084b {
+
+    static int assertionCount = 0;
+
+    static void assertTrue(boolean cond) {
+        assertionCount++;
+        if (!cond) {
+            throw new AssertionError();
+        }
+    }
+
+    interface Extras {
+        static class Enums {
+            static class Component {
+                Component() { throw new RuntimeException("oops!"); }
+            }
+        }
+    }
+
+    interface Test {
+        public class Enums {
+            interface Widget {
+                enum Component { X, Y };
+            }
+
+            enum Component implements Widget, Extras {
+                Z;
+            };
+
+            public static void test() {
+               assertTrue(Component.values().length == 1);
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        Test.Enums.test();
+        assertTrue(assertionCount == 1);
+    }
+}