Search in sources :

Example 66 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class ExplodedGraphWalker method startingStates.

private Iterable<ProgramState> startingStates(MethodTree tree, ProgramState currentState) {
    Stream<ProgramState> stateStream = Stream.of(currentState);
    boolean isEqualsMethod = EQUALS.matches(tree);
    boolean nonNullParameters = isGloballyAnnotatedParameterNonNull(methodTree.symbol());
    boolean nullableParameters = isGloballyAnnotatedParameterNullable(methodTree.symbol());
    boolean hasMethodBehavior = methodBehavior != null;
    for (final VariableTree variableTree : tree.parameters()) {
        // create
        final SymbolicValue sv = constraintManager.createSymbolicValue(variableTree);
        Symbol variableSymbol = variableTree.symbol();
        if (hasMethodBehavior) {
            methodBehavior.addParameter(sv);
        }
        stateStream = stateStream.map(ps -> ps.put(variableSymbol, sv));
        if (isEqualsMethod || parameterCanBeNull(variableSymbol, nullableParameters)) {
            stateStream = stateStream.flatMap((ProgramState ps) -> Stream.concat(sv.setConstraint(ps, ObjectConstraint.NULL).stream(), sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream()));
        } else if (nonNullParameters || isAnnotatedNonNull(variableSymbol)) {
            stateStream = stateStream.flatMap(ps -> sv.setConstraint(ps, ObjectConstraint.NOT_NULL).stream());
        }
    }
    return stateStream.collect(Collectors.toList());
}
Also used : JavaSymbol(org.sonar.java.resolve.JavaSymbol) JavaFileScanner(org.sonar.plugins.java.api.JavaFileScanner) BlockTree(org.sonar.plugins.java.api.tree.BlockTree) ExpressionUtils(org.sonar.java.model.ExpressionUtils) MethodYield(org.sonar.java.se.xproc.MethodYield) Loggers(org.sonar.api.utils.log.Loggers) IfStatementTree(org.sonar.plugins.java.api.tree.IfStatementTree) NullDereferenceCheck(org.sonar.java.se.checks.NullDereferenceCheck) SECheck(org.sonar.java.se.checks.SECheck) RedundantAssignmentsCheck(org.sonar.java.se.checks.RedundantAssignmentsCheck) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) Map(java.util.Map) MethodMatcher(org.sonar.java.matcher.MethodMatcher) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) ImmutableSet(com.google.common.collect.ImmutableSet) NewArrayTree(org.sonar.plugins.java.api.tree.NewArrayTree) Collection(java.util.Collection) Set(java.util.Set) JavaTree(org.sonar.java.model.JavaTree) TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) Collectors(java.util.stream.Collectors) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) DebugCheck(org.sonar.java.DebugCheck) StreamConsumedCheck(org.sonar.java.se.checks.StreamConsumedCheck) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) NullableAnnotationUtils.isGloballyAnnotatedParameterNonNull(org.sonar.java.se.NullableAnnotationUtils.isGloballyAnnotatedParameterNonNull) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) Symbol(org.sonar.plugins.java.api.semantic.Symbol) Joiner(com.google.common.base.Joiner) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) NullableAnnotationUtils.isAnnotatedNonNull(org.sonar.java.se.NullableAnnotationUtils.isAnnotatedNonNull) HashMap(java.util.HashMap) Deque(java.util.Deque) ThrowStatementTree(org.sonar.plugins.java.api.tree.ThrowStatementTree) NullableAnnotationUtils.isGloballyAnnotatedParameterNullable(org.sonar.java.se.NullableAnnotationUtils.isGloballyAnnotatedParameterNullable) ArrayList(java.util.ArrayList) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) ForStatementTree(org.sonar.plugins.java.api.tree.ForStatementTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) JavaType(org.sonar.java.resolve.JavaType) DivisionByZeroCheck(org.sonar.java.se.checks.DivisionByZeroCheck) ConstraintManager(org.sonar.java.se.constraint.ConstraintManager) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) NoWayOutLoopCheck(org.sonar.java.se.checks.NoWayOutLoopCheck) LiveVariables(org.sonar.java.cfg.LiveVariables) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) ArrayDimensionTree(org.sonar.plugins.java.api.tree.ArrayDimensionTree) LinkedList(java.util.LinkedList) MethodMatcherCollection(org.sonar.java.matcher.MethodMatcherCollection) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) Logger(org.sonar.api.utils.log.Logger) UnclosedResourcesCheck(org.sonar.java.se.checks.UnclosedResourcesCheck) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) LiteralTree(org.sonar.plugins.java.api.tree.LiteralTree) Types(org.sonar.java.resolve.Types) Iterator(java.util.Iterator) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) Type(org.sonar.plugins.java.api.semantic.Type) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue) WhileStatementTree(org.sonar.plugins.java.api.tree.WhileStatementTree) OptionalGetBeforeIsPresentCheck(org.sonar.java.se.checks.OptionalGetBeforeIsPresentCheck) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) DoWhileStatementTree(org.sonar.plugins.java.api.tree.DoWhileStatementTree) NonNullSetToNullCheck(org.sonar.java.se.checks.NonNullSetToNullCheck) CFG(org.sonar.java.cfg.CFG) SemanticModel(org.sonar.java.resolve.SemanticModel) BehaviorCache(org.sonar.java.se.xproc.BehaviorCache) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) CheckForNull(javax.annotation.CheckForNull) LocksNotUnlockedCheck(org.sonar.java.se.checks.LocksNotUnlockedCheck) NullableAnnotationUtils.isAnnotatedNullable(org.sonar.java.se.NullableAnnotationUtils.isAnnotatedNullable) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) JavaSymbol(org.sonar.java.resolve.JavaSymbol) Symbol(org.sonar.plugins.java.api.semantic.Symbol) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)

