This seems to be a new example of a false positive of the rule "Conditionally executed blocks should be reachable" (squid:S2583). Does anyone know why SonarQube claims that if(this.x == 0)
always evaluates to false
in the following Java class?
public class MyClass {
private long x;
void setX(long x) {
this.x = x;
}
public void decrementX() {
if(this.x > 0) {
this.x--;
if(this.x == 0) { // <-- Always false?!
// apparently dead code
}
}
}
}
Clearly the variable x
can be set to 1
and then decrementX()
will get into that exact condition:
@Test
public void testDecrement() {
MyClass c = new MyClass();
c.setX(1);
c.decrementX();
}
(executed on SonarQube server 5.6.6 with SonarJava plugin 4.13.0.11627)
Update: as noted by Absurd-Mind, SonarQube is happy when this.x
is shortened to x
. In my opinion, this is a false-positive.
This is indeed a False Positive (FP) raised by version 4.13.0.11627 of the SonarJava plugin.
After investigation, the FP is caused by a bug in handling of unary operators in our Symbolic Execution (SE) engine. The following ticket will fix the issue: SONARJAVA-2460 (expected fix version: 4.14)
For details about WHY the issue is occurring: Class fields, when accessed using this.x
or super.x
, are not handled as they should be. They are currently purely and simply ignored (will be fixed by the JIRA ticket). It has for side effect that update of the field occurring with this.x--
is not registered by the SE engine: the symbolic value associated to symbol x
is not updated. Consequently, when test x == 0
is done, the only thing that the engine knows at this time is the (wrong) constraint that x > 0
. In such state, the condition will always be false. Fixing the issue will allow the engine to know that the x
tested in the condition is not the same anymore as the one used for checking x > 0
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With