Skip to content
Permalink
Browse files

8233655: NPE at jdk.compiler/com.sun.tools.javac.comp.Flow$FlowAnalyz…

…er.visitApply

Ensuring that errors reported during speculative attribution that belong to a different file are not lost.

Reviewed-by: mcimadamore
  • Loading branch information
Jan Lahoda committed Jan 15, 2020
1 parent 006b5e0 commit 8787b9a66d4e72d151dcc28cfe5e9d4c8eec1b83
@@ -505,14 +505,15 @@ JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInf
/**
* 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 @@ JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInf
}
}
}
//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
@@ -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 @@ public void test() throws Exception {

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));
}
}

0 comments on commit 8787b9a

Please sign in to comment.