Example 67 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class ExplodedGraphWalker method executeBinaryExpression.

private void executeBinaryExpression(Tree tree) {
    // Consume two and produce one SV.
    ProgramState.Pop unstackBinary = programState.unstackValue(2);
    programState = unstackBinary.state;
    SymbolicValue symbolicValue = constraintManager.createBinarySymbolicValue(tree, unstackBinary.valuesAndSymbols);
    programState = programState.addConstraint(symbolicValue, ObjectConstraint.NOT_NULL);
    programState = programState.stackValue(symbolicValue);
}
Also used : SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)

Example 68 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class ExplodedGraphWalker method executeMethodInvocation.

private void executeMethodInvocation(MethodInvocationTree mit) {
    setSymbolicValueOnFields(mit);
    // unstack arguments and method identifier
    ProgramState.Pop unstack = programState.unstackValue(mit.arguments().size() + 1);
    logState(mit);
    programState = unstack.state;
    // get method behavior for method with known declaration (ie: within the same file)
    MethodBehavior methodInvokedBehavior = null;
    Symbol methodSymbol = mit.symbol();
    if (methodSymbol.isMethodSymbol()) {
        methodInvokedBehavior = behaviorCache.get((Symbol.MethodSymbol) methodSymbol);
    }
    // Enqueue additional exceptional paths corresponding to unchecked exceptions, for instance OutOfMemoryError
    enqueueUncheckedExceptionalPaths(methodSymbol);
    final SymbolicValue resultValue = constraintManager.createMethodSymbolicValue(mit, unstack.valuesAndSymbols);
    if (methodInvokedBehavior != null && methodInvokedBehavior.isComplete() && !EQUALS_METHODS.anyMatch(mit)) {
        List<SymbolicValue> invocationArguments = invocationArguments(unstack.values);
        List<Type> invocationTypes = mit.arguments().stream().map(ExpressionTree::symbolType).collect(Collectors.toList());
        Map<Type, SymbolicValue.ExceptionalSymbolicValue> thrownExceptionsByExceptionType = new HashMap<>();
        // Enqueue exceptional paths from exceptional yields
        methodInvokedBehavior.exceptionalPathYields().forEach(yield -> yield.statesAfterInvocation(invocationArguments, invocationTypes, programState, () -> thrownExceptionsByExceptionType.computeIfAbsent(yield.exceptionType(semanticModel), constraintManager::createExceptionalSymbolicValue)).forEach(psYield -> enqueueExceptionalPaths(psYield, methodSymbol, yield)));
        // Enqueue happy paths
        methodInvokedBehavior.happyPathYields().forEach(yield -> yield.statesAfterInvocation(invocationArguments, invocationTypes, programState, () -> resultValue).map(psYield -> handleSpecialMethods(psYield, mit)).forEach(psYield -> enqueueHappyPath(psYield, mit, yield)));
    } else {
        // Enqueue exceptional paths from thrown exceptions
        enqueueThrownExceptionalPaths(methodSymbol);
        // Enqueue happy paths
        programState = handleSpecialMethods(programState.stackValue(resultValue), mit);
        checkerDispatcher.executeCheckPostStatement(mit);
        clearStack(mit);
    }
}
Also used : JavaSymbol(org.sonar.java.resolve.JavaSymbol) JavaFileScanner(org.sonar.plugins.java.api.JavaFileScanner) BlockTree(org.sonar.plugins.java.api.tree.BlockTree) ExpressionUtils(org.sonar.java.model.ExpressionUtils) MethodYield(org.sonar.java.se.xproc.MethodYield) Loggers(org.sonar.api.utils.log.Loggers) IfStatementTree(org.sonar.plugins.java.api.tree.IfStatementTree) NullDereferenceCheck(org.sonar.java.se.checks.NullDereferenceCheck) SECheck(org.sonar.java.se.checks.SECheck) RedundantAssignmentsCheck(org.sonar.java.se.checks.RedundantAssignmentsCheck) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) Map(java.util.Map) MethodMatcher(org.sonar.java.matcher.MethodMatcher) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) ImmutableSet(com.google.common.collect.ImmutableSet) NewArrayTree(org.sonar.plugins.java.api.tree.NewArrayTree) Collection(java.util.Collection) Set(java.util.Set) JavaTree(org.sonar.java.model.JavaTree) TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) Collectors(java.util.stream.Collectors) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) DebugCheck(org.sonar.java.DebugCheck) StreamConsumedCheck(org.sonar.java.se.checks.StreamConsumedCheck) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) NullableAnnotationUtils.isGloballyAnnotatedParameterNonNull(org.sonar.java.se.NullableAnnotationUtils.isGloballyAnnotatedParameterNonNull) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) Symbol(org.sonar.plugins.java.api.semantic.Symbol) Joiner(com.google.common.base.Joiner) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) NullableAnnotationUtils.isAnnotatedNonNull(org.sonar.java.se.NullableAnnotationUtils.isAnnotatedNonNull) HashMap(java.util.HashMap) Deque(java.util.Deque) ThrowStatementTree(org.sonar.plugins.java.api.tree.ThrowStatementTree) NullableAnnotationUtils.isGloballyAnnotatedParameterNullable(org.sonar.java.se.NullableAnnotationUtils.isGloballyAnnotatedParameterNullable) ArrayList(java.util.ArrayList) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) ForStatementTree(org.sonar.plugins.java.api.tree.ForStatementTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) JavaType(org.sonar.java.resolve.JavaType) DivisionByZeroCheck(org.sonar.java.se.checks.DivisionByZeroCheck) ConstraintManager(org.sonar.java.se.constraint.ConstraintManager) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) NoWayOutLoopCheck(org.sonar.java.se.checks.NoWayOutLoopCheck) LiveVariables(org.sonar.java.cfg.LiveVariables) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) ArrayDimensionTree(org.sonar.plugins.java.api.tree.ArrayDimensionTree) LinkedList(java.util.LinkedList) MethodMatcherCollection(org.sonar.java.matcher.MethodMatcherCollection) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) Logger(org.sonar.api.utils.log.Logger) UnclosedResourcesCheck(org.sonar.java.se.checks.UnclosedResourcesCheck) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) LiteralTree(org.sonar.plugins.java.api.tree.LiteralTree) Types(org.sonar.java.resolve.Types) Iterator(java.util.Iterator) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) Type(org.sonar.plugins.java.api.semantic.Type) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue) WhileStatementTree(org.sonar.plugins.java.api.tree.WhileStatementTree) OptionalGetBeforeIsPresentCheck(org.sonar.java.se.checks.OptionalGetBeforeIsPresentCheck) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) DoWhileStatementTree(org.sonar.plugins.java.api.tree.DoWhileStatementTree) NonNullSetToNullCheck(org.sonar.java.se.checks.NonNullSetToNullCheck) CFG(org.sonar.java.cfg.CFG) SemanticModel(org.sonar.java.resolve.SemanticModel) BehaviorCache(org.sonar.java.se.xproc.BehaviorCache) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) CheckForNull(javax.annotation.CheckForNull) LocksNotUnlockedCheck(org.sonar.java.se.checks.LocksNotUnlockedCheck) NullableAnnotationUtils.isAnnotatedNullable(org.sonar.java.se.NullableAnnotationUtils.isAnnotatedNullable) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) HashMap(java.util.HashMap) JavaSymbol(org.sonar.java.resolve.JavaSymbol) Symbol(org.sonar.plugins.java.api.semantic.Symbol) JavaType(org.sonar.java.resolve.JavaType) Type(org.sonar.plugins.java.api.semantic.Type) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)

