use of org.sonar.java.se.constraint.ConstraintsByDomain in project sonar-java by SonarSource.
the class InvariantReturnCheck method checkEndOfExecutionPath.
@Override
public void checkEndOfExecutionPath(CheckerContext context, ConstraintManager constraintManager) {
if (context.getState().exitingOnRuntimeException()) {
return;
}
MethodInvariantContext methodInvariantContext = methodInvariantContexts.peek();
if (!methodInvariantContext.methodToCheck) {
return;
}
SymbolicValue exitValue = context.getState().exitValue();
if (exitValue != null) {
methodInvariantContext.endPaths++;
methodInvariantContext.symbolicValues.add(exitValue);
ConstraintsByDomain constraints = context.getState().getConstraints(exitValue);
if (constraints != null) {
constraints.forEach(methodInvariantContext.methodConstraints::put);
} else {
// Relational SV or NOT SV : we can't say anything.
methodInvariantContext.avoidRaisingConstraintIssue = true;
}
}
}
use of org.sonar.java.se.constraint.ConstraintsByDomain in project sonar-java by SonarSource.
the class RelationalSymbolicValue method copyConstraintFromTo.
private List<ProgramState> copyConstraintFromTo(SymbolicValue from, SymbolicValue to, ProgramState programState, Set<RelationalSymbolicValue> knownRelations) {
List<ProgramState> states = new ArrayList<>();
states.add(programState);
ConstraintsByDomain leftConstraints = programState.getConstraints(from);
if (leftConstraints == null) {
return states;
}
leftConstraints.forEach((d, c) -> {
Constraint constraint = c.copyOver(kind);
if (constraint != null) {
List<ProgramState> newStates = applyConstraint(constraint, to, states, knownRelations);
states.clear();
states.addAll(newStates);
}
});
return states;
}
use of org.sonar.java.se.constraint.ConstraintsByDomain in project sonar-java by SonarSource.
the class ExceptionalCheckBasedYield method applicableOnVarArgs.
private boolean applicableOnVarArgs(List<Type> invocationTypes) {
int numberParametersYield = parametersConstraints.size();
int numberArgumentsInCall = invocationTypes.size();
if (numberParametersYield > numberArgumentsInCall) {
// VarArgs method called without variadic parameter
return true;
}
ConstraintsByDomain lastParamConstraint = parametersConstraints.get(numberParametersYield - 1);
if (lastParamConstraint.isEmpty()) {
// no constraint on the last parameter on yield side
return true;
}
if (numberParametersYield != numberArgumentsInCall) {
// there is a constraint on last parameter, but varArgs method called with multiple arguments in variadic part
return false;
}
// compatible number of parameters, type must be compatible on arguments side
Type lastArgumentType = invocationTypes.get(numberArgumentsInCall - 1);
return !isMethodVarargs || (lastArgumentType.isArray() || lastArgumentType.is("<nulltype>"));
}
use of org.sonar.java.se.constraint.ConstraintsByDomain in project sonar-java by SonarSource.
the class ExceptionalCheckBasedYield method parameterConstraintsMatchExactly.
private boolean parameterConstraintsMatchExactly(List<SymbolicValue> invocationArguments, List<Type> invocationTypes, ProgramState programState) {
if (!applicableOnVarArgs(invocationTypes)) {
// VarArgs method invoked with the last parameter being not an array, but an item which will be wrapped in the array
return false;
}
for (int index = 0; index < parametersConstraints.size(); index++) {
ConstraintsByDomain yieldConstraint = parametersConstraints.get(index);
ConstraintsByDomain stateConstraint = argumentConstraint(invocationArguments, programState, index);
if (!yieldConstraint.isEmpty() && !yieldConstraint.equals(stateConstraint)) {
// in order to avoid wrongly learning from this yield and thus raising FPs.
return false;
}
}
return true;
}
use of org.sonar.java.se.constraint.ConstraintsByDomain in project sonar-java by SonarSource.
the class MethodYield method parametersAfterInvocation.
public Stream<ProgramState> parametersAfterInvocation(List<SymbolicValue> invocationArguments, List<Type> invocationTypes, ProgramState programState) {
Set<ProgramState> results = new LinkedHashSet<>();
for (int index = 0; index < invocationArguments.size(); index++) {
ConstraintsByDomain constraints = getConstraint(index, invocationTypes);
if (constraints == null) {
// no constraints on this parameter, let's try next one.
continue;
}
SymbolicValue invokedArg = invocationArguments.get(index);
Set<ProgramState> programStates = programStatesForConstraint(results.isEmpty() ? Lists.newArrayList(programState) : results, invokedArg, constraints);
if (programStates.isEmpty()) {
// TODO there might be some issue to report in this case.
return Stream.empty();
}
results = programStates;
}
// That means that this yield is still possible and we need to stack a returned SV with its eventual constraints.
if (results.isEmpty()) {
results.add(programState);
}
return results.stream();
}
Aggregations