OpenJDK / jdk / jdk
changeset 57708:a8680d72a2bf
8233655: NPE at jdk.compiler/com.sun.tools.javac.comp.Flow$FlowAnalyzer.visitApply
Summary: Ensuring that errors reported during speculative attribution that belong to a different file are not lost.
Reviewed-by: mcimadamore
author | jlahoda |
---|---|
date | Wed, 15 Jan 2020 11:31:16 +0100 |
parents | d2f1fd498726 |
children | 20c8599c64b7 |
files | src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java test/langtools/tools/javac/T8177068/NoCompletionFailureSkipOnSpeculativeAttribution.java |
diffstat | 2 files changed, 62 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Tue Jan 14 20:19:51 2020 -0800 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Wed Jan 15 11:31:16 2020 +0100 @@ -505,14 +505,15 @@ /** * Attribute the given tree, mostly reverting side-effects applied to shared * compiler state. Exceptions include the ArgumentAttr.argumentTypeCache, - * changes to which may be preserved if localCache is null. + * changes to which may be preserved if localCache is null and errors reported + * outside of the speculatively attributed tree. */ <Z> JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo, Supplier<DiagnosticHandler> diagHandlerCreator, AttributionMode attributionMode, LocalCacheContext localCache) { Env<AttrContext> speculativeEnv = env.dup(tree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); speculativeEnv.info.attributionMode = attributionMode; - Log.DiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator != null ? diagHandlerCreator.get() : new DeferredDiagnosticHandler(log); + Log.DiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator != null ? diagHandlerCreator.get() : new DeferredAttrDiagHandler(log, tree); DeferredCompletionFailureHandler.Handler prevCFHandler = dcfh.setHandler(dcfh.speculativeCodeHandler); Queues prevQueues = annotate.setQueues(new Queues()); int nwarnings = log.nwarnings; @@ -531,6 +532,35 @@ } } } + //where + static class DeferredAttrDiagHandler extends Log.DeferredDiagnosticHandler { + + static class PosScanner extends TreeScanner { + DiagnosticPosition pos; + boolean found = false; + + PosScanner(DiagnosticPosition pos) { + this.pos = pos; + } + + @Override + public void scan(JCTree tree) { + if (tree != null && + tree.pos() == pos) { + found = true; + } + super.scan(tree); + } + } + + DeferredAttrDiagHandler(Log log, JCTree newTree) { + super(log, d -> { + PosScanner posScanner = new PosScanner(d.getDiagnosticPosition()); + posScanner.scan(newTree); + return posScanner.found; + }); + } + } /** * A deferred context is created on each method check. A deferred context is
--- a/test/langtools/tools/javac/T8177068/NoCompletionFailureSkipOnSpeculativeAttribution.java Tue Jan 14 20:19:51 2020 -0800 +++ b/test/langtools/tools/javac/T8177068/NoCompletionFailureSkipOnSpeculativeAttribution.java Wed Jan 15 11:31:16 2020 +0100 @@ -23,7 +23,7 @@ /* * @test - * @bug 8177068 + * @bug 8177068 8233655 * @summary CompletionFailures occurring during speculative attribution should * not be lost forever. * @library /tools/lib @@ -72,6 +72,7 @@ public static void main(String[] args) throws Exception { new NoCompletionFailureSkipOnSpeculativeAttribution().test(); + new NoCompletionFailureSkipOnSpeculativeAttribution().test8233655(); } public void test() throws Exception { @@ -101,4 +102,32 @@ Assert.check(output.equals(expectedOutput)); } + + public void test8233655() throws Exception { + ToolBox tb = new ToolBox(); + tb.writeJavaFiles(Paths.get("."), + "public class Test {" + + " private <T> T test(Class<?> c) {\n" + + " Class<?> c2 = test(test(Helper.class));\n" + + " return null;\n" + + " }\n" + + "}", + "public class Helper extends Unknown {}"); + + List<String> output = new JavacTask(tb) + .sourcepath(".") + .options("-XDrawDiagnostics") + .classpath(".") + .files("Test.java") + .run(Task.Expect.FAIL) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + List<String> expectedOutput = List.of( + "Helper.java:1:29: compiler.err.cant.resolve: kindname.class, Unknown, , ", + "1 error" + ); + + Assert.check(output.equals(expectedOutput)); + } }