Example 69 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class ExplodedGraphWalker method handleBlockExit.

private void handleBlockExit(ProgramPoint programPosition) {
    CFG.Block block = (CFG.Block) programPosition.block;
    Tree terminator = block.terminator();
    cleanUpProgramState(block);
    boolean exitPath = node.exitPath;
    if (terminator != null) {
        switch(terminator.kind()) {
            case IF_STATEMENT:
                ExpressionTree ifCondition = ((IfStatementTree) terminator).condition();
                handleBranch(block, cleanupCondition(ifCondition), verifyCondition(ifCondition));
                return;
            case CONDITIONAL_OR:
            case CONDITIONAL_AND:
                handleBranch(block, ((BinaryExpressionTree) terminator).leftOperand());
                return;
            case CONDITIONAL_EXPRESSION:
                handleBranch(block, ((ConditionalExpressionTree) terminator).condition());
                return;
            case FOR_STATEMENT:
                ExpressionTree condition = ((ForStatementTree) terminator).condition();
                if (condition != null) {
                    handleBranch(block, condition, false);
                    return;
                }
                break;
            case WHILE_STATEMENT:
                ExpressionTree whileCondition = ((WhileStatementTree) terminator).condition();
                handleBranch(block, cleanupCondition(whileCondition), verifyCondition(whileCondition));
                return;
            case DO_STATEMENT:
                ExpressionTree doCondition = ((DoWhileStatementTree) terminator).condition();
                handleBranch(block, cleanupCondition(doCondition), verifyCondition(doCondition));
                return;
            case SYNCHRONIZED_STATEMENT:
                resetFieldValues(false);
                break;
            case RETURN_STATEMENT:
                ExpressionTree returnExpression = ((ReturnStatementTree) terminator).expression();
                if (returnExpression != null) {
                    programState.storeExitValue();
                }
                break;
            case THROW_STATEMENT:
                ProgramState.Pop unstack = programState.unstackValue(1);
                SymbolicValue sv = unstack.values.get(0);
                if (sv instanceof SymbolicValue.CaughtExceptionSymbolicValue) {
                    // retrowing the exception from a catch block
                    sv = ((SymbolicValue.CaughtExceptionSymbolicValue) sv).exception();
                } else {
                    sv = constraintManager.createExceptionalSymbolicValue(((ThrowStatementTree) terminator).expression().symbolType());
                }
                programState = unstack.state.stackValue(sv);
                programState.storeExitValue();
                break;
            default:
        }
    }
    // unconditional jumps, for-statement, switch-statement, synchronized:
    if (exitPath) {
        if (block.exitBlock() != null) {
            enqueue(new ProgramPoint(block.exitBlock()), programState, true);
        } else {
            for (CFG.Block successor : block.successors()) {
                enqueue(new ProgramPoint(successor), programState, true);
            }
        }
    } else {
        for (CFG.Block successor : block.successors()) {
            if (!block.isFinallyBlock() || isDirectFlowSuccessorOf(successor, block)) {
                enqueue(new ProgramPoint(successor), programState, successor == block.exitBlock());
            }
        }
    }
}
Also used : ForStatementTree(org.sonar.plugins.java.api.tree.ForStatementTree) CFG(org.sonar.java.cfg.CFG) WhileStatementTree(org.sonar.plugins.java.api.tree.WhileStatementTree) DoWhileStatementTree(org.sonar.plugins.java.api.tree.DoWhileStatementTree) DoWhileStatementTree(org.sonar.plugins.java.api.tree.DoWhileStatementTree) 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) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) IfStatementTree(org.sonar.plugins.java.api.tree.IfStatementTree) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)

