changeset 1514:7e2c650b86bc

7160084: javac fails to compile an apparently valid class/interface combination Summary: javac generates wrong syntetized trees for nested enum constants Reviewed-by: jjg
author mcimadamore
date Wed, 29 May 2013 14:49:14 +0100
parents 12506bba2b67
children 028d81ce5e5b 9f2eea2fae59
files src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/MemberEnter.java src/share/classes/com/sun/tools/javac/tree/TreeInfo.java test/tools/javac/enum/7160084/T7160084a.java test/tools/javac/enum/7160084/T7160084b.java
diffstat 5 files changed, 152 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed May 22 16:02:05 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed May 29 14:49:14 2013 +0100
@@ -674,6 +674,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)
@@ -1620,7 +1627,9 @@
 
         // 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);
         Pair<Scope,Scope> mapping = getSyntheticScopeMapping(clazztype);
         clazztype = chk.checkDiamond(tree, clazztype);
         chk.validate(clazz, localEnv);
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Wed May 22 16:02:05 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Wed May 29 14:49:14 2013 +0100
@@ -625,7 +625,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/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Wed May 22 16:02:05 2013 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Wed May 29 14:49:14 2013 +0100
@@ -217,6 +217,15 @@
         }
     }
 
+    public static boolean isEnumInit(JCTree tree) {
+        switch (tree.getTag()) {
+            case JCTree.VARDEF:
+                return (((JCVariableDecl)tree).mods.flags & ENUM) != 0;
+            default:
+                return false;
+        }
+    }
+
     /** Return true if a tree represents the null literal. */
     public static boolean isNull(JCTree tree) {
         if (tree.getTag() != JCTree.LITERAL)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/enum/7160084/T7160084a.java	Wed May 29 14:49:14 2013 +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/test/tools/javac/enum/7160084/T7160084b.java	Wed May 29 14:49:14 2013 +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);
+    }
+}