Search in sources :

Example 6 with CFG

use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.

the class JavaAstScannerTest method should_swallow_log_and_report_checks_exceptions_for_symbolic_execution.

@Test
public void should_swallow_log_and_report_checks_exceptions_for_symbolic_execution() {
    JavaAstScanner scanner = new JavaAstScanner(JavaParser.createParser(), null);
    logTester.clear();
    SonarComponents sonarComponent = new SonarComponents(null, context.fileSystem(), null, null, null, null);
    context.setRuntime(SonarRuntimeImpl.forSonarLint(Version.create(6, 7)));
    sonarComponent.setSensorContext(context);
    scanner.setVisitorBridge(new VisitorsBridge(Collections.singletonList(new SECheck() {

        @Override
        public void init(MethodTree methodTree, CFG cfg) {
            throw new NullPointerException("nobody expect the spanish inquisition !");
        }
    }), new ArrayList<>(), sonarComponent, SymbolicExecutionMode.ENABLED_WITHOUT_X_FILE));
    scanner.scan(ImmutableList.of(new File("src/test/resources/se/MethodBehavior.java")));
    assertThat(logTester.logs(LoggerLevel.ERROR)).hasSize(1);
    assertThat(logTester.logs(LoggerLevel.ERROR).get(0)).startsWith("Unable to run check class org.sonar.java.se.SymbolicExecutionVisitor");
    assertThat(sonarComponent.analysisErrors).hasSize(1);
    assertThat(sonarComponent.analysisErrors.get(0).getKind()).isSameAs(AnalysisError.Kind.SE_ERROR);
}
Also used : SonarComponents(org.sonar.java.SonarComponents) 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) VisitorsBridge(org.sonar.java.model.VisitorsBridge) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) File(java.io.File) Test(org.junit.Test)

Example 7 with CFG

use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.

the class UCFGJavaVisitor method buildUCfg.

private UCFG buildUCfg(MethodTree methodTree, CFG cfg) {
    String signature = signatureFor(methodTree.symbol());
    IdentifierGenerator idGenerator = new IdentifierGenerator(methodTree);
    UCFGBuilder builder = UCFGBuilder.createUCFGForMethod(signature);
    methodTree.parameters().stream().map(p -> idGenerator.lookupIdFor(p.symbol())).map(UCFGBuilder::variableWithId).forEach(builder::addMethodParam);
    BlockBuilder entryBlockBuilder = buildBasicBlock(cfg.entry(), methodTree, idGenerator);
    if (getAnnotatedStringParameters(methodTree).count() > 0) {
        builder.addStartingBlock(buildParameterAnnotationsBlock(methodTree, idGenerator, cfg));
        builder.addBasicBlock(entryBlockBuilder);
    } else {
        builder.addStartingBlock(entryBlockBuilder);
    }
    cfg.blocks().stream().filter(b -> !b.equals(cfg.entry())).forEach(b -> builder.addBasicBlock(buildBasicBlock(b, methodTree, idGenerator)));
    return builder.build();
}
Also used : JavaSymbol(org.sonar.java.resolve.JavaSymbol) Label(org.sonar.ucfg.Label) BaseTreeVisitor(org.sonar.plugins.java.api.tree.BaseTreeVisitor) JavaFileScanner(org.sonar.plugins.java.api.JavaFileScanner) Loggers(org.sonar.api.utils.log.Loggers) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) PLUS(org.sonar.plugins.java.api.tree.Tree.Kind.PLUS) Map(java.util.Map) SyntaxToken(org.sonar.plugins.java.api.tree.SyntaxToken) Set(java.util.Set) Collectors(java.util.stream.Collectors) JavaFileScannerContext(org.sonar.plugins.java.api.JavaFileScannerContext) Sets(com.google.common.collect.Sets) List(java.util.List) UCFGtoProtobuf(org.sonar.ucfg.UCFGtoProtobuf) Stream(java.util.stream.Stream) MEMBER_SELECT(org.sonar.plugins.java.api.tree.Tree.Kind.MEMBER_SELECT) UCFGBuilder.variableWithId(org.sonar.ucfg.UCFGBuilder.variableWithId) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) Symbol(org.sonar.plugins.java.api.semantic.Symbol) ASSIGNMENT(org.sonar.plugins.java.api.tree.Tree.Kind.ASSIGNMENT) PLUS_ASSIGNMENT(org.sonar.plugins.java.api.tree.Tree.Kind.PLUS_ASSIGNMENT) UCFG(org.sonar.ucfg.UCFG) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) HashSet(java.util.HashSet) BlockBuilder(org.sonar.ucfg.UCFGBuilder.BlockBuilder) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) UCFGBuilder(org.sonar.ucfg.UCFGBuilder) LiteralUtils(org.sonar.java.model.LiteralUtils) Nullable(javax.annotation.Nullable) Logger(org.sonar.api.utils.log.Logger) AnnotationTree(org.sonar.plugins.java.api.tree.AnnotationTree) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) LiteralTree(org.sonar.plugins.java.api.tree.LiteralTree) UCFGBuilder.call(org.sonar.ucfg.UCFGBuilder.call) METHOD_INVOCATION(org.sonar.plugins.java.api.tree.Tree.Kind.METHOD_INVOCATION) Tree(org.sonar.plugins.java.api.tree.Tree) Type(org.sonar.plugins.java.api.semantic.Type) File(java.io.File) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) LocationInFile(org.sonar.ucfg.LocationInFile) CFG(org.sonar.java.cfg.CFG) VariableReadExtractor(org.sonar.java.cfg.VariableReadExtractor) Preconditions(com.google.common.base.Preconditions) Expression(org.sonar.ucfg.Expression) UCFGBuilder.constant(org.sonar.ucfg.UCFGBuilder.constant) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) UCFGBuilder(org.sonar.ucfg.UCFGBuilder) BlockBuilder(org.sonar.ucfg.UCFGBuilder.BlockBuilder)

