typetools / checker-framework

Pluggable type-checking for Java
http://checkerframework.org/
Other
1.02k stars 354 forks source link

Refined types in loops should not be cached #602

Open smillst opened 8 years ago

smillst commented 8 years ago

Because the qualified types of some expressions are cached, the code below does not issue a warning that it should.

class Loop {
    @PolyNull String id(@PolyNull String o) {
        return o;
    }
    void loop(boolean condition) {
        @NonNull String notNull = "hello";
        String nullable = "";
        while (condition) {
            notNull = nullable;  // error, the type of nullable is not cached.
            notNull = id(nullable); // no error, the type of id(nullable) is cached.
            nullable = null;
        }
    }
}

When data flow analyzes the code in the loop for the first time, the type of nullable is @NonNull, so the type of id(nullable) is also @NonNull. This type is cached in the AnnotatedTypeFactory and then used on subsequent data flow passes and also when type checking.

Caching should be turned off when data flow is analyzing code in a loop.

smillst commented 8 years ago

Fixing this issue will fix the todo in framework/tests/value/rRepo.java

smillst commented 8 years ago

Turing off caching in dataflow with the body of a loop is tricky because data flow works on CGFs which do not contain information about whether an expression is in the body of a loop. So, instead of turning off caching only during loops, we will start by turning off caching during dataflow.

Implementation plan:

  1. Cache all expressions in method bodies
  2. Turn off caching during data flow.