Skip to content

Unhandled NullPointerException with intersection bounds on generic field #1377

@HildingLinden

Description

@HildingLinden

Using NullAway 0.12.14 in JSpecify mode we encountered the following unhandled NullPointerException:

NullAwayNPEReproduction\src\main\java\org\example\Main.java:15: error: An unhandled exception was thrown by the Error Prone static analysis plugin.
        instance.method();
                       ^
     Please report this at https://github.com/google/error-prone/issues/new and include the following, as well as a reproducing code sample (if possible):
  
     error-prone version: 2.43.0
     BugPattern: NullAway
     Stack Trace:
     java.lang.NullPointerException: Cannot invoke "com.sun.tools.javac.code.Type.hasTag(com.sun.tools.javac.code.TypeTag)" because "t" is null
        at jdk.compiler/com.sun.tools.javac.code.Types.capture(Types.java:4398)
        at jdk.compiler/com.sun.tools.javac.code.Types$13.visitClassType(Types.java:2317)
        at jdk.compiler/com.sun.tools.javac.code.Types$13.visitClassType(Types.java:2297)
        at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1050)
        at jdk.compiler/com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:4909)
        at jdk.compiler/com.sun.tools.javac.code.Types.memberType(Types.java:2294)
        at jdk.compiler/com.sun.tools.javac.code.Types$13.visitTypeVar(Types.java:2336)
        at jdk.compiler/com.sun.tools.javac.code.Types$13.visitTypeVar(Types.java:2297)
        at jdk.compiler/com.sun.tools.javac.code.Type$TypeVar.accept(Type.java:1705)
        at jdk.compiler/com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:4909)
        at jdk.compiler/com.sun.tools.javac.code.Types.memberType(Types.java:2294)
        at com.uber.nullaway.generics.TypeSubstitutionUtils.memberType(TypeSubstitutionUtils.java:66)
        at com.uber.nullaway.generics.GenericsChecks.compareGenericTypeParameterNullabilityForCall(GenericsChecks.java:1224)
        at com.uber.nullaway.NullAway.handleInvocation(NullAway.java:2003)
        at com.uber.nullaway.NullAway.matchMethodInvocation(NullAway.java:444)
        at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:509)
        at com.google.errorprone.scanner.ErrorProneScanner.visitMethodInvocation(ErrorProneScanner.java:824)
        at com.google.errorprone.scanner.ErrorProneScanner.visitMethodInvocation(ErrorProneScanner.java:170)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1832)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        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:503)
        at com.google.errorprone.scanner.ErrorProneScanner.visitExpressionStatement(ErrorProneScanner.java:711)
        at com.google.errorprone.scanner.ErrorProneScanner.visitExpressionStatement(ErrorProneScanner.java:170)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCExpressionStatement.accept(JCTree.java:1611)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        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:111)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:272)
        at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:591)
        at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:170)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1104)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        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:96)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitMethod(TreeScanner.java:224)
        at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:818)
        at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:170)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:948)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        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:96)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:111)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:119)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitClass(TreeScanner.java:203)
        at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:619)
        at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:170)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:855)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:92)
        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:96)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:111)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:119)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitCompilationUnit(TreeScanner.java:152)
        at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:631)
        at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:170)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:623)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:66)
        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:231)
        at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:133)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1443)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1390)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:963)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
        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:92)
        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:83)
        at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:50)
        at org.gradle.api.internal.tasks.compile.daemon.AbstractIsolatedCompilerWorkerExecutor$CompilerWorkAction.execute(AbstractIsolatedCompilerWorkerExecutor.java:78)
        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
        at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:54)
        at org.gradle.workers.internal.AbstractClassLoaderWorker$1.create(AbstractClassLoaderWorker.java:48)
        at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:100)
        at org.gradle.workers.internal.AbstractClassLoaderWorker.executeInClassLoader(AbstractClassLoaderWorker.java:48)
        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:108)
        at org.gradle.workers.internal.WorkerDaemonServer.run(WorkerDaemonServer.java:77)
        at org.gradle.process.internal.worker.request.WorkerAction.lambda$run$1(WorkerAction.java:150)
        at org.gradle.process.internal.worker.child.WorkerLogEventListener.withWorkerLoggingProtocol(WorkerLogEventListener.java:41)
        at org.gradle.process.internal.worker.request.WorkerAction.lambda$run$2(WorkerAction.java:150)
        at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:85)
        at org.gradle.process.internal.worker.request.WorkerAction.run(WorkerAction.java:142)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
        at java.base/java.lang.reflect.Method.invoke(Method.java:580)
        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.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:48)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
        at java.base/java.lang.Thread.run(Thread.java:1570)

Example that reproduces the exception.
Main.java:

package org.example;

interface Marker {}

class Generic<T> {
    public void method() {}
}

class Base<T extends Object & Marker> {
    T instance;
}

class SubClass<T extends Generic<Integer> & Marker> extends Base<T> {
    void method() {
        instance.method();
    }
}

build.gradle:

plugins {
    id 'java'
    id 'net.ltgt.errorprone' version '4.3.0'
}

repositories {
    mavenCentral()
}

dependencies {
    errorprone 'com.uber.nullaway:nullaway:0.12.14'
    errorprone 'com.google.errorprone:error_prone_core:2.43.0'
}

tasks.withType(JavaCompile) {
    options.errorprone {
        disableAllChecks = true
        enable('NullAway')
        option('NullAway:AnnotatedPackages', 'org.example')
        option('NullAway:JSpecifyMode', true)
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions