# HG changeset patch # User vromero # Date 1394741623 0 # Node ID 06e3726c6b3f7999e3a987890b7042354ed4b7fc # Parent e7e0973e6d2e0e192770abd824fe4821ea6fafe3 8034924: Incorrect inheritance of inaccessible static method Reviewed-by: jjg, jlahoda diff -r e7e0973e6d2e -r 06e3726c6b3f langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Mar 13 17:36:51 2014 +0000 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Mar 13 20:13:43 2014 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, 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 @@ -467,11 +467,24 @@ private boolean hiddenIn(ClassSymbol clazz, Types types) { Symbol sym = hiddenInInternal(clazz, types); - return sym != null && sym != this; + Assert.check(sym != null, "the result of hiddenInInternal() can't be null"); + /* If we find the current symbol then there is no symbol hiding it + */ + return sym != this; } - private Symbol hiddenInInternal(ClassSymbol c, Types types) { - Scope.Entry e = c.members().lookup(name); + /** This method looks in the supertypes graph that has the current class as the + * initial node, till it finds the current symbol or another symbol that hides it. + * If the current class has more than one supertype (extends one class and + * implements one or more interfaces) then null can be returned, meaning that + * a wrong path in the supertypes graph was selected. Null can only be returned + * as a temporary value, as a result of the recursive call. + */ + private Symbol hiddenInInternal(ClassSymbol currentClass, Types types) { + if (currentClass == owner) { + return this; + } + Scope.Entry e = currentClass.members().lookup(name); while (e.scope != null) { if (e.sym.kind == kind && (kind != MTH || @@ -481,18 +494,19 @@ } e = e.next(); } - List hiddenSyms = List.nil(); - for (Type st : types.interfaces(c.type).prepend(types.supertype(c.type))) { + Symbol hiddenSym = null; + for (Type st : types.interfaces(currentClass.type) + .prepend(types.supertype(currentClass.type))) { if (st != null && (st.hasTag(CLASS))) { Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types); - if (sym != null) { - hiddenSyms = hiddenSyms.prepend(hiddenInInternal((ClassSymbol)st.tsym, types)); + if (sym == this) { + return this; + } else if (sym != null) { + hiddenSym = sym; } } } - return hiddenSyms.contains(this) ? - this : - (hiddenSyms.isEmpty() ? null : hiddenSyms.head); + return hiddenSym; } /** Is this symbol inherited into a given class? diff -r e7e0973e6d2e -r 06e3726c6b3f langtools/test/tools/javac/IncorrectInheritance/IncorrectInheritanceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/IncorrectInheritance/IncorrectInheritanceTest.java Thu Mar 13 20:13:43 2014 +0000 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, 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 8034924 + * @summary Incorrect inheritance of inaccessible static method + * @library /tools/javac/lib + * @build ToolBox + * @run main IncorrectInheritanceTest + */ + +public class IncorrectInheritanceTest { + private static final String ASrc = + "package pkg;\n" + + "\n" + + "public class A {\n" + + " static void foo(Object o) {}\n" + + " private static void bar(Object o) {}\n" + + "}"; + + private static final String BSrc = + "import pkg.A;\n" + + "class B extends A {\n" + + " public void foo(Object o) {}\n" + + " public void bar(Object o) {}\n" + + "}"; + + private static final String CSrc = + "class C extends B {\n" + + " public void m(Object o) {\n" + + " foo(o);\n" + + " bar(o);\n" + + " }\n" + + "}"; + + public static void main(String[] args) throws Exception { + new IncorrectInheritanceTest().test(); + } + + public void test() throws Exception { + ToolBox.JavaToolArgs javacParams = + new ToolBox.JavaToolArgs() + .setSources(ASrc, BSrc, CSrc); + ToolBox.javac(javacParams); + } + +}