use of org.sonar.java.bytecode.cfg.BytecodeCFG in project sonar-java by SonarSource.
the class BytecodeEGWalkerExecuteTest method test_tableswitch.
@Test
public void test_tableswitch() throws Exception {
Instructions instr = new Instructions();
instr.visitVarInsn(ILOAD, 0);
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
Label l3 = new Label();
instr.visitTableSwitchInsn(0, 2, l3, new Label[] { l0, l1, l2 });
instr.visitLabel(l0);
instr.visitInsn(ICONST_0);
instr.visitVarInsn(ISTORE, 1);
instr.visitJumpInsn(GOTO, l3);
instr.visitLabel(l1);
instr.visitInsn(ICONST_0);
instr.visitVarInsn(ISTORE, 2);
instr.visitJumpInsn(GOTO, l3);
instr.visitLabel(l2);
instr.visitInsn(ICONST_0);
instr.visitVarInsn(ISTORE, 3);
instr.visitLabel(l3);
instr.visitInsn(RETURN);
BytecodeCFG cfg = instr.cfg();
CFG.IBlock<Instruction> entry = cfg.entry();
BytecodeEGWalker walker = new BytecodeEGWalker(null, null);
walker.programState = ProgramState.EMPTY_STATE.stackValue(new SymbolicValue());
walker.handleBlockExit(new ProgramPoint(entry));
assertThat(walker.workList).hasSize(entry.successors().size());
walker.workList.forEach(node -> {
assertThat(node.programState.peekValue()).isNull();
assertThat(entry.successors().contains(node.programPoint.block)).isTrue();
});
}
use of org.sonar.java.bytecode.cfg.BytecodeCFG in project sonar-java by SonarSource.
the class BytecodeEGWalkerExecuteTest method test_enqueuing_exceptional_yields.
@Test
public void test_enqueuing_exceptional_yields() {
BytecodeCFG cfg = SETestUtils.bytecodeCFG(TRY_CATCH_SIGNATURE, squidClassLoader);
BytecodeCFG.Block b2 = cfg.blocks().get(2);
walker.programState = ProgramState.EMPTY_STATE.stackValue(new SymbolicValue()).stackValue(new SymbolicValue());
walker.programPosition = new ProgramPoint(b2).next().next();
walker.executeInstruction(b2.elements().get(3));
assertThat(walker.workList).hasSize(4);
}
use of org.sonar.java.bytecode.cfg.BytecodeCFG in project sonar-java by SonarSource.
the class BytecodeEGWalker method execute.
private void execute(String signature, SquidClassLoader classLoader) {
BytecodeCFGMethodVisitor cfgVisitor = new BytecodeCFGMethodVisitor();
MethodLookup lookup = MethodLookup.lookup(signature, classLoader, cfgVisitor);
if (lookup == null) {
LOG.debug("Method body not found: %s", signature);
return;
}
methodBehavior.setDeclaredExceptions(lookup.declaredExceptions);
methodBehavior.setVarArgs(lookup.isVarArgs);
BytecodeCFG bytecodeCFG = cfgVisitor.getCfg();
if (bytecodeCFG == null) {
return;
}
exitBlock = bytecodeCFG.exitBlock();
steps = 0;
for (ProgramState startingState : startingStates(signature, ProgramState.EMPTY_STATE, lookup.isStatic)) {
enqueue(new ProgramPoint(bytecodeCFG.entry()), startingState);
}
while (!workList.isEmpty()) {
steps++;
if (steps > maxSteps()) {
throw new ExplodedGraphWalker.MaximumStepsReachedException("Too many steps resolving " + methodBehavior.signature());
}
// LIFO:
setNode(workList.removeFirst());
if (programPosition.block.successors().isEmpty()) {
endOfExecutionPath.add(node);
continue;
}
if (programPosition.i < programPosition.block.elements().size()) {
// process block element
executeInstruction((Instruction) programPosition.block.elements().get(programPosition.i));
} else {
// process block exit, which is unconditional jump such as goto-statement or return-statement
handleBlockExit(programPosition);
}
}
handleEndOfExecutionPath();
executeCheckEndOfExecution();
methodBehavior.completed();
// Cleanup:
workList = null;
node = null;
programState = null;
constraintManager = null;
}
Aggregations