Example 70 with SymbolicValue

use of org.sonar.java.se.symbolicvalues.SymbolicValue in project sonar-java by SonarSource.

the class ExplodedGraphWalker method enqueueExceptionalPaths.

private void enqueueExceptionalPaths(ProgramState ps, Symbol methodSymbol, @Nullable MethodYield methodYield) {
    Set<CFG.Block> exceptionBlocks = ((CFG.Block) node.programPoint.block).exceptions();
    List<CFG.Block> catchBlocks = exceptionBlocks.stream().filter(CFG.Block.IS_CATCH_BLOCK).collect(Collectors.toList());
    SymbolicValue peekValue = ps.peekValue();
    Preconditions.checkState(peekValue instanceof SymbolicValue.ExceptionalSymbolicValue, "Top of stack should always contains exceptional SV");
    SymbolicValue.ExceptionalSymbolicValue exceptionSV = (SymbolicValue.ExceptionalSymbolicValue) peekValue;
    // only consider the first match, as order of catch block is important
    List<CFG.Block> caughtBlocks = catchBlocks.stream().filter(b -> isCaughtByBlock(exceptionSV.exceptionType(), b)).sorted((b1, b2) -> Integer.compare(b2.id(), b1.id())).collect(Collectors.toList());
    if (!caughtBlocks.isEmpty()) {
        caughtBlocks.forEach(b -> enqueue(new ProgramPoint(b), ps, methodYield));
        return;
    }
    // branch to any unchecked exception catch
    catchBlocks.stream().filter(ExplodedGraphWalker::isCatchingUncheckedException).forEach(b -> enqueue(new ProgramPoint(b), ps, methodYield));
    // store the exception as exit value in case of method exit in next block
    ps.storeExitValue();
    // use other exceptional blocks, i.e. finally block and exit blocks
    List<CFG.Block> otherBlocks = exceptionBlocks.stream().filter(CFG.Block.IS_CATCH_BLOCK.negate().or(b -> methodSymbol.isUnknown())).collect(Collectors.toList());
    if (otherBlocks.isEmpty()) {
        // explicitly add the exception branching to method exit
        CFG.Block methodExit = node.programPoint.block.successors().stream().map(b -> (CFG.Block) b).filter(CFG.Block::isMethodExitBlock).findFirst().orElse(exitBlock);
        enqueue(new ProgramPoint(methodExit), ps, true, methodYield);
    } else {
        otherBlocks.forEach(b -> enqueue(new ProgramPoint(b), ps, true, methodYield));
    }
}
Also used : JavaSymbol(org.sonar.java.resolve.JavaSymbol) JavaFileScanner(org.sonar.plugins.java.api.JavaFileScanner) BlockTree(org.sonar.plugins.java.api.tree.BlockTree) ExpressionUtils(org.sonar.java.model.ExpressionUtils) MethodYield(org.sonar.java.se.xproc.MethodYield) Loggers(org.sonar.api.utils.log.Loggers) IfStatementTree(org.sonar.plugins.java.api.tree.IfStatementTree) NullDereferenceCheck(org.sonar.java.se.checks.NullDereferenceCheck) SECheck(org.sonar.java.se.checks.SECheck) RedundantAssignmentsCheck(org.sonar.java.se.checks.RedundantAssignmentsCheck) MemberSelectExpressionTree(org.sonar.plugins.java.api.tree.MemberSelectExpressionTree) Map(java.util.Map) MethodMatcher(org.sonar.java.matcher.MethodMatcher) BooleanConstraint(org.sonar.java.se.constraint.BooleanConstraint) ImmutableSet(com.google.common.collect.ImmutableSet) NewArrayTree(org.sonar.plugins.java.api.tree.NewArrayTree) Collection(java.util.Collection) Set(java.util.Set) JavaTree(org.sonar.java.model.JavaTree) TypeCastTree(org.sonar.plugins.java.api.tree.TypeCastTree) Collectors(java.util.stream.Collectors) NewClassTree(org.sonar.plugins.java.api.tree.NewClassTree) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) DebugCheck(org.sonar.java.DebugCheck) StreamConsumedCheck(org.sonar.java.se.checks.StreamConsumedCheck) AssignmentExpressionTree(org.sonar.plugins.java.api.tree.AssignmentExpressionTree) NullableAnnotationUtils.isGloballyAnnotatedParameterNonNull(org.sonar.java.se.NullableAnnotationUtils.isGloballyAnnotatedParameterNonNull) IdentifierTree(org.sonar.plugins.java.api.tree.IdentifierTree) Symbol(org.sonar.plugins.java.api.semantic.Symbol) Joiner(com.google.common.base.Joiner) ObjectConstraint(org.sonar.java.se.constraint.ObjectConstraint) NullableAnnotationUtils.isAnnotatedNonNull(org.sonar.java.se.NullableAnnotationUtils.isAnnotatedNonNull) HashMap(java.util.HashMap) Deque(java.util.Deque) ThrowStatementTree(org.sonar.plugins.java.api.tree.ThrowStatementTree) NullableAnnotationUtils.isGloballyAnnotatedParameterNullable(org.sonar.java.se.NullableAnnotationUtils.isGloballyAnnotatedParameterNullable) ArrayList(java.util.ArrayList) ExpressionTree(org.sonar.plugins.java.api.tree.ExpressionTree) ForStatementTree(org.sonar.plugins.java.api.tree.ForStatementTree) VariableTree(org.sonar.plugins.java.api.tree.VariableTree) JavaType(org.sonar.java.resolve.JavaType) DivisionByZeroCheck(org.sonar.java.se.checks.DivisionByZeroCheck) ConstraintManager(org.sonar.java.se.constraint.ConstraintManager) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) NoWayOutLoopCheck(org.sonar.java.se.checks.NoWayOutLoopCheck) LiveVariables(org.sonar.java.cfg.LiveVariables) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) MethodBehavior(org.sonar.java.se.xproc.MethodBehavior) ArrayDimensionTree(org.sonar.plugins.java.api.tree.ArrayDimensionTree) LinkedList(java.util.LinkedList) MethodMatcherCollection(org.sonar.java.matcher.MethodMatcherCollection) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) Logger(org.sonar.api.utils.log.Logger) UnclosedResourcesCheck(org.sonar.java.se.checks.UnclosedResourcesCheck) BinaryExpressionTree(org.sonar.plugins.java.api.tree.BinaryExpressionTree) ReturnStatementTree(org.sonar.plugins.java.api.tree.ReturnStatementTree) LiteralTree(org.sonar.plugins.java.api.tree.LiteralTree) Types(org.sonar.java.resolve.Types) Iterator(java.util.Iterator) ConditionalExpressionTree(org.sonar.plugins.java.api.tree.ConditionalExpressionTree) Tree(org.sonar.plugins.java.api.tree.Tree) Type(org.sonar.plugins.java.api.semantic.Type) ArrayAccessExpressionTree(org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue) WhileStatementTree(org.sonar.plugins.java.api.tree.WhileStatementTree) OptionalGetBeforeIsPresentCheck(org.sonar.java.se.checks.OptionalGetBeforeIsPresentCheck) MethodInvocationTree(org.sonar.plugins.java.api.tree.MethodInvocationTree) DoWhileStatementTree(org.sonar.plugins.java.api.tree.DoWhileStatementTree) NonNullSetToNullCheck(org.sonar.java.se.checks.NonNullSetToNullCheck) CFG(org.sonar.java.cfg.CFG) SemanticModel(org.sonar.java.resolve.SemanticModel) BehaviorCache(org.sonar.java.se.xproc.BehaviorCache) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) CheckForNull(javax.annotation.CheckForNull) LocksNotUnlockedCheck(org.sonar.java.se.checks.LocksNotUnlockedCheck) NullableAnnotationUtils.isAnnotatedNullable(org.sonar.java.se.NullableAnnotationUtils.isAnnotatedNullable) MethodTree(org.sonar.plugins.java.api.tree.MethodTree) CFG(org.sonar.java.cfg.CFG) SymbolicValue(org.sonar.java.se.symbolicvalues.SymbolicValue) RelationalSymbolicValue(org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)

