Product: SonarQube Community Build 26.5.0.122743
sonar-java version: sonar-java 8.29 (build 43460)
sonar-java SE version: sonar-java-symbolic-execution 8.16.4 (build 1912)
Java source level: 21 (javac 21, source/target 21)
Rule
S2189 - Loops should not be infinite
Description
There is an inconsistency in how rule java:S2189 handles infinite for loops.
When a for loop has no condition expression (which implicitly evaluates to true), the rule correctly raises an issue. However, when the condition is explicitly set to true, and the update expression contains a method call, the rule fails to detect the infinite loop (False Negative).
Logically, both cases are identical infinite loops without any break, return, or throw statements, so they should exhibit the same analysis results.
Reproducer
public class LoopInconsistency {
// Case A: NO finding (False Negative)
void loopWithExplicitTrue() {
for (Object o = getNext(); true; o = getNext()) {
String s = (String) o;
}
}
// Case B: S2189 fired (Correct)
void loopWithEmptyCondition() {
for (Object o = getNext(); ; o = getNext()) {
String s = (String) o;
}
}
Object getNext() {
return null;
}
}
Expected behavior
Both loopWithExplicitTrue and loopWithEmptyCondition should trigger a java:S2189 warning because both are infinite loops that cannot terminate normally.
Actual behavior
loopWithEmptyConditiontriggersjava:S2189as expected.loopWithExplicitTruedoes not trigger any issue. It seems the Symbolic Execution engine becomes overly conservative when an explicittruecondition is paired with a method call in the loop update expression, potentially fearing side-effects or exceptions that are not actually handling the loop termination.