# HG changeset patch # User mcimadamore # Date 1441985240 -3600 # Node ID 551d797dc8637a489411c0c028439e4b97b4acfd # Parent 2d65e99e2ae7fa64ad1ea83dbf16c171aca75a68 8135246: CheckAttributedTree silently generates spurious compiler error Summary: cyclic inheritance errors should cause shared combo context to be thrown away Reviewed-by: jlahoda diff -r 2d65e99e2ae7 -r 551d797dc863 test/tools/javac/lib/combo/ReusableContext.java --- a/test/tools/javac/lib/combo/ReusableContext.java Thu Sep 10 21:10:20 2015 +0200 +++ b/test/tools/javac/lib/combo/ReusableContext.java Fri Sep 11 16:27:20 2015 +0100 @@ -31,8 +31,12 @@ import com.sun.source.util.TaskListener; import com.sun.source.util.TreeScanner; import com.sun.tools.javac.api.MultiTaskListener; +import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symtab; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Type.ClassType; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.comp.Check; import com.sun.tools.javac.comp.CompileStates; @@ -93,23 +97,46 @@ //find if any of the roots have redefined java.* classes Symtab syms = Symtab.instance(this); - new TreeScanner() { - @Override - public Void visitClass(ClassTree node, Void aVoid) { - Symbol sym = ((JCClassDecl)node).sym; - if (sym != null) { - syms.classes.remove(sym.flatName()); - if (sym.flatName().toString().startsWith("java.")) { - polluted = true; - } - } - return super.visitClass(node, aVoid); - } - }.scan(roots, null); + pollutionScanner.scan(roots, syms); roots.clear(); } } + /** + * This scanner detects as to whether the shared context has been polluted. This happens + * whenever a compiled program redefines a core class (in 'java.*' package) or when + * (typically because of cyclic inheritance) the symbol kind of a core class has been touched. + */ + TreeScanner pollutionScanner = new TreeScanner() { + @Override + public Void visitClass(ClassTree node, Symtab syms) { + Symbol sym = ((JCClassDecl)node).sym; + if (sym != null) { + syms.classes.remove(sym.flatName()); + Type sup = supertype(sym); + if (isCoreClass(sym) || + (sup != null && isCoreClass(sup.tsym) && sup.tsym.kind != Kinds.Kind.TYP)) { + polluted = true; + } + } + return super.visitClass(node, syms); + } + + private boolean isCoreClass(Symbol s) { + return s.flatName().toString().startsWith("java."); + } + + private Type supertype(Symbol s) { + if (s.type == null || + !s.type.hasTag(TypeTag.CLASS)) { + return null; + } else { + ClassType ct = (ClassType)s.type; + return ct.supertype_field; + } + } + }; + @Override public void finished(TaskEvent e) { if (e.getKind() == Kind.PARSE) {