Search in sources :

Example 86 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class ParameterNullnessCheck method checkParameters.

private void checkParameters(Tree syntaxNode, Symbol symbol, Arguments arguments, ProgramState state) {
    if (!symbol.isMethodSymbol() || arguments.isEmpty()) {
        return;
    }
    JavaSymbol.MethodJavaSymbol methodSymbol = (JavaSymbol.MethodJavaSymbol) symbol;
    if (nonNullAnnotationOnParameters(methodSymbol) == null) {
        // method is not annotated (locally or globally)
        return;
    }
    int nbArguments = arguments.size();
    List<SymbolicValue> argumentSVs = getArgumentSVs(state, syntaxNode, nbArguments);
    List<JavaSymbol> argumentSymbols = methodSymbol.getParameters().scopeSymbols();
    int nbArgumentToCheck = Math.min(nbArguments, argumentSymbols.size() - (methodSymbol.isVarArgs() ? 1 : 0));
    for (int i = 0; i < nbArgumentToCheck; i++) {
        ObjectConstraint constraint = state.getConstraint(argumentSVs.get(i), ObjectConstraint.class);
        if (constraint != null && constraint.isNull() && !parameterIsNullable(methodSymbol, argumentSymbols.get(i))) {
            reportIssue(syntaxNode, arguments.get(i), methodSymbol);
        }
    }
}
Also used : JavaSymbol(org.sonar.java.resolve.JavaSymbol) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint)

Example 87 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class HappyPathYield method statesAfterInvocation.

@Override
public Stream<ProgramState> statesAfterInvocation(List<SymbolicValue> invocationArguments, List<Type> invocationTypes, ProgramState programState, Supplier<SymbolicValue> svSupplier) {
    Stream<ProgramState> results = parametersAfterInvocation(invocationArguments, invocationTypes, programState);
    // applied all constraints from parameters, stack return value
    SymbolicValue sv;
    if (resultIndex < 0 || resultIndex == invocationArguments.size()) {
        // if returnIndex is the size of invocationArguments : returning vararg parameter on a call with no elements specified
        sv = svSupplier.get();
    } else {
        // returned SV is the same as one of the arguments.
        sv = invocationArguments.get(resultIndex);
    }
    // sv can be null if method is void
    if (sv != null) {
        results = results.map(s -> s.stackValue(sv));
        if (resultConstraint != null) {
            results = results.map(s -> s.addConstraints(sv, resultConstraint));
        }
    }
    return results.distinct();
}
Also used : ProgramState(org.sonar.java.se.ProgramState) HashCodeBuilder(org.apache.commons.lang.builder.HashCodeBuilder) ExplodedGraph(org.sonar.java.se.ExplodedGraph) Type(org.sonar.plugins.java.api.semantic.Type) ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) Supplier(java.util.function.Supplier) Collectors(java.util.stream.Collectors) List(java.util.List) Stream(java.util.stream.Stream) EqualsBuilder(org.apache.commons.lang.builder.EqualsBuilder) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Constraint(org.sonar.java.se.constraint.Constraint) CheckForNull(javax.annotation.CheckForNull) Nullable(javax.annotation.Nullable) ProgramState(org.sonar.java.se.ProgramState) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue)

Example 88 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue 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)

Example 89 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class MethodBehavior method createYield.