Example 8 with CFG

use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.

the class FileLinesVisitor method computeExecutableLines.

private void computeExecutableLines(List<? extends Tree> trees) {
    if (trees.isEmpty()) {
        return;
    }
    // rely on cfg to get every instructions and get most of the token.
    CFG cfg = CFG.buildCFG(trees);
    cfg.blocks().stream().flatMap(b -> b.elements().stream()).forEach(t -> {
        if (t.is(NEW_CLASS)) {
            NewClassTree newClassTree = (NewClassTree) t;
            new ExecutableLinesTokenVisitor().scanTree(newClassTree.identifier());
            executableLines.add(newClassTree.newKeyword().line());
        } else if (t.is(TRY_STATEMENT)) {
            // add last token of try statements
            executableLines.add(t.lastToken().line());
        } else {
            executableLines.add(t.firstToken().line());
        }
    });
}
Also used : NEW_CLASS(org.sonar.plugins.java.api.tree.Tree.Kind.NEW_CLASS) SyntaxTrivia(org.sonar.plugins.java.api.tree.SyntaxTrivia) FOR_EACH_STATEMENT(org.sonar.plugins.java.api.tree.Tree.Kind.FOR_EACH_STATEMENT) STATIC_INITIALIZER(org.sonar.plugins.java.api.tree.Tree.Kind.STATIC_INITIALIZER) BlockTree(org.sonar.plugins.java.api.tree.BlockTree) CATCH(org.sonar.plugins.java.api.tree.Tree.Kind.CATCH) LAMBDA_EXPRESSION(org.sonar.plugins.java.api.tree.Tree.Kind.LAMBDA_EXPRESSION) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) FileLinesContext(org.sonar.api.measures.FileLinesContext) HashSet(java.util.HashSet) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) DO_STATEMENT(org.sonar.plugins.java.api.tree.Tree.Kind.DO_STATEMENT) TOKEN(org.sonar.plugins.java.api.tree.Tree.Kind.TOKEN) VARIABLE(org.sonar.plugins.java.api.tree.Tree.Kind.VARIABLE) SyntaxToken(org.sonar.plugins.java.api.tree.SyntaxToken) SonarComponents(org.sonar.java.SonarComponents) FLOAT_LITERAL(org.sonar.plugins.java.api.tree.Tree.Kind.FLOAT_LITERAL) Modifier(org.sonar.plugins.java.api.tree.Modifier) STRING_LITERAL(org.sonar.plugins.java.api.tree.Tree.Kind.STRING_LITERAL) TypeTree(org.sonar.plugins.java.api.tree.TypeTree) INITIALIZER(org.sonar.plugins.java.api.tree.Tree.Kind.INITIALIZER) Set(java.util.Set) INT_LITERAL(org.sonar.plugins.java.api.tree.Tree.Kind.INT_LITERAL) Tree(org.sonar.plugins.java.api.tree.Tree) LONG_LITERAL(org.sonar.plugins.java.api.tree.Tree.Kind.LONG_LITERAL) METHOD(org.sonar.plugins.java.api.tree.Tree.Kind.METHOD) ModifiersUtils(org.sonar.java.model.ModifiersUtils) FOR_STATEMENT(org.sonar.plugins.java.api.tree.Tree.Kind.FOR_STATEMENT) JavaFileScannerContext(org.sonar.plugins.java.api.JavaFileScannerContext) CoreMetrics(org.sonar.api.measures.CoreMetrics) File(java.io.File) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) LambdaExpressionTree(org.sonar.plugins.java.api.tree.LambdaExpressionTree) NULL_LITERAL(org.sonar.plugins.java.api.tree.Tree.Kind.NULL_LITERAL) List(java.util.List) CFG(org.sonar.java.cfg.CFG) DOUBLE_LITERAL(org.sonar.plugins.java.api.tree.Tree.Kind.DOUBLE_LITERAL) BOOLEAN_LITERAL(org.sonar.plugins.java.api.tree.Tree.Kind.BOOLEAN_LITERAL) CONSTRUCTOR(org.sonar.plugins.java.api.tree.Tree.Kind.CONSTRUCTOR) BLOCK(org.sonar.plugins.java.api.tree.Tree.Kind.BLOCK) CHAR_LITERAL(org.sonar.plugins.java.api.tree.Tree.Kind.CHAR_LITERAL) WHILE_STATEMENT(org.sonar.plugins.java.api.tree.Tree.Kind.WHILE_STATEMENT) Collections(java.util.Collections) TRY_STATEMENT(org.sonar.plugins.java.api.tree.Tree.Kind.TRY_STATEMENT) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) CFG(org.sonar.java.cfg.CFG) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree)

