Closed michaelhixson closed 2 years ago
Thanks for the report, @michaelhixson! For the java.lang.RuntimeException
, fixing should conceptually be easy, though some thought may be required as to how to do it while still allowing NullAway to build on JDK 8.
For the java.lang.AssertionError
, looks like that is an issue in the Checker Dataflow library from the Checker Framework and we'll need a fix there. Could you possibly file an issue on the Checker Framework regarding support for switch
expressions in Checker Dataflow to get their thoughts on difficulty of fixing?
Could you possibly file an issue on the Checker Framework regarding support for
switch
expressions in Checker Dataflow to get their thoughts on difficulty of fixing?
Any idea how I can craft a test case that uses Checker Dataflow directly, without NullAway, to demonstrate the problem to them? I gave it a shot and couldn't figure out how to use anything in the org.checkerframework.dataflow
package.
Yeah a standalone example will be tricky. You can probably just point them to this issue. Here is the relevant part of the exception stack that you can paste:
[ERROR] Caused by: java.lang.AssertionError: case visitor is implemented in SwitchBuilder
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder$CFGTranslationPhaseOne.visitCase(CFGBuilder.java:3381)
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder$CFGTranslationPhaseOne.visitCase(CFGBuilder.java:1416)
[ERROR] at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCase.accept(JCTree.java:1293)
[ERROR] at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
[ERROR] at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:106)
[ERROR] at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:114)
[ERROR] at jdk.compiler/com.sun.source.util.TreeScanner.visitSwitchExpression(TreeScanner.java:354)
[ERROR] at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1325)
[ERROR] at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder$CFGTranslationPhaseOne.translateAssignment(CFGBuilder.java:2687)
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder$CFGTranslationPhaseOne.visitVariable(CFGBuilder.java:4766)
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder$CFGTranslationPhaseOne.visitVariable(CFGBuilder.java:1416)
[ERROR] at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:980)
[ERROR] at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder$CFGTranslationPhaseOne.visitBlock(CFGBuilder.java:3258)
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder$CFGTranslationPhaseOne.visitBlock(CFGBuilder.java:1416)
[ERROR] at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1038)
[ERROR] at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:56)
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder$CFGTranslationPhaseOne.process(CFGBuilder.java:1571)
[ERROR] at org.checkerframework.dataflow.cfg.CFGBuilder.build(CFGBuilder.java:255)
And here is the line throwing the exception on the Checker Framework master branch.
Ok, I filed the upstream issue here: https://github.com/typetools/checker-framework/issues/2373
Does NullAway cover standard switch statements on enums today? I noticed this in our codebase today
Good catch, @ZacSweers! That one should be easy to fix. Can you file a separate issue for it?
Done - #299
For the
java.lang.RuntimeException
, fixing should conceptually be easy, though some thought may be required as to how to do it while still allowing NullAway to build on JDK 8.
@msridhar What do you think of an approach like this?
diff --git a/nullaway/src/main/java/com/uber/nullaway/NullAway.java b/nullaway/src/main/java/com/uber/nullaway/NullAway.java
index a600c5d..ce823b6 100644
--- a/nullaway/src/main/java/com/uber/nullaway/NullAway.java
+++ b/nullaway/src/main/java/com/uber/nullaway/NullAway.java
@@ -1962,6 +1962,10 @@ public class NullAway extends BugChecker
exprMayBeNull = nullnessFromDataflow(state, expr);
break;
default:
+ if (expr.getKind().name().equals("SWITCH_EXPRESSION")) {
+ exprMayBeNull = nullnessFromDataflow(state, expr);
+ break;
+ }
throw new RuntimeException(
"whoops, better handle " + expr.getKind() + " " + state.getSourceForNode(expr));
}
With that change to NullAway and the following change to dataflow, my code with switch expressions compiles.
diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java
index 505b5a3ec..58ed6738b 100644
--- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java
+++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/CFGBuilder.java
@@ -3382,11 +3382,6 @@ public class CFGBuilder {
}
}
- @Override
- public Node visitCase(CaseTree tree, Void p) {
- throw new AssertionError("case visitor is implemented in SwitchBuilder");
- }
-
@Override
public Node visitCatch(CatchTree tree, Void p) {
scan(tree.getParameter(), p);
This doesn't catch nullness errors involving switch expressions, but it seems like a good intermediate step.
@michaelhixson I'm ok with a change like this, though as you know we'll also need an updated Checker Framework dataflow library.
Any updates or a work around? Ran into this problem on a Java 14 project.
@lessthanoptimal unfortunately, no. We would still need a fix for typetools/checker-framework#2373 before we could ship a NullAway fix for this problem. We will definitely post an update here when we make some progress
With #510 landed the latest NullAway snapshot should no longer crash on the new kinds of switch
though it may be imprecise. Is anyone able to test this out? @lessthanoptimal?
It threw this exception:
error-prone version: 2.10.0
BugPattern: NullAway
Stack Trace:
java.lang.RuntimeException: whoops, better handle SWITCH_EXPRESSION switch (index) {
case 0 -> a;
case 1 -> b;
case 2 -> c;
case 3 -> d;
default -> throw new IllegalArgumentException("Requested index out of range. " + index);
}
at com.uber.nullaway.NullAway.mayBeNullExpr(NullAway.java:1948)
at com.uber.nullaway.NullAway.checkReturnExpression(NullAway.java:630)
at com.uber.nullaway.NullAway.matchReturn(NullAway.java:293)
at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:449)
at com.google.errorprone.scanner.ErrorProneScanner.visitReturn(ErrorProneScanner.java:816)
at com.google.errorprone.scanner.ErrorProneScanner.visitReturn(ErrorProneScanner.java:150)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1665)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
at jdk.compiler/com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:250)
at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:520)
at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:150)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1059)
Here's how I added the dependency:
project.ext.nullaway_version = '0.9.3-SNAPSHOT'
annotationProcessor "com.uber.nullaway:nullaway:$project.nullaway_version"
testAnnotationProcessor "com.uber.nullaway:nullaway:$project.nullaway_version"
Thanks! I should have known that something wouldn't work. I will work on fixing that crash and putting together a proper test case (may take a bit of time as we currently don't test on JDK 17).
Sounds good an thanks for working on this issue! FYI I got that error in JDK 15.
Sounds good an thanks for working on this issue! FYI I got that error in JDK 15.
Thanks! I'm sure the same error will appear in JDK 17. FWIW I don't think we have resources to test and fix NullAway bugs on non-LTS JDK releases, though if it's an easy fix we will try.
@lessthanoptimal this should be fixed now! Any chance you can again test the snapshot build on your code base?
@msridhar Just tried it and the SNAPSHOT is working! Thanks! I tested it in two projects.
Thanks for checking! We'll get this out in a new release soon though it may be after the holidays
Celebration might be premature. Was in the process of adding null checks to a project and ran into a situation where it blew up.
(see http://t.uber.com/nullaway )
/home/pja/projects/boofcv/main/boofcv-geo/src/main/java/boofcv/factory/geo/FactoryMultiViewRobust.java:190: error: An unhandled exception was thrown by the Error Prone static analysis plugin.
() -> switch (_configFundamental.errorModel) {
^
Please report this at https://github.com/google/error-prone/issues/new and include the following:
error-prone version: 2.9.0
BugPattern: NullAway
Stack Trace:
com.google.common.util.concurrent.ExecutionError: java.lang.AssertionError: case visitor is implemented in SwitchBuilder
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2053)
at com.google.common.cache.LocalCache.get(LocalCache.java:3966)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3989)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4950)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4956)
at com.uber.nullaway.dataflow.DataFlow.dataflow(DataFlow.java:146)
at com.uber.nullaway.dataflow.DataFlow.resultFor(DataFlow.java:276)
at com.uber.nullaway.dataflow.DataFlow.resultForExpr(DataFlow.java:253)
at com.uber.nullaway.dataflow.DataFlow.expressionDataflow(DataFlow.java:196)
at com.uber.nullaway.dataflow.AccessPathNullnessAnalysis.getNullness(AccessPathNullnessAnalysis.java:127)
at com.uber.nullaway.NullAway.nullnessFromDataflow(NullAway.java:1979)
at com.uber.nullaway.NullAway.mayBeNullExpr(NullAway.java:1942)
at com.uber.nullaway.NullAway.matchDereference(NullAway.java:2016)
at com.uber.nullaway.NullAway.matchMemberSelect(NullAway.java:439)
at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:450)
at com.google.errorprone.scanner.ErrorProneScanner.visitMemberSelect(ErrorProneScanner.java:727)
at com.google.errorprone.scanner.ErrorProneScanner.visitMemberSelect(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:2293)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.visitParenthesized(TreeScanner.java:591)
at com.google.errorprone.scanner.ErrorProneScanner.visitParenthesized(ErrorProneScanner.java:800)
at com.google.errorprone.scanner.ErrorProneScanner.visitParenthesized(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCParens.accept(JCTree.java:1970)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.visitSwitchExpression(TreeScanner.java:347)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1338)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
at jdk.compiler/com.sun.source.util.TreeScanner.visitLambdaExpression(TreeScanner.java:578)
at com.google.errorprone.scanner.ErrorProneScanner.visitLambdaExpression(ErrorProneScanner.java:703)
at com.google.errorprone.scanner.ErrorProneScanner.visitLambdaExpression(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCLambda.accept(JCTree.java:1926)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:113)
at jdk.compiler/com.sun.source.util.TreeScanner.visitMethodInvocation(TreeScanner.java:528)
at com.google.errorprone.scanner.ErrorProneScanner.visitMethodInvocation(ErrorProneScanner.java:752)
at com.google.errorprone.scanner.ErrorProneScanner.visitMethodInvocation(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1761)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.visitExpressionStatement(TreeScanner.java:452)
at com.google.errorprone.scanner.ErrorProneScanner.visitExpressionStatement(ErrorProneScanner.java:634)
at com.google.errorprone.scanner.ErrorProneScanner.visitExpressionStatement(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1540)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
at jdk.compiler/com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:250)
at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:521)
at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1059)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
at jdk.compiler/com.sun.source.util.TreeScanner.visitMethod(TreeScanner.java:208)
at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:741)
at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:925)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:113)
at jdk.compiler/com.sun.source.util.TreeScanner.visitClass(TreeScanner.java:189)
at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:549)
at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:832)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:113)
at jdk.compiler/com.sun.source.util.TreeScanner.visitCompilationUnit(TreeScanner.java:144)
at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:561)
at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:151)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:603)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:56)
at com.google.errorprone.scanner.Scanner.scan(Scanner.java:58)
at com.google.errorprone.scanner.ErrorProneScannerTransformer.apply(ErrorProneScannerTransformer.java:43)
at com.google.errorprone.ErrorProneAnalyzer.finished(ErrorProneAnalyzer.java:152)
at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:132)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1421)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1368)
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:960)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:147)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:74)
at org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:94)
at org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:55)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:40)
at org.gradle.api.internal.tasks.compile.daemon.AbstractDaemonCompiler$CompilerWorkAction.execute(AbstractDaemonCompiler.java:135)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:49)
at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:43)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:43)
at org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:32)
at org.gradle.workers.internal.FlatClassLoaderWorker.run(FlatClassLoaderWorker.java:22)
at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:85)
at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:55)
at org.gradle.process.internal.worker.request.WorkerAction$1.call(WorkerAction.java:138)
at org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41)
at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:135)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.AssertionError: case visitor is implemented in SwitchBuilder
at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.visitCase(CFGTranslationPhaseOne.java:2407)
at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.visitCase(CFGTranslationPhaseOne.java:193)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCase.accept(JCTree.java:1307)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.scan(CFGTranslationPhaseOne.java:491)
at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.scan(CFGTranslationPhaseOne.java:193)
at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:113)
at jdk.compiler/com.sun.source.util.TreeScanner.visitSwitchExpression(TreeScanner.java:348)
at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1338)
at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:56)
at org.checkerframework.nullaway.dataflow.cfg.builder.CFGTranslationPhaseOne.process(CFGTranslationPhaseOne.java:426)
at org.checkerframework.nullaway.dataflow.cfg.builder.CFGBuilder.build(CFGBuilder.java:91)
at com.uber.nullaway.dataflow.DataFlow$2.load(DataFlow.java:130)
at com.uber.nullaway.dataflow.DataFlow$2.load(DataFlow.java:97)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3533)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2282)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2159)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2049)
... 135 more
@lessthanoptimal oof that looks like a Checker Framework issue. Any chance you can reduce to a self-contained small-ish example with the same crash?
Also, if you add @SuppressWarnings("NullAway")
to the containing method or class, does the crash go away?
@msridhar Adding @SuppressWarnings("NullAway")
stopped it from crashing there.
I'll see if I can create a stand alone example. This particular project is fairly large. Not sure if this is relevant, but the switch expression is inside a lambda which is not typical in my use cases.
() -> switch (_configFundamental.errorModel) {
case SAMPSON -> new DistanceFromModelResidual<>(new FundamentalResidualSampson());
case GEOMETRIC -> new DistanceFundamentalGeometric();
});
Ok, thanks! I may be able to repro just based on your excerpt; will report back.
Managed to reproduce; opened #524 on it. While we work to fix, you'll have to use @SuppressWarnings("NullAway")
as a workaround. Hope that's ok for the time being; getting a full fix may take a few weeks given Checker Framework release cycle, and I'd rather not hold up the next NullAway release on that.
FYI our current switch expression support is now released in version 0.9.3
Support switch expressions, which are a preview feature in Java 12.
Currently, if I use a switch expression in my code, NullAway will throw an error during compilation. Removing NullAway from my
<annotationProcessorPaths>
and removing the NullAway-related compiler arguments makes the error go away.I've seen two kinds of errors so far.
Error 1: "java.lang.AssertionError: case visitor is implemented in SwitchBuilder"
Source code:
Output:
Error 2: "java.lang.RuntimeException: whoops, better handle SWITCH_EXPRESSION"
Source code:
Output: