Search in sources :

Example 11 with ConstraintsByDomain

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;
        }
    }
}
Also used : ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue)

Example 12 with ConstraintsByDomain

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;
}
Also used : ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) Constraint(org.sonar.java.se.constraint.Constraint) ArrayList(java.util.ArrayList) ProgramState(org.sonar.java.se.ProgramState)

Example 13 with ConstraintsByDomain

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>"));
}
Also used : ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) Type(org.sonar.plugins.java.api.semantic.Type) Constraint(org.sonar.java.se.constraint.Constraint)

Example 14 with ConstraintsByDomain

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;
}
Also used : ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) Constraint(org.sonar.java.se.constraint.Constraint)

Example 15 with ConstraintsByDomain

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();
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) ProgramState(org.sonar.java.se.ProgramState) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) Constraint(org.sonar.java.se.constraint.Constraint)

Aggregations

ConstraintsByDomain (org.sonar.java.se.constraint.ConstraintsByDomain)20 SymbolicValue (org.sonar.java.se.symbolicvalues.SymbolicValue)12 BooleanConstraint (org.sonar.java.se.constraint.BooleanConstraint)9 ProgramState (org.sonar.java.se.ProgramState)8 Test (org.junit.Test)7 ProgramPoint (org.sonar.java.se.ProgramPoint)6 Instruction (org.sonar.java.bytecode.cfg.Instruction)5 ZeroConstraint (org.sonar.java.se.checks.DivisionByZeroCheck.ZeroConstraint)5 Constraint (org.sonar.java.se.constraint.Constraint)5 ObjectConstraint (org.sonar.java.se.constraint.ObjectConstraint)4 RelationalSymbolicValue (org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)3 Type (org.sonar.plugins.java.api.semantic.Type)3 ArrayList (java.util.ArrayList)2 TypedConstraint (org.sonar.java.se.constraint.TypedConstraint)2 BinarySymbolicValue (org.sonar.java.se.symbolicvalues.BinarySymbolicValue)2 LinkedHashSet (java.util.LinkedHashSet)1 BiConsumer (java.util.function.BiConsumer)1 PMap (org.sonar.java.collections.PMap)1 ExplodedGraph (org.sonar.java.se.ExplodedGraph)1 SETestUtils.getMethodBehavior (org.sonar.java.se.SETestUtils.getMethodBehavior)1