I use SonarLint for Eclipse v4.0.0.201810170711.
With the following sample code (simplified from my actual code) I get a false positive with the message Change this condition so that it does not always evaluate to “false” (squid S2583).
public static void main(String[] args) {
Random random = new Random();
boolean flag1 = random.nextBoolean();
boolean flag2 = false;
int c = random.nextInt();
while (true) {
if (random.nextBoolean()) {
if (flag2 && c == 5) { // here I get the linter warning 'Change this condition so that it does not always evaluate to "false"'
flag1 = false;
}
} else {
flag2 = true;
if (!flag1 && !random.nextBoolean()) {
return;
}
}
c = random.nextInt();
}
}
I do not see what causes SonarJava to think that flag2 is always false - it seems like it does not see the while loop around the condition.
Even if you have a why looping around the condition, random.nextBoolean() will always be true and the flag2 will never be set to true as it is initialised with a false value.
Then maybe c will be 5 at some point but flag2 will remain false.
random.nextBoolean is randomly true or false - I don’t get why it should always be true. Am I missing something here?
(BTW, my original code does not contain randomBoolean, this was only used to reproduce the issue).
This limitation is very likely due to the nested ifs that are in your while loop and the way the current symbolic execution engine deals with loops.
Roughly, the engine will stop going in the loop when exploring 3 times the same state of the program at the same location and I believe (but did not verify) this happens before it has a chance to update flag2 to true.
There is no real workaround besides marking the issue as false positive.
We are currently working on implementing a better dataflow analysis because of such limitations of the engine, but we do not really have a timeframe to communicate.
The rule does not account for the for loop during which the variable can very well be assigned the true value.
Version is SonarQube LTS 8.9 with latest SonarJava Ruleset