Skip to content

Commit

Permalink
SONARJAVA-1988 Handle properly unset constraint on wrapped sv
Browse files Browse the repository at this point in the history
  • Loading branch information
benzonico committed Dec 6, 2016
1 parent 1102012 commit b7486ef
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package org.sonar.java.se.checks;

import com.google.common.collect.ImmutableList;

import org.sonar.check.Rule;
import org.sonar.java.matcher.MethodMatcher;
import org.sonar.java.se.CheckerContext;
Expand Down Expand Up @@ -66,7 +65,11 @@ public OptionalSymbolicValue(int id, SymbolicValue sv) {
@Override
public List<ProgramState> setConstraint(ProgramState programState, BooleanConstraint booleanConstraint) {
ObjectConstraint optionalConstraint = (ObjectConstraint) programState.getConstraint(optionalSV);
if (optionalConstraint == null || isImpossibleState(booleanConstraint, optionalConstraint)) {
if(optionalConstraint == null) {
// Constraint on the optional SV might have been disposed. But is is necessarily non null because NPE check is ran before.
optionalConstraint = ObjectConstraint.NOT_NULL;
}
if (isImpossibleState(booleanConstraint, optionalConstraint)) {
return ImmutableList.of();
}
if (optionalConstraint.hasStatus(Status.NOT_PRESENT) || optionalConstraint.hasStatus(Status.PRESENT)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import java.util.Optional;

public class Squid2583 {

private boolean isSpecial(MyObject obj) {
return obj.getMyString().contains("B") && noEmptyNodeNames(obj) && foo(); // FP might be raised here because of optional in noEmptyNodeName method
}

private boolean noEmptyNodeNames(MyObject obj) {
return obj.getValueOne().isPresent() && obj.getValueTwo().isPresent(); // constraint cleanup can cause absence of yields which can lead to FP.
}

public static final class MyObject {
private String myString;
private final Optional<String> valueOne;
private final Optional<String> valueTwo;

public MyObject() {
}

public String getMyString() {
return myString;
}

public Optional<String> getValueOne() {
return valueOne;
}

public Optional<String> getValueTwo() {
return valueTwo;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ public void test() {
JavaCheckVerifier.verify("src/test/files/se/ConditionAlwaysTrueOrFalseCheck.java", new ConditionAlwaysTrueOrFalseCheck());
}

@Test
public void condition_always_true_with_optional() {
JavaCheckVerifier.verifyNoIssue("src/test/files/se/ConditionAlwaysTrueWithOptional.java", new ConditionAlwaysTrueOrFalseCheck());
}

@Test
public void resetFields_ThreadSleepCalls() throws Exception {
JavaCheckVerifier.verifyNoIssue("src/test/files/se/ThreadSleepCall.java", new ConditionAlwaysTrueOrFalseCheck());
Expand Down

0 comments on commit b7486ef

Please sign in to comment.