Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
|
@@ -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)); |
|
|
} |
|
|
} |