8233655: NPE at jdk.compiler/com.sun.tools.javac.comp.Flow$FlowAnalyzer.visitApply
Ensuring that errors reported during speculative attribution that belong to a different file are not lost. Reviewed-by: mcimadamore
This commit is contained in:
parent
006b5e0f96
commit
8787b9a66d
@ -505,14 +505,15 @@ public class DeferredAttr extends JCTree.Visitor {
|
|||||||
/**
|
/**
|
||||||
* Attribute the given tree, mostly reverting side-effects applied to shared
|
* Attribute the given tree, mostly reverting side-effects applied to shared
|
||||||
* compiler state. Exceptions include the ArgumentAttr.argumentTypeCache,
|
* 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,
|
<Z> JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo,
|
||||||
Supplier<DiagnosticHandler> diagHandlerCreator, AttributionMode attributionMode,
|
Supplier<DiagnosticHandler> diagHandlerCreator, AttributionMode attributionMode,
|
||||||
LocalCacheContext localCache) {
|
LocalCacheContext localCache) {
|
||||||
Env<AttrContext> speculativeEnv = env.dup(tree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner)));
|
Env<AttrContext> speculativeEnv = env.dup(tree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner)));
|
||||||
speculativeEnv.info.attributionMode = attributionMode;
|
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);
|
DeferredCompletionFailureHandler.Handler prevCFHandler = dcfh.setHandler(dcfh.speculativeCodeHandler);
|
||||||
Queues prevQueues = annotate.setQueues(new Queues());
|
Queues prevQueues = annotate.setQueues(new Queues());
|
||||||
int nwarnings = log.nwarnings;
|
int nwarnings = log.nwarnings;
|
||||||
@ -531,6 +532,35 @@ public class DeferredAttr extends JCTree.Visitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//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 deferred context is created on each method check. A deferred context is
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8177068
|
* @bug 8177068 8233655
|
||||||
* @summary CompletionFailures occurring during speculative attribution should
|
* @summary CompletionFailures occurring during speculative attribution should
|
||||||
* not be lost forever.
|
* not be lost forever.
|
||||||
* @library /tools/lib
|
* @library /tools/lib
|
||||||
@ -72,6 +72,7 @@ public class NoCompletionFailureSkipOnSpeculativeAttribution {
|
|||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
new NoCompletionFailureSkipOnSpeculativeAttribution().test();
|
new NoCompletionFailureSkipOnSpeculativeAttribution().test();
|
||||||
|
new NoCompletionFailureSkipOnSpeculativeAttribution().test8233655();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() throws Exception {
|
public void test() throws Exception {
|
||||||
@ -101,4 +102,32 @@ public class NoCompletionFailureSkipOnSpeculativeAttribution {
|
|||||||
|
|
||||||
Assert.check(output.equals(expectedOutput));
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user