Aggregations

SymbolicValue (org.sonar.java.se.symbolicvalues.SymbolicValue)132 RelationalSymbolicValue (org.sonar.java.se.symbolicvalues.RelationalSymbolicValue)94 Test (org.junit.Test)79 ProgramState (org.sonar.java.se.ProgramState)74 BinarySymbolicValue (org.sonar.java.se.symbolicvalues.BinarySymbolicValue)55 Instruction (org.sonar.java.bytecode.cfg.Instruction)52 ObjectConstraint (org.sonar.java.se.constraint.ObjectConstraint)38 BooleanConstraint (org.sonar.java.se.constraint.BooleanConstraint)36 ProgramPoint (org.sonar.java.se.ProgramPoint)30 Constraint (org.sonar.java.se.constraint.Constraint)29 TypedConstraint (org.sonar.java.se.constraint.TypedConstraint)22 Type (org.sonar.plugins.java.api.semantic.Type)18 Symbol (org.sonar.plugins.java.api.semantic.Symbol)17 JavaSymbol (org.sonar.java.resolve.JavaSymbol)16 ConstraintsByDomain (org.sonar.java.se.constraint.ConstraintsByDomain)16 MethodInvocationTree (org.sonar.plugins.java.api.tree.MethodInvocationTree)15 List (java.util.List)13 Collectors (java.util.stream.Collectors)11 VisibleForTesting (com.google.common.annotations.VisibleForTesting)10 Lists (com.google.common.collect.Lists)10