[Java] False Negative: Rule S2259 misses null dereference when using instanceof

Issue:

Rule S2259 (Null pointers should not be dereferenced) fails to detect null pointer dereferences when the null check is performed using instanceof instead of an explicit != null comparison.

Code to reproduce:

class Foo {
  private void foo1(String s1) {
      if (s1 != null) return;
      String str = s1.toString();  // S2259 reported ✓
  }
  
  private void foo2(String s2) {
      if (s2 instanceof String) return;
      String str = s2.toString();  // S2259 NOT reported ✗
  }
}

Expected behavior:
Both foo1() and foo2() should be reported with S2259, since both methods dereference a variable that is guaranteed to be null on some execution path.

Actual behavior:
SonarQube scan results:

[MAJOR] java:S2259: A "NullPointerException" could be thrown; "s1" is nullable here. at line 4

// Line 9 (foo2): NO S2259 report
[MAJOR] java:S1144: Remove this unused private "foo2" method. at line 7
[MINOR] java:S1481: Remove this unused "str" local variable. at line 9
[MINOR] java:S1858: "s2" is already a string, there's no need to call "toString()" on it. at line 9

Only foo1() is reported with S2259. foo2() is silently ignored.

Analysis:
When a variable x with static type T is checked using x instanceof T, this is semantically equivalent to a null check, since instanceof returns false for null values:

// When x has static type T:
x instanceof T ≡ x != null

Runtime verification:
Both methods throw NullPointerException when passed null:

public class Test {
    public static void main(String[] args) {
        try { new Foo().foo1(null); } 
        catch (NullPointerException e) { System.out.println("foo1 NPE!"); }
        
        try { new Foo().foo2(null); } 
        catch (NullPointerException e) { System.out.println("foo2 NPE!"); }
    }
}

Output:

foo1 NPE!
foo2 NPE!

Versions:

  • SonarQube Server: 26.1.0.118079 Community Build
  • Scanner: SonarScanner CLI 8.0.1.6346
  • Java Plugin: 8.22.0.41895
  • Java version: JDK 21

Deployment:
Deployed as a standalone server

Hi,

Welcome to the community!

In SonarQube Cloud and current versions of SonarQube Server, that rule has been moved to javabugs:S2259 and its performance improved. No further work is anticipated on the version of java:S2259 that remains in SonarQube Community Build.

Please let us know if you still see this once you upgrade.

 
HTH,
Ann