S2589 field value not properly read in nested for loops

  • What language is this for?
    Java
  • Which rule?
    S2589
  • Why do you believe it’s a false-positive/false-negative?
    Because the output in from an allegedly unreachable branch was reached.
  • Are you using
    • SonarLint - which IDE/version?
      Yes, 7.4.0.60471
      • in connected mode with SonarQube or SonarCloud?
        No
  • How can we reproduce the problem? Give us a self-contained snippet of code (formatted text, no screenshots)

The Problem:

In the disjunction in line 7 the second term (j == 0) is always marked as

Remove this expression which always evaluates to “true”

The false-positive still occurs, when the value from FOO is assigned inside the ctor. When rewriting the disjunction with de-morgan to !(i != 0 && j != 0) it is still being marked as always true. And when changing the type from FOO to Integer it also still occurs.

But vanishes, when the declaration for FOO is inlined into the ctor, or the upper bounds of any of the two for-loops are altered (funny, that even appending + 1 - 1 to FOO in any of the loop declarations is fixing this issue as well :rofl:).

public class Main {
    private final int FOO = 2;

    public Main() {
        for (int i = 0; i < FOO; i++)
            for (int j = 0; j < FOO; j++)
                if (i == 0 || j == 0) System.out.printf("i: %d, j: %d\n", i, j);
                else System.out.printf("SHOULD NEVER PRINT!! i: %d, j: %d\n", i, j);
    }

    public static void main(String[] args) {
        new Main();
    }
}

Output, when ran with temurin-17.0.6:

i: 0, j: 0
i: 0, j: 1
i: 1, j: 0
SHOULD NEVER PRINT!! i: 1, j: 1

Process finished with exit code 0

Note: when swapping i== 0 with j == 0 then i == 0 is being marked as always true instead.

There could be a connection to [SONARJAVA-2523] - Jira

Hi Valerij, thank you for you report!

This is unfortunately a known issue, also a complex one, of the engine that we use to detect if a condition can or cannot ever evaluate to different values.
There is an open ticket here if you want to follow its progress. I will link this post there and hopefully we will be able to fix this problem in the future!

Leonardo