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);
}
}
}
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();
}
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();
}
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);
}
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);
}
}
Aggregations