Example 9 with CFG

use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.

the class DeadStoreCheck method visitNode.

@Override
public void visitNode(Tree tree) {
    if (!hasSemantic()) {
        return;
    }
    MethodTree methodTree = (MethodTree) tree;
    if (methodTree.block() == null) {
        return;
    }
    // TODO(npe) Exclude try statements with finally as CFG is incorrect for those and lead to false positive
    if (hasTryFinallyWithLocalVar(methodTree.block(), methodTree.symbol())) {
        return;
    }
    Symbol.MethodSymbol methodSymbol = methodTree.symbol();
    CFG cfg = CFG.build(methodTree);
    LiveVariables liveVariables = LiveVariables.analyze(cfg);
    // Liveness analysis provides information only for block boundaries, so we should do analysis between elements within blocks
    for (CFG.Block block : cfg.blocks()) {
        checkElements(block, liveVariables.getOut(block), methodSymbol);
    }
}
Also used : MethodTree(org.sonar.plugins.java.api.tree.MethodTree) CFG(org.sonar.java.cfg.CFG) LiveVariables(org.sonar.java.cfg.LiveVariables) Symbol(org.sonar.plugins.java.api.semantic.Symbol)

Example 10 with CFG

use of org.sonar.java.cfg.CFG in project sonar-java by SonarSource.

the class SECheckTest method flow_from_exit_node_should_not_lead_to_infinite_recursion.

@Test(timeout = 3000)
public void flow_from_exit_node_should_not_lead_to_infinite_recursion() throws Exception {
    CFG cfg = CFGTest.buildCFG("void foo(boolean a) { if(a) {foo(true);} foo(false); }");
    ExplodedGraph eg = new ExplodedGraph();
    ExplodedGraph.Node node = eg.node(new ProgramPoint(cfg.blocks().get(3)), ProgramState.EMPTY_STATE);
    node.addParent(eg.node(new ProgramPoint(cfg.blocks().get(2)).next().next(), ProgramState.EMPTY_STATE), null);
    Set<Flow> flows = FlowComputation.flow(node, new SymbolicValue(), Collections.singletonList(ObjectConstraint.class));
    assertThat(flows.iterator().next().isEmpty()).isTrue();
}
Also used : CFG(org.sonar.java.cfg.CFG) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) Test(org.junit.Test) CFGTest(org.sonar.java.cfg.CFGTest)

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