typetools / typetools/checker-framework

Handling of non-canonical qualified types is unsound

Open
#1,857 1 comment 0 reactions 1 assignee View on GitHub

@wmdietl is already working on this.

Since Feb 27, 2018.

False Negative (missing warning or unsoundness)
Dominant language
Java
Stars
1.1k
Forks
440
Avg merge
1d 12h
Merged PRs (30d)
134

Description

In the following example, the canonical type of B<Object>.I is A<@Nullable Object>.I. javac's type annotation handling appears to emit type_paths for type annotations as they appears in the source type, which don't always correspond to the canonical type that appears in bytecide. For example, below there's a @NonNull annotation on the field i at location [TYPE_ARGUMENT(0)], which is correct for the non-canonical type B<Object>.I that appears in source and incorrect for the canonical type A<Object>.I that appears in bytecode.

I'm not sure that javac's behaviour here is desirable (see JDK-8198566).

import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.NonNull;

class A<@Nullable T> {
  class I {
    T f() {
      return null;
    }
  }
}

class B<@NonNull T> extends A<@Nullable Object> {
  static B<Object>.I i = new B<>().new I();

  public static void main(String[] args) {
    i.f().hashCode();
  }
}

The example compiles cleanly but results in an NPE at runtime:

./checker-framework-2.3.2/checker/bin/javac -processor Nullness T.java && java B
Exception in thread "main" java.lang.NullPointerException
        at B.main(T.java:16)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.