Search in sources :

Example 1 with BinaryOperationNode

use of org.checkerframework.dataflow.cfg.node.BinaryOperationNode in project checker-framework by typetools.

the class LowerBoundTransfer method getAnnotationForPlus.

/**
 * getAnnotationForPlus handles the following cases (cases 10-12 above):
 *
 * <pre>
 *      8. lit -2 + pos &rarr; gte-1
 *      lit -1 + * &rarr; call demote
 *      lit 0 + * &rarr; *
 *      lit 1 + * &rarr; call promote
 *      9. lit &ge; 2 + {gte-1, nn, or pos} &rarr; pos
 *      let all other lits, including sets, fall through:
 *      10. pos + pos &rarr; pos
 *      11. nn + * &rarr; *
 *      12. pos + gte-1 &rarr; nn
 *      * + * &rarr; lbu
 *  </pre>
 */
private AnnotationMirror getAnnotationForPlus(BinaryOperationNode binaryOpNode, TransferInput<CFValue, CFStore> p) {
    Node leftExprNode = binaryOpNode.getLeftOperand();
    Node rightExprNode = binaryOpNode.getRightOperand();
    AnnotationMirror leftAnno = getLowerBoundAnnotation(leftExprNode, p);
    // Check if the right side's value is known at compile time.
    Long valRight = ValueCheckerUtils.getExactValue(rightExprNode.getTree(), aTypeFactory.getValueAnnotatedTypeFactory());
    if (valRight != null) {
        return getAnnotationForLiteralPlus(valRight.intValue(), leftAnno);
    }
    AnnotationMirror rightAnno = getLowerBoundAnnotation(rightExprNode, p);
    // Check if the left side's value is known at compile time.
    Long valLeft = ValueCheckerUtils.getExactValue(leftExprNode.getTree(), aTypeFactory.getValueAnnotatedTypeFactory());
    if (valLeft != null) {
        return getAnnotationForLiteralPlus(valLeft.intValue(), rightAnno);
    }
    /* This section is handling the generic cases:
     *      pos + pos -> pos
     *      nn + * -> *
     *      pos + gte-1 -> nn
     */
    if (aTypeFactory.areSameByClass(leftAnno, Positive.class) && aTypeFactory.areSameByClass(rightAnno, Positive.class)) {
        return POS;
    }
    if (aTypeFactory.areSameByClass(leftAnno, NonNegative.class)) {
        return rightAnno;
    }
    if (aTypeFactory.areSameByClass(rightAnno, NonNegative.class)) {
        return leftAnno;
    }
    if ((isPositive(leftAnno) && isGTEN1(rightAnno)) || (isGTEN1(leftAnno) && isPositive(rightAnno))) {
        return NN;
    }
    return UNKNOWN;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) Positive(org.checkerframework.checker.index.qual.Positive) BinaryOperationNode(org.checkerframework.dataflow.cfg.node.BinaryOperationNode) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) Node(org.checkerframework.dataflow.cfg.node.Node)

Example 2 with BinaryOperationNode

use of org.checkerframework.dataflow.cfg.node.BinaryOperationNode in project checker-framework by typetools.

the class JavaExpression method fromNode.

/**
 * We ignore operations such as widening and narrowing when computing the internal representation.
 *
 * @param receiverNode a node to convert to a JavaExpression
 * @return the internal representation of the given node. Might contain {@link Unknown}.
 */
