Search in sources :

Example 1 with CFG

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");
}
Also used : SECheck(org.sonar.java.se.checks.SECheck) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) CFG(org.sonar.java.cfg.CFG) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Example 2 with CFG

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);
}
Also used : CFG(org.sonar.java.cfg.CFG)

Example 3 with CFG

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;
}
Also used : ConstraintManager(org.sonar.java.se.constraint.ConstraintManager) CFG(org.sonar.java.cfg.CFG) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue) JavaTree(org.sonar.java.model.JavaTree) BlockTree(org.sonar.plugins.java.api.tree.BlockTree) IfStatementTree(org.sonar.plugins.java.api.tree.IfStatementTree) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) NewArrayTree(org.sonar.plugins.java.api.tree.NewArrayTree) JavaTree(org.sonar.java.model.JavaTree) TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) ThrowStatementTree(org.sonar.plugins.java.api.tree.ThrowStatementTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) ForStatementTree(org.sonar.plugins.java.api.tree.ForStatementTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) ArrayDimensionTree(org.sonar.plugins.java.api.tree.ArrayDimensionTree) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) LiteralTree(org.sonar.plugins.java.api.tree.LiteralTree) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) WhileStatementTree(org.sonar.plugins.java.api.tree.WhileStatementTree) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) DoWhileStatementTree(org.sonar.plugins.java.api.tree.DoWhileStatementTree) MethodTree(org.sonar.plugins.java.api.tree.MethodTree)

Example 4 with CFG

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);
    }
}
Also used : CFG(org.sonar.java.cfg.CFG) LiveVariables(org.sonar.java.cfg.LiveVariables) Symbol(org.sonar.plugins.java.api.semantic.Symbol)

Example 5 with CFG

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();
    });
}
Also used : BytecodeCFG(org.sonar.java.bytecode.cfg.BytecodeCFG) CFG(org.sonar.java.cfg.CFG) ProgramPoint(org.sonar.java.se.ProgramPoint) BytecodeCFG(org.sonar.java.bytecode.cfg.BytecodeCFG) Label(org.objectweb.asm.Label) Instructions(org.sonar.java.bytecode.cfg.Instructions) Instruction(org.sonar.java.bytecode.cfg.Instruction) BinarySymbolicValue(org.sonar.java.se.symbolicvalues.BinarySymbolicValue) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue) Test(org.junit.Test)

Aggregations

CFG (org.sonar.java.cfg.CFG)17 Test (org.junit.Test)7 MethodTree (org.sonar.plugins.java.api.tree.MethodTree)6 LiveVariables (org.sonar.java.cfg.LiveVariables)5 Symbol (org.sonar.plugins.java.api.semantic.Symbol)5 File (java.io.File)4 ArrayList (java.util.ArrayList)4 RelationalSymbolicValue (org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)4 SymbolicValue (org.sonar.java.se.symbolicvalues.SymbolicValue)4 List (java.util.List)3 Set (java.util.Set)3 Label (org.objectweb.asm.Label)3 ExpressionTree (org.sonar.plugins.java.api.tree.ExpressionTree)3 Tree (org.sonar.plugins.java.api.tree.Tree)3 VariableTree (org.sonar.plugins.java.api.tree.VariableTree)3 Preconditions (com.google.common.base.Preconditions)2 Collections (java.util.Collections)2 HashSet (java.util.HashSet)2 Collectors (java.util.stream.Collectors)2 SonarComponents (org.sonar.java.SonarComponents)2