use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class BytecodeEGWalkerTest method verify_behavior_of_fun2_method.
@Test
public void verify_behavior_of_fun2_method() throws Exception {
MethodBehavior methodBehavior = getMethodBehavior("fun2(Z)Ljava/lang/Object;");
assertThat(methodBehavior.yields()).hasSize(2);
SymbolicValue svFirstArg = new SymbolicValue();
SymbolicValue svResult = new SymbolicValue();
List<SymbolicValue> invocationArguments = Lists.newArrayList(svFirstArg);
List<HappyPathYield> oneYield = methodBehavior.happyPathYields().filter(my -> ObjectConstraint.NULL.equals(my.resultConstraint().get(ObjectConstraint.class))).collect(Collectors.toList());
assertThat(oneYield).hasSize(1);
HappyPathYield yield = oneYield.get(0);
Collection<ProgramState> pss = yield.statesAfterInvocation(invocationArguments, Lists.newArrayList(), ProgramState.EMPTY_STATE, () -> svResult).collect(Collectors.toList());
assertThat(pss).hasSize(1);
ProgramState ps = pss.iterator().next();
assertThat(ps.getConstraint(svFirstArg, ObjectConstraint.class)).isNull();
assertThat(ps.getConstraint(svFirstArg, BooleanConstraint.class)).isSameAs(BooleanConstraint.TRUE);
assertThat(ps.getConstraint(svFirstArg, DivisionByZeroCheck.ZeroConstraint.class)).isNull();
oneYield = methodBehavior.happyPathYields().filter(my -> ObjectConstraint.NOT_NULL.equals(my.resultConstraint().get(ObjectConstraint.class))).collect(Collectors.toList());
assertThat(oneYield).hasSize(1);
yield = oneYield.get(0);
pss = yield.statesAfterInvocation(invocationArguments, Lists.newArrayList(), ProgramState.EMPTY_STATE, () -> svResult).collect(Collectors.toList());
assertThat(pss).hasSize(1);
ps = pss.iterator().next();
assertThat(ps.getConstraint(svFirstArg, ObjectConstraint.class)).isNull();
assertThat(ps.getConstraint(svFirstArg, BooleanConstraint.class)).isSameAs(BooleanConstraint.FALSE);
assertThat(ps.getConstraint(svFirstArg, DivisionByZeroCheck.ZeroConstraint.class)).isNull();
}
use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class BytecodeEGWalkerTest method test_guava.
@Test
public void test_guava() throws Exception {
MethodBehavior methodBehavior = getMethodBehavior(ByteStreams.class, "read(Ljava/io/InputStream;[BII)I");
assertThat(methodBehavior.happyPathYields().anyMatch(y -> y.resultConstraint() == null)).isTrue();
}
use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class ExplodedGraphWalker method startingStates.
private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState currentState) {
Stream<ProgramState> stateStream = Stream.of(currentState);
boolean isEqualsMethod = EQUALS.matches(tree);
boolean nonNullParameters = isGloballyAnnotatedParameterNonNull(methodTree.symbol());
boolean nullableParameters = isGloballyAnnotatedParameterNullable(methodTree.symbol());
boolean hasMethodBehavior = methodBehavior != null;
for (final VariableTree variableTree : tree.parameters()) {
// create
final SymbolicValue sv = constraintManager.createSymbolicValue(variableTree);
Symbol variableSymbol = variableTree.symbol();
if (hasMethodBehavior) {
methodBehavior.addParameter(sv);
}
stateStream = stateStream.map(ps -> ps.put(variableSymbol, sv));
if (isEqualsMethod || parameterCanBeNull(variableSymbol, nullableParameters)) {
stateStream = stateStream.flatMap((ProgramState ps) -> Stream.concat(sv.setConstraint(ps, ObjectConstraint.NULL).stream(), sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream()));
} else if (nonNullParameters || isAnnotatedNonNull(variableSymbol)) {
stateStream = stateStream.flatMap(ps -> sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream());
}
}
return stateStream.collect(Collectors.toList());
}
use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class ExplodedGraphWalker method executeMethodInvocation.
private void executeMethodInvocation(MethodInvocationTree mit) {
setSymbolicValueOnFields(mit);
// unstack arguments and method identifier
ProgramState.Pop unstack = programState.unstackValue(mit.arguments().size() + 1);
logState(mit);
programState = unstack.state;
// get method behavior for method with known declaration (ie: within the same file)
MethodBehavior methodInvokedBehavior = null;
Symbol methodSymbol = mit.symbol();
if (methodSymbol.isMethodSymbol()) {
methodInvokedBehavior = behaviorCache.get((Symbol.MethodSymbol) methodSymbol);
}
// Enqueue additional exceptional paths corresponding to unchecked exceptions, for instance OutOfMemoryError
enqueueUncheckedExceptionalPaths(methodSymbol);
final SymbolicValue resultValue = constraintManager.createMethodSymbolicValue(mit, unstack.valuesAndSymbols);
if (methodInvokedBehavior != null && methodInvokedBehavior.isComplete() && !EQUALS_METHODS.anyMatch(mit)) {
List<SymbolicValue> invocationArguments = invocationArguments(unstack.values);
List<Type> invocationTypes = mit.arguments().stream().map(ExpressionTree::symbolType).collect(Collectors.toList());
Map<Type, SymbolicValue.ExceptionalSymbolicValue> thrownExceptionsByExceptionType = new HashMap<>();
// Enqueue exceptional paths from exceptional yields
methodInvokedBehavior.exceptionalPathYields().forEach(yield -> yield.statesAfterInvocation(invocationArguments, invocationTypes, programState, () -> thrownExceptionsByExceptionType.computeIfAbsent(yield.exceptionType(semanticModel), constraintManager::createExceptionalSymbolicValue)).forEach(psYield -> enqueueExceptionalPaths(psYield, methodSymbol, yield)));
// Enqueue happy paths
methodInvokedBehavior.happyPathYields().forEach(yield -> yield.statesAfterInvocation(invocationArguments, invocationTypes, programState, () -> resultValue).map(psYield -> handleSpecialMethods(psYield, mit)).forEach(psYield -> enqueueHappyPath(psYield, mit, yield)));
} else {
// Enqueue exceptional paths from thrown exceptions
enqueueThrownExceptionalPaths(methodSymbol);
// Enqueue happy paths
programState = handleSpecialMethods(programState.stackValue(resultValue), mit);
checkerDispatcher.executeCheckPostStatement(mit);
clearStack(mit);
}
}
use of org.sonar.java.se.xproc.MethodBehavior in project sonar-java by SonarSource.
the class SymbolicExecutionVisitor method execute.
public void execute(MethodTree methodTree) {
ExplodedGraphWalker walker = getWalker();
try {
Symbol.MethodSymbol methodSymbol = methodTree.symbol();
if (methodCanNotBeOverriden(methodSymbol)) {
MethodBehavior methodBehavior = behaviorCache.methodBehaviorForSymbol(methodSymbol);
if (!methodBehavior.isVisited()) {
methodBehavior = walker.visitMethod(methodTree, methodBehavior);
methodBehavior.completed();
}
} else {
walker.visitMethod(methodTree);
}
} catch (ExplodedGraphWalker.MaximumStepsReachedException | ExplodedGraphWalker.ExplodedGraphTooBigException exception) {
LOG.debug("Could not complete symbolic execution: ", exception);
if (walker.methodBehavior != null) {
walker.methodBehavior.visited();
}
}
}
Aggregations