# HG changeset patch # User mcimadamore # Date 1338482644 -3600 # Node ID 37dc15c68760f84edde588a5a788701757be7648 # Parent af6a4c24f4e3a021d96ef404ca41f8454d8dafd3 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 diff -r af6a4c24f4e3 -r 37dc15c68760 src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu May 31 17:42:14 2012 +0100 +++ b/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 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) { diff -r af6a4c24f4e3 -r 37dc15c68760 src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu May 31 17:42:14 2012 +0100 +++ b/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); } diff -r af6a4c24f4e3 -r 37dc15c68760 src/share/classes/com/sun/tools/javac/tree/TreeInfo.java --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu May 31 17:42:14 2012 +0100 +++ b/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 */ diff -r af6a4c24f4e3 -r 37dc15c68760 test/tools/javac/enum/7160084/T7160084a.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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); + } +} diff -r af6a4c24f4e3 -r 37dc15c68760 test/tools/javac/enum/7160084/T7160084b.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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); + } +}