public void createYield(ExplodedGraph.Node node, boolean storeNodeForReporting) {
    ExplodedGraph.Node nodeForYield = null;
    if (storeNodeForReporting) {
        nodeForYield = node;
    }
    MethodYield yield;
    boolean expectReturnValue = !(isConstructor() || isVoidMethod());
    SymbolicValue resultSV = node.programState.exitValue();
    if ((resultSV == null && expectReturnValue) || resultSV instanceof SymbolicValue.ExceptionalSymbolicValue) {
        ExceptionalYield exceptionalYield = new ExceptionalYield(nodeForYield, this);
        if (resultSV != null) {
            Type type = ((SymbolicValue.ExceptionalSymbolicValue) resultSV).exceptionType();
            String typeName = null;
            if (type != null) {
                typeName = type.fullyQualifiedName();
            }
            exceptionalYield.setExceptionType(typeName);
        }
        yield = exceptionalYield;
    } else {
        HappyPathYield happyPathYield = new HappyPathYield(nodeForYield, this);
        if (expectReturnValue) {
            ConstraintsByDomain cleanup = cleanup(node.programState.getConstraints(resultSV), org.objectweb.asm.Type.getReturnType(signature.substring(signature.indexOf('('))));
            if (cleanup.isEmpty()) {
                cleanup = null;
            }
            happyPathYield.setResult(parameters.indexOf(resultSV), cleanup);
        }
        yield = happyPathYield;
    }
    addParameterConstraints(node, yield);
    yields.add(yield);
}
Also used : ConstraintsByDomain(org.sonar.java.se.constraint.ConstraintsByDomain) ExplodedGraph(org.sonar.java.se.ExplodedGraph) Type(org.sonar.plugins.java.api.semantic.Type) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue)

Example 90 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class BytecodeEGWalkerExecuteTest method test_array_store.

@Test
public void test_array_store() throws Exception {
    int[] storeArrayOpcodes = new int[] { Opcodes.IASTORE, Opcodes.LASTORE, Opcodes.FASTORE, Opcodes.DASTORE, Opcodes.AASTORE, Opcodes.BASTORE, Opcodes.CASTORE, Opcodes.SASTORE };
    SymbolicValue array = new SymbolicValue();
    SymbolicValue index = new SymbolicValue();
    SymbolicValue value = new SymbolicValue();
    ProgramState initState = ProgramState.EMPTY_STATE.stackValue(array).stackValue(index).stackValue(value);
    for (int opcode : storeArrayOpcodes) {
        ProgramState ps = execute(new Instruction(opcode), initState);
        assertEmptyStack(ps);
    }
}
Also used : ProgramState(org.sonar.java.se.ProgramState) Instruction(org.sonar.java.bytecode.cfg.Instruction) BinarySymbolicValue(org.sonar.java.se.symbolicvalues.BinarySymbolicValue) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) TypedConstraint(org.sonar.java.se.constraint.TypedConstraint) Constraint(org.sonar.java.se.constraint.Constraint) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) ProgramPoint(org.sonar.java.se.ProgramPoint) Test(org.junit.Test)

Aggregations

SymbolicValue (org.sonar.java.se.symbolicvalues.SymbolicValue)132 RelationalSymbolicValue (org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)94 Test (org.junit.Test)79 ProgramState (org.sonar.java.se.ProgramState)74 BinarySymbolicValue (org.sonar.java.se.symbolicvalues.BinarySymbolicValue)55 Instruction (org.sonar.java.bytecode.cfg.Instruction)52 ObjectConstraint (org.sonar.java.se.constraint.ObjectConstraint)38 BooleanConstraint (org.sonar.java.se.constraint.BooleanConstraint)36 ProgramPoint (org.sonar.java.se.ProgramPoint)30 Constraint (org.sonar.java.se.constraint.Constraint)29 TypedConstraint (org.sonar.java.se.constraint.TypedConstraint)22 Type (org.sonar.plugins.java.api.semantic.Type)18 Symbol (org.sonar.plugins.java.api.semantic.Symbol)17 JavaSymbol (org.sonar.java.resolve.JavaSymbol)16 ConstraintsByDomain (org.sonar.java.se.constraint.ConstraintsByDomain)16 MethodInvocationTree (org.sonar.plugins.java.api.tree.MethodInvocationTree)15 List (java.util.List)13 Collectors (java.util.stream.Collectors)11 VisibleForTesting (com.google.common.annotations.VisibleForTesting)10 Lists (com.google.common.collect.Lists)10