use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.
the class ExplodedGraphWalkerTest method private_method_should_be_visited.
@Test
public void private_method_should_be_visited() {
List<String> visitedMethods = new ArrayList<>();
JavaCheckVerifier.verifyNoIssue("src/test/files/se/XprocIfaceWithPrivateMethod.java", new SECheck() {
@Override
public void init(MethodTree methodTree, CFG cfg) {
visitedMethods.add(methodTree.symbol().name());
}
});
assertThat(visitedMethods).containsExactly("test", "privateMethod");
}
use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.
the class UnconditionalJumpStatementCheck method executeUnconditionnally.
private static boolean executeUnconditionnally(Tree loopTree) {
CFG cfg = getCFG(loopTree);
CFG.Block loopBlock = getLoopBlock(cfg, loopTree);
// we cannot find a path in the CFG that goes twice through this instruction.
return !hasPredecessorInBlock(loopBlock, loopTree);
}
use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.
the class ExplodedGraphWalker method execute.
private void execute(MethodTree tree) {
CFG cfg = CFG.build(tree);
exitBlock = cfg.exitBlock();
checkerDispatcher.init(tree, cfg);
liveVariables = LiveVariables.analyze(cfg);
explodedGraph = new ExplodedGraph();
methodTree = tree;
constraintManager = new ConstraintManager();
workList = new LinkedList<>();
// Linked hashSet is required to guarantee order of yields to be generated
endOfExecutionPath = new LinkedHashSet<>();
if (DEBUG_MODE_ACTIVATED) {
LOG.debug("Exploring Exploded Graph for method " + tree.simpleName().name() + " at line " + ((JavaTree) tree).getLine());
}
programState = ProgramState.EMPTY_STATE;
steps = 0;
for (ProgramState startingState : startingStates(tree, programState)) {
enqueue(new ProgramPoint(cfg.entry()), startingState);
}
while (!workList.isEmpty()) {
steps++;
if (steps > maxSteps()) {
throwMaxSteps(tree);
}
// LIFO:
setNode(workList.removeFirst());
CFG.Block block = (CFG.Block) programPosition.block;
if (block.successors().isEmpty()) {
endOfExecutionPath.add(node);
continue;
}
try {
Tree terminator = block.terminator();
if (programPosition.i < block.elements().size()) {
// process block element
visit(block.elements().get(programPosition.i), terminator);
} else if (terminator == null) {
// process block exit, which is unconditional jump such as goto-statement or return-statement
handleBlockExit(programPosition);
} else if (programPosition.i == block.elements().size()) {
// process block exist, which is conditional jump such as if-statement
checkerDispatcher.executeCheckPostStatement(terminator);
} else {
// process branch
// process block exist, which is conditional jump such as if-statement
checkerDispatcher.executeCheckPreStatement(terminator);
handleBlockExit(programPosition);
}
} catch (TooManyNestedBooleanStatesException e) {
throwTooManyBooleanStates(tree, e);
} catch (RelationalSymbolicValue.TransitiveRelationExceededException e) {
throwTooManyTransitiveRelationsException(tree, e);
}
}
handleEndOfExecutionPath(false);
checkerDispatcher.executeCheckEndOfExecution();
// Cleanup:
workList = null;
node = null;
programState = null;
constraintManager = null;
}
use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.
the class ParameterReassignedToCheck method visitForEachStatement.
@Override
public void visitForEachStatement(ForEachStatement tree) {
CFG cfg = CFG.buildCFG(Collections.singletonList(tree), true);
Symbol var = tree.variable().symbol();
boolean liveVar = true;
if (var.owner().isMethodSymbol()) {
cfg.setMethodSymbol((Symbol.MethodSymbol) var.owner());
LiveVariables analyze = LiveVariables.analyze(cfg);
Set<Symbol> live = analyze.getOut(cfg.reversedBlocks().get(1));
liveVar = live.contains(var);
}
if (!liveVar) {
variables.add(var);
}
super.visitForEachStatement(tree);
if (!liveVar) {
variables.remove(var);
}
}
use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.
the class BytecodeEGWalkerExecuteTest method test_lookupswitch.
@Test
public void test_lookupswitch() 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.visitLookupSwitchInsn(l3, new int[] { 0, 1, 2, 50 }, new Label[] { l0, l1, l2, l3 });
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.visitJumpInsn(GOTO, l3);
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();
});
}
Aggregations