use of org.sonar.java.bytecode.cfg.Instruction in project sonar-java by SonarSource.
the class BytecodeEGWalkerExecuteTest method test_getfield.
@Test
public void test_getfield() throws Exception {
SymbolicValue objectRef = new SymbolicValue();
ProgramState programState = execute(new Instruction(Opcodes.GETFIELD, new Instruction.FieldOrMethod("", "", "D", false)), ProgramState.EMPTY_STATE.stackValue(objectRef));
SymbolicValue fieldValue = programState.peekValue();
assertThat(fieldValue).isNotNull();
assertThat(isDoubleOrLong(programState, fieldValue)).isTrue();
assertThat(fieldValue).isNotEqualTo(objectRef);
programState = execute(new Instruction(Opcodes.GETFIELD, new Instruction.FieldOrMethod("", "", "I", false)), ProgramState.EMPTY_STATE.stackValue(objectRef));
fieldValue = programState.peekValue();
assertThat(fieldValue).isNotNull();
assertThat(isDoubleOrLong(programState, fieldValue)).isFalse();
assertThatThrownBy(() -> execute(new Instruction(Opcodes.GETFIELD))).hasMessage("GETFIELD needs 1 values on stack");
}
use of org.sonar.java.bytecode.cfg.Instruction in project sonar-java by SonarSource.
the class BytecodeEGWalkerExecuteTest method test_compare_instructions.
@Test
public void test_compare_instructions() {
int[] opcodes = { Opcodes.IF_ICMPEQ, Opcodes.IF_ICMPNE, Opcodes.IF_ICMPLT, Opcodes.IF_ICMPGE, Opcodes.IF_ACMPEQ, Opcodes.IF_ACMPNE };
SymbolicValue left = new SymbolicValue();
SymbolicValue right = new SymbolicValue();
for (int opcode : opcodes) {
ProgramState programState = walker.branchingState(new Instruction(opcode), ProgramState.EMPTY_STATE.stackValue(left).stackValue(right));
RelationalSymbolicValue relSV = (RelationalSymbolicValue) programState.peekValue();
assertThat(relSV.getLeftOp()).isSameAs(left);
assertThat(relSV.getRightOp()).isSameAs(right);
}
// these opcodes inverse operator and swap operands
int[] swapOperandsOpcodes = { Opcodes.IF_ICMPLE, Opcodes.IF_ICMPGT };
for (int opcode : swapOperandsOpcodes) {
ProgramState programState = walker.branchingState(new Instruction(opcode), ProgramState.EMPTY_STATE.stackValue(left).stackValue(right));
RelationalSymbolicValue relSV = (RelationalSymbolicValue) programState.peekValue();
assertThat(relSV.getRightOp()).isSameAs(left);
assertThat(relSV.getLeftOp()).isSameAs(right);
}
}
use of org.sonar.java.bytecode.cfg.Instruction in project sonar-java by SonarSource.
the class BytecodeEGWalkerExecuteTest method test_athrow.
@Test
public void test_athrow() throws Exception {
SymbolicValue sv = new SymbolicValue();
Type exceptionType = semanticModel.getClassType("java.lang.RuntimeException");
ProgramState initialState = ProgramState.EMPTY_STATE.stackValue(sv).addConstraint(sv, new TypedConstraint("java.lang.RuntimeException"));
ProgramState programState = execute(new Instruction(Opcodes.ATHROW), initialState);
SymbolicValue exception = programState.peekValue();
assertThat(exception).isInstanceOf(SymbolicValue.ExceptionalSymbolicValue.class);
assertThat(((SymbolicValue.ExceptionalSymbolicValue) exception).exceptionType()).isEqualTo(exceptionType);
assertThat(programState.exitValue()).isEqualTo(exception);
}
use of org.sonar.java.bytecode.cfg.Instruction in project sonar-java by SonarSource.
the class BytecodeEGWalker method handleBlockExit.
@VisibleForTesting
void handleBlockExit(ProgramPoint programPosition) {
BytecodeCFG.Block block = (BytecodeCFG.Block) programPosition.block;
Instruction terminator = block.terminator();
if (terminator == null) {
enqueueHappyPath(programPosition);
return;
}
switch(terminator.opcode) {
case GOTO:
enqueueHappyPath(programPosition);
break;
case TABLESWITCH:
case LOOKUPSWITCH:
programState = programState.unstackValue(1).state;
enqueueHappyPath(programPosition);
break;
default:
handleBranching(terminator);
}
}
use of org.sonar.java.bytecode.cfg.Instruction in project sonar-java by SonarSource.
the class BytecodeEGWalker method branchingState.
@VisibleForTesting
ProgramState branchingState(Instruction terminator, ProgramState programState) {
ProgramState.Pop pop;
ProgramState ps;
List<ProgramState.SymbolicValueSymbol> symbolicValueSymbols;
switch(terminator.opcode) {
case IFEQ:
case IFNE:
case IFLT:
case IFGE:
case IFGT:
case IFLE:
pop = programState.unstackValue(1);
SymbolicValue svZero = new SymbolicValue();
symbolicValueSymbols = ImmutableList.of(new ProgramState.SymbolicValueSymbol(svZero, null), pop.valuesAndSymbols.get(0));
List<ProgramState> programStates = svZero.setConstraint(pop.state, DivisionByZeroCheck.ZeroConstraint.ZERO).stream().flatMap(s -> svZero.setConstraint(s, BooleanConstraint.FALSE).stream()).collect(Collectors.toList());
Preconditions.checkState(programStates.size() == 1);
ps = programStates.get(0);
break;
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
case IF_ACMPEQ:
case IF_ACMPNE:
pop = programState.unstackValue(2);
symbolicValueSymbols = pop.valuesAndSymbols;
ps = pop.state;
break;
case IFNULL:
case IFNONNULL:
pop = programState.unstackValue(1);
symbolicValueSymbols = ImmutableList.of(new ProgramState.SymbolicValueSymbol(SymbolicValue.NULL_LITERAL, null), pop.valuesAndSymbols.get(0));
ps = pop.state;
break;
default:
throw new IllegalStateException("Unexpected terminator " + terminator);
}
return ps.stackValue(constraintManager.createBinarySymbolicValue(terminator, symbolicValueSymbols));
}
Aggregations