public static JavaExpression fromNode(Node receiverNode) {
    JavaExpression result = null;
    if (receiverNode instanceof FieldAccessNode) {
        result = fromNodeFieldAccess((FieldAccessNode) receiverNode);
    } else if (receiverNode instanceof ExplicitThisNode) {
        result = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof ThisNode) {
        result = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof SuperNode) {
        result = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof LocalVariableNode) {
        LocalVariableNode lv = (LocalVariableNode) receiverNode;
        result = new LocalVariable(lv);
    } else if (receiverNode instanceof ArrayAccessNode) {
        ArrayAccessNode a = (ArrayAccessNode) receiverNode;
        result = fromArrayAccess(a);
    } else if (receiverNode instanceof StringConversionNode) {
        // ignore string conversion
        return fromNode(((StringConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof WideningConversionNode) {
        // ignore widening
        return fromNode(((WideningConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof NarrowingConversionNode) {
        // ignore narrowing
        return fromNode(((NarrowingConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof UnaryOperationNode) {
        UnaryOperationNode uopn = (UnaryOperationNode) receiverNode;
        return new UnaryOperation(uopn, fromNode(uopn.getOperand()));
    } else if (receiverNode instanceof BinaryOperationNode) {
        BinaryOperationNode bopn = (BinaryOperationNode) receiverNode;
        return new BinaryOperation(bopn, fromNode(bopn.getLeftOperand()), fromNode(bopn.getRightOperand()));
    } else if (receiverNode instanceof ClassNameNode) {
        ClassNameNode cn = (ClassNameNode) receiverNode;
        result = new ClassName(cn.getType());
    } else if (receiverNode instanceof ValueLiteralNode) {
        ValueLiteralNode vn = (ValueLiteralNode) receiverNode;
        result = new ValueLiteral(vn.getType(), vn);
    } else if (receiverNode instanceof ArrayCreationNode) {
        ArrayCreationNode an = (ArrayCreationNode) receiverNode;
        List<@Nullable JavaExpression> dimensions = CollectionsPlume.mapList(JavaExpression::fromNode, an.getDimensions());
        List<JavaExpression> initializers = CollectionsPlume.mapList(JavaExpression::fromNode, an.getInitializers());
        result = new ArrayCreation(an.getType(), dimensions, initializers);
    } else if (receiverNode instanceof MethodInvocationNode) {
        MethodInvocationNode mn = (MethodInvocationNode) receiverNode;
        MethodInvocationTree t = mn.getTree();
        if (t == null) {
            throw new BugInCF("Unexpected null tree for node: " + mn);
        }
        assert TreeUtils.isUseOfElement(t) : "@AssumeAssertion(nullness): tree kind";
        ExecutableElement invokedMethod = TreeUtils.elementFromUse(t);
        // Note that the method might be nondeterministic.
        List<JavaExpression> parameters = CollectionsPlume.mapList(JavaExpression::fromNode, mn.getArguments());
        JavaExpression methodReceiver;
        if (ElementUtils.isStatic(invokedMethod)) {
            methodReceiver = new ClassName(mn.getTarget().getReceiver().getType());
        } else {
            methodReceiver = fromNode(mn.getTarget().getReceiver());
        }
        result = new MethodCall(mn.getType(), invokedMethod, methodReceiver, parameters);
    }
    if (result == null) {
        result = new Unknown(receiverNode);
    }
    return result;
}
Also used : ExecutableElement(javax.lang.model.element.ExecutableElement) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) ExplicitThisNode(org.checkerframework.dataflow.cfg.node.ExplicitThisNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) BinaryOperationNode(org.checkerframework.dataflow.cfg.node.BinaryOperationNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) List(java.util.List) ArrayList(java.util.ArrayList) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) BugInCF(org.checkerframework.javacutil.BugInCF) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) UnaryOperationNode(org.checkerframework.dataflow.cfg.node.UnaryOperationNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) ExplicitThisNode(org.checkerframework.dataflow.cfg.node.ExplicitThisNode) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 3 with BinaryOperationNode

use of org.checkerframework.dataflow.cfg.node.BinaryOperationNode in project checker-framework by typetools.

the class LiveVarStore method addUseInExpression.

/**
 * Add the information of live variables in an expression to the live variable set.
 *
 * @param expression a node
 */
public void addUseInExpression(Node expression) {
    // TODO Do we need a AbstractNodeScanner to do the following job?
    if (expression instanceof LocalVariableNode || expression instanceof FieldAccessNode) {
        LiveVarValue liveVarValue = new LiveVarValue(expression);
        putLiveVar(liveVarValue);
    } else if (expression instanceof UnaryOperationNode) {
        UnaryOperationNode unaryNode = (UnaryOperationNode) expression;
        addUseInExpression(unaryNode.getOperand());
    } else if (expression instanceof TernaryExpressionNode) {
        TernaryExpressionNode ternaryNode = (TernaryExpressionNode) expression;
        addUseInExpression(ternaryNode.getConditionOperand());
        addUseInExpression(ternaryNode.getThenOperand());
        addUseInExpression(ternaryNode.getElseOperand());
    } else if (expression instanceof TypeCastNode) {
        TypeCastNode typeCastNode = (TypeCastNode) expression;
        addUseInExpression(typeCastNode.getOperand());
    } else if (expression instanceof InstanceOfNode) {
        InstanceOfNode instanceOfNode = (InstanceOfNode) expression;
        addUseInExpression(instanceOfNode.getOperand());
    } else if (expression instanceof BinaryOperationNode) {
        BinaryOperationNode binaryNode = (BinaryOperationNode) expression;
        addUseInExpression(binaryNode.getLeftOperand());
        addUseInExpression(binaryNode.getRightOperand());
    }
}
Also used : TernaryExpressionNode(org.checkerframework.dataflow.cfg.node.TernaryExpressionNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) UnaryOperationNode(org.checkerframework.dataflow.cfg.node.UnaryOperationNode) InstanceOfNode(org.checkerframework.dataflow.cfg.node.InstanceOfNode) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) BinaryOperationNode(org.checkerframework.dataflow.cfg.node.BinaryOperationNode)

Aggregations

BinaryOperationNode (org.checkerframework.dataflow.cfg.node.BinaryOperationNode)3 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)2 LocalVariableNode (org.checkerframework.dataflow.cfg.node.LocalVariableNode)2 UnaryOperationNode (org.checkerframework.dataflow.cfg.node.UnaryOperationNode)2 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 AnnotationMirror (javax.lang.model.element.AnnotationMirror)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 Positive (org.checkerframework.checker.index.qual.Positive)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1 ArrayAccessNode (org.checkerframework.dataflow.cfg.node.ArrayAccessNode)1 ArrayCreationNode (org.checkerframework.dataflow.cfg.node.ArrayCreationNode)1 BitwiseAndNode (org.checkerframework.dataflow.cfg.node.BitwiseAndNode)1 ClassNameNode (org.checkerframework.dataflow.cfg.node.ClassNameNode)1 ExplicitThisNode (org.checkerframework.dataflow.cfg.node.ExplicitThisNode)1 InstanceOfNode (org.checkerframework.dataflow.cfg.node.InstanceOfNode)1 IntegerDivisionNode (org.checkerframework.dataflow.cfg.node.IntegerDivisionNode)1 IntegerRemainderNode (org.checkerframework.dataflow.cfg.node.IntegerRemainderNode)1 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)1