Search in sources :

Example 1 with IntegerDivisionNode

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

the class CFGTranslationPhaseOne method visitCompoundAssignment.

@Override
public Node visitCompoundAssignment(CompoundAssignmentTree tree, Void p) {
    // According the JLS 15.26.2, E1 op= E2 is equivalent to
    // E1 = (T) ((E1) op (E2)), where T is the type of E1,
    // except that E1 is evaluated only once.
    // 
    Tree.Kind kind = tree.getKind();
    switch(kind) {
        case DIVIDE_ASSIGNMENT:
        case MULTIPLY_ASSIGNMENT:
        case REMAINDER_ASSIGNMENT:
            {
                // see JLS 15.17 and 15.26.2
                Node targetLHS = scan(tree.getVariable(), p);
                Node value = scan(tree.getExpression(), p);
                TypeMirror exprType = TreeUtils.typeOf(tree);
                TypeMirror leftType = TreeUtils.typeOf(tree.getVariable());
                TypeMirror rightType = TreeUtils.typeOf(tree.getExpression());
                TypeMirror promotedType = binaryPromotedType(leftType, rightType);
                Node targetRHS = binaryNumericPromotion(targetLHS, promotedType);
                value = binaryNumericPromotion(value, promotedType);
                BinaryTree operTree = treeBuilder.buildBinary(promotedType, withoutAssignment(kind), tree.getVariable(), tree.getExpression());
                handleArtificialTree(operTree);
                Node operNode;
                if (kind == Tree.Kind.MULTIPLY_ASSIGNMENT) {
                    operNode = new NumericalMultiplicationNode(operTree, targetRHS, value);
                } else if (kind == Tree.Kind.DIVIDE_ASSIGNMENT) {
                    if (TypesUtils.isIntegralPrimitive(exprType)) {
                        operNode = new IntegerDivisionNode(operTree, targetRHS, value);
                        extendWithNodeWithException(operNode, arithmeticExceptionType);
                    } else {
                        operNode = new FloatingDivisionNode(operTree, targetRHS, value);
                    }
                } else {
                    assert kind == Tree.Kind.REMAINDER_ASSIGNMENT;
                    if (TypesUtils.isIntegralPrimitive(exprType)) {
                        operNode = new IntegerRemainderNode(operTree, targetRHS, value);
                        extendWithNodeWithException(operNode, arithmeticExceptionType);
                    } else {
                        operNode = new FloatingRemainderNode(operTree, targetRHS, value);
                    }
                }
                extendWithNode(operNode);
                TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
                handleArtificialTree(castTree);
                TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType, types);
                castNode.setInSource(false);
                extendWithNode(castNode);
                AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
                extendWithNode(assignNode);
                return assignNode;
            }
        case MINUS_ASSIGNMENT:
        case PLUS_ASSIGNMENT:
            {
                // see JLS 15.18 and 15.26.2
                Node targetLHS = scan(tree.getVariable(), p);
                Node value = scan(tree.getExpression(), p);
                TypeMirror leftType = TreeUtils.typeOf(tree.getVariable());
                TypeMirror rightType = TreeUtils.typeOf(tree.getExpression());
                if (TypesUtils.isString(leftType) || TypesUtils.isString(rightType)) {
                    assert (kind == Tree.Kind.PLUS_ASSIGNMENT);
                    Node targetRHS = stringConversion(targetLHS);
                    value = stringConversion(value);
                    Node r = new StringConcatenateAssignmentNode(tree, targetRHS, value);
                    extendWithNode(r);
                    return r;
                } else {
                    TypeMirror promotedType = binaryPromotedType(leftType, rightType);
                    Node targetRHS = binaryNumericPromotion(targetLHS, promotedType);
                    value = binaryNumericPromotion(value, promotedType);
                    BinaryTree operTree = treeBuilder.buildBinary(promotedType, withoutAssignment(kind), tree.getVariable(), tree.getExpression());
                    handleArtificialTree(operTree);
                    Node operNode;
                    if (kind == Tree.Kind.PLUS_ASSIGNMENT) {
                        operNode = new NumericalAdditionNode(operTree, targetRHS, value);
                    } else {
                        assert kind == Tree.Kind.MINUS_ASSIGNMENT;
                        operNode = new NumericalSubtractionNode(operTree, targetRHS, value);
                    }
                    extendWithNode(operNode);
                    TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
                    handleArtificialTree(castTree);
                    TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType, types);
                    castNode.setInSource(false);
                    extendWithNode(castNode);
                    // Map the compound assignment tree to an assignment node, which
                    // will have the correct type.
                    AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
                    extendWithNode(assignNode);
                    return assignNode;
                }
            }
        case LEFT_SHIFT_ASSIGNMENT:
        case RIGHT_SHIFT_ASSIGNMENT:
        case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
            {
                // see JLS 15.19 and 15.26.2
                Node targetLHS = scan(tree.getVariable(), p);
                Node value = scan(tree.getExpression(), p);
                TypeMirror leftType = TreeUtils.typeOf(tree.getVariable());
                Node targetRHS = unaryNumericPromotion(targetLHS);
                value = unaryNumericPromotion(value);
                BinaryTree operTree = treeBuilder.buildBinary(leftType, withoutAssignment(kind), tree.getVariable(), tree.getExpression());
                handleArtificialTree(operTree);
                Node operNode;
                if (kind == Tree.Kind.LEFT_SHIFT_ASSIGNMENT) {
                    operNode = new LeftShiftNode(operTree, targetRHS, value);
                } else if (kind == Tree.Kind.RIGHT_SHIFT_ASSIGNMENT) {
                    operNode = new SignedRightShiftNode(operTree, targetRHS, value);
                } else {
                    assert kind == Tree.Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT;
                    operNode = new UnsignedRightShiftNode(operTree, targetRHS, value);
                }
                extendWithNode(operNode);
                TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
                handleArtificialTree(castTree);
                TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType, types);
                castNode.setInSource(false);
                extendWithNode(castNode);
                AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
                extendWithNode(assignNode);
                return assignNode;
            }
        case AND_ASSIGNMENT:
        case OR_ASSIGNMENT:
        case XOR_ASSIGNMENT:
            // see JLS 15.22
            Node targetLHS = scan(tree.getVariable(), p);
            Node value = scan(tree.getExpression(), p);
            TypeMirror leftType = TreeUtils.typeOf(tree.getVariable());
            TypeMirror rightType = TreeUtils.typeOf(tree.getExpression());
            Node targetRHS = null;
            if (isNumericOrBoxed(leftType) && isNumericOrBoxed(rightType)) {
                TypeMirror promotedType = binaryPromotedType(leftType, rightType);
                targetRHS = binaryNumericPromotion(targetLHS, promotedType);
                value = binaryNumericPromotion(value, promotedType);
            } else if (TypesUtils.isBooleanType(leftType) && TypesUtils.isBooleanType(rightType)) {
                targetRHS = unbox(targetLHS);
                value = unbox(value);
            } else {
                throw new BugInCF("Both arguments to logical operation must be numeric or boolean");
            }
            BinaryTree operTree = treeBuilder.buildBinary(leftType, withoutAssignment(kind), tree.getVariable(), tree.getExpression());
            handleArtificialTree(operTree);
            Node operNode;
            if (kind == Tree.Kind.AND_ASSIGNMENT) {
                operNode = new BitwiseAndNode(operTree, targetRHS, value);
            } else if (kind == Tree.Kind.OR_ASSIGNMENT) {
                operNode = new BitwiseOrNode(operTree, targetRHS, value);
            } else {
                assert kind == Tree.Kind.XOR_ASSIGNMENT;
                operNode = new BitwiseXorNode(operTree, targetRHS, value);
            }
            extendWithNode(operNode);
            TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
            handleArtificialTree(castTree);
            TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType, types);
            castNode.setInSource(false);
            extendWithNode(castNode);
            AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
            extendWithNode(assignNode);
            return assignNode;
        default:
            throw new BugInCF("unexpected compound assignment type");
    }
}
Also used : IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) TypeCastTree(com.sun.source.tree.TypeCastTree) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) FloatingDivisionNode(org.checkerframework.dataflow.cfg.node.FloatingDivisionNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) LeftShiftNode(org.checkerframework.dataflow.cfg.node.LeftShiftNode) PrimitiveTypeNode(org.checkerframework.dataflow.cfg.node.PrimitiveTypeNode) FloatLiteralNode(org.checkerframework.dataflow.cfg.node.FloatLiteralNode) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) BitwiseOrNode(org.checkerframework.dataflow.cfg.node.BitwiseOrNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) EqualToNode(org.checkerframework.dataflow.cfg.node.EqualToNode) NumericalPlusNode(org.checkerframework.dataflow.cfg.node.NumericalPlusNode) ConditionalAndNode(org.checkerframework.dataflow.cfg.node.ConditionalAndNode) VariableDeclarationNode(org.checkerframework.dataflow.cfg.node.VariableDeclarationNode) ClassDeclarationNode(org.checkerframework.dataflow.cfg.node.ClassDeclarationNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) AssertionErrorNode(org.checkerframework.dataflow.cfg.node.AssertionErrorNode) InstanceOfNode(org.checkerframework.dataflow.cfg.node.InstanceOfNode) BooleanLiteralNode(org.checkerframework.dataflow.cfg.node.BooleanLiteralNode) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) ArrayTypeNode(org.checkerframework.dataflow.cfg.node.ArrayTypeNode) LambdaResultExpressionNode(org.checkerframework.dataflow.cfg.node.LambdaResultExpressionNode) IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ConditionalOrNode(org.checkerframework.dataflow.cfg.node.ConditionalOrNode) NotEqualNode(org.checkerframework.dataflow.cfg.node.NotEqualNode) BitwiseXorNode(org.checkerframework.dataflow.cfg.node.BitwiseXorNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ExplicitThisNode(org.checkerframework.dataflow.cfg.node.ExplicitThisNode) StringConcatenateNode(org.checkerframework.dataflow.cfg.node.StringConcatenateNode) NullChkNode(org.checkerframework.dataflow.cfg.node.NullChkNode) CharacterLiteralNode(org.checkerframework.dataflow.cfg.node.CharacterLiteralNode) FloatingDivisionNode(org.checkerframework.dataflow.cfg.node.FloatingDivisionNode) FunctionalInterfaceNode(org.checkerframework.dataflow.cfg.node.FunctionalInterfaceNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) LongLiteralNode(org.checkerframework.dataflow.cfg.node.LongLiteralNode) MarkerNode(org.checkerframework.dataflow.cfg.node.MarkerNode) ImplicitThisNode(org.checkerframework.dataflow.cfg.node.ImplicitThisNode) FloatingRemainderNode(org.checkerframework.dataflow.cfg.node.FloatingRemainderNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) PackageNameNode(org.checkerframework.dataflow.cfg.node.PackageNameNode) DoubleLiteralNode(org.checkerframework.dataflow.cfg.node.DoubleLiteralNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) IntegerLiteralNode(org.checkerframework.dataflow.cfg.node.IntegerLiteralNode) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) ThrowNode(org.checkerframework.dataflow.cfg.node.ThrowNode) GreaterThanOrEqualNode(org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode) StringLiteralNode(org.checkerframework.dataflow.cfg.node.StringLiteralNode) TernaryExpressionNode(org.checkerframework.dataflow.cfg.node.TernaryExpressionNode) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) ParameterizedTypeNode(org.checkerframework.dataflow.cfg.node.ParameterizedTypeNode) CaseNode(org.checkerframework.dataflow.cfg.node.CaseNode) SwitchExpressionNode(org.checkerframework.dataflow.cfg.node.SwitchExpressionNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) BitwiseComplementNode(org.checkerframework.dataflow.cfg.node.BitwiseComplementNode) ConditionalNotNode(org.checkerframework.dataflow.cfg.node.ConditionalNotNode) NumericalMinusNode(org.checkerframework.dataflow.cfg.node.NumericalMinusNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) GreaterThanNode(org.checkerframework.dataflow.cfg.node.GreaterThanNode) LessThanOrEqualNode(org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode) SynchronizedNode(org.checkerframework.dataflow.cfg.node.SynchronizedNode) Node(org.checkerframework.dataflow.cfg.node.Node) BitwiseOrNode(org.checkerframework.dataflow.cfg.node.BitwiseOrNode) BinaryTree(com.sun.source.tree.BinaryTree) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) BitwiseXorNode(org.checkerframework.dataflow.cfg.node.BitwiseXorNode) LeftShiftNode(org.checkerframework.dataflow.cfg.node.LeftShiftNode) BugInCF(org.checkerframework.javacutil.BugInCF) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) Kind(com.sun.source.tree.Tree.Kind) TypeMirror(javax.lang.model.type.TypeMirror) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) LiteralTree(com.sun.source.tree.LiteralTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ForLoopTree(com.sun.source.tree.ForLoopTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ThrowTree(com.sun.source.tree.ThrowTree) BlockTree(com.sun.source.tree.BlockTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ReturnTree(com.sun.source.tree.ReturnTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) LabeledStatementTree(com.sun.source.tree.LabeledStatementTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) BreakTree(com.sun.source.tree.BreakTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) WildcardTree(com.sun.source.tree.WildcardTree) UnionTypeTree(com.sun.source.tree.UnionTypeTree) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ContinueTree(com.sun.source.tree.ContinueTree) CaseTree(com.sun.source.tree.CaseTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) SwitchTree(com.sun.source.tree.SwitchTree) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) AssertTree(com.sun.source.tree.AssertTree) StatementTree(com.sun.source.tree.StatementTree) ModifiersTree(com.sun.source.tree.ModifiersTree) WhileLoopTree(com.sun.source.tree.WhileLoopTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) EmptyStatementTree(com.sun.source.tree.EmptyStatementTree) ClassTree(com.sun.source.tree.ClassTree) IfTree(com.sun.source.tree.IfTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) ErroneousTree(com.sun.source.tree.ErroneousTree) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree) TryTree(com.sun.source.tree.TryTree) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) FloatingRemainderNode(org.checkerframework.dataflow.cfg.node.FloatingRemainderNode)

Example 2 with IntegerDivisionNode

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

the class CFGTranslationPhaseOne method visitBinary.

@Override
public Node visitBinary(BinaryTree tree, Void p) {
    // Note that for binary operations it is important to perform any required promotion on the left
    // operand before generating any Nodes for the right operand, because labels must be inserted
    // AFTER ALL preceding Nodes and BEFORE ALL following Nodes.
    Node r = null;
    Tree leftTree = tree.getLeftOperand();
    Tree rightTree = tree.getRightOperand();
    Tree.Kind kind = tree.getKind();
    switch(kind) {
        case DIVIDE:
        case MULTIPLY:
        case REMAINDER:
            {
                // see JLS 15.17
                TypeMirror exprType = TreeUtils.typeOf(tree);
                TypeMirror leftType = TreeUtils.typeOf(leftTree);
                TypeMirror rightType = TreeUtils.typeOf(rightTree);
                TypeMirror promotedType = binaryPromotedType(leftType, rightType);
                Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
                Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
                if (kind == Tree.Kind.MULTIPLY) {
                    r = new NumericalMultiplicationNode(tree, left, right);
                } else if (kind == Tree.Kind.DIVIDE) {
                    if (TypesUtils.isIntegralPrimitive(exprType)) {
                        r = new IntegerDivisionNode(tree, left, right);
                        extendWithNodeWithException(r, arithmeticExceptionType);
                    } else {
                        r = new FloatingDivisionNode(tree, left, right);
                    }
                } else {
                    assert kind == Tree.Kind.REMAINDER;
                    if (TypesUtils.isIntegralPrimitive(exprType)) {
                        r = new IntegerRemainderNode(tree, left, right);
                        extendWithNodeWithException(r, arithmeticExceptionType);
                    } else {
                        r = new FloatingRemainderNode(tree, left, right);
                    }
                }
                break;
            }
        case MINUS:
        case PLUS:
            {
                // see JLS 15.18
                // TypeMirror exprType = InternalUtils.typeOf(tree);
                TypeMirror leftType = TreeUtils.typeOf(leftTree);
                TypeMirror rightType = TreeUtils.typeOf(rightTree);
                if (TypesUtils.isString(leftType) || TypesUtils.isString(rightType)) {
                    assert (kind == Tree.Kind.PLUS);
                    Node left = stringConversion(scan(leftTree, p));
                    Node right = stringConversion(scan(rightTree, p));
                    r = new StringConcatenateNode(tree, left, right);
                } else {
                    TypeMirror promotedType = binaryPromotedType(leftType, rightType);
                    Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
                    Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
                    // set conversion.
                    if (kind == Tree.Kind.PLUS) {
                        r = new NumericalAdditionNode(tree, left, right);
                    } else {
                        assert kind == Tree.Kind.MINUS;
                        r = new NumericalSubtractionNode(tree, left, right);
                    }
                }
                break;
            }
        case LEFT_SHIFT:
        case RIGHT_SHIFT:
        case UNSIGNED_RIGHT_SHIFT:
            {
                // see JLS 15.19
                Node left = unaryNumericPromotion(scan(leftTree, p));
                Node right = unaryNumericPromotion(scan(rightTree, p));
                if (kind == Tree.Kind.LEFT_SHIFT) {
                    r = new LeftShiftNode(tree, left, right);
                } else if (kind == Tree.Kind.RIGHT_SHIFT) {
                    r = new SignedRightShiftNode(tree, left, right);
                } else {
                    assert kind == Tree.Kind.UNSIGNED_RIGHT_SHIFT;
                    r = new UnsignedRightShiftNode(tree, left, right);
                }
                break;
            }
        case GREATER_THAN:
        case GREATER_THAN_EQUAL:
        case LESS_THAN:
        case LESS_THAN_EQUAL:
            {
                // see JLS 15.20.1
                TypeMirror leftType = TreeUtils.typeOf(leftTree);
                if (TypesUtils.isBoxedPrimitive(leftType)) {
                    leftType = types.unboxedType(leftType);
                }
                TypeMirror rightType = TreeUtils.typeOf(rightTree);
                if (TypesUtils.isBoxedPrimitive(rightType)) {
                    rightType = types.unboxedType(rightType);
                }
                TypeMirror promotedType = binaryPromotedType(leftType, rightType);
                Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
                Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
                Node node;
                if (kind == Tree.Kind.GREATER_THAN) {
                    node = new GreaterThanNode(tree, left, right);
                } else if (kind == Tree.Kind.GREATER_THAN_EQUAL) {
                    node = new GreaterThanOrEqualNode(tree, left, right);
                } else if (kind == Tree.Kind.LESS_THAN) {
                    node = new LessThanNode(tree, left, right);
                } else {
                    assert kind == Tree.Kind.LESS_THAN_EQUAL;
                    node = new LessThanOrEqualNode(tree, left, right);
                }
                extendWithNode(node);
                return node;
            }
        case EQUAL_TO:
        case NOT_EQUAL_TO:
            {
                // see JLS 15.21
                TreeInfo leftInfo = getTreeInfo(leftTree);
                TreeInfo rightInfo = getTreeInfo(rightTree);
                Node left = scan(leftTree, p);
                Node right = scan(rightTree, p);
                if (leftInfo.isNumeric() && rightInfo.isNumeric() && !(leftInfo.isBoxed() && rightInfo.isBoxed())) {
                    // JLS 15.21.1 numerical equality
                    TypeMirror promotedType = binaryPromotedType(leftInfo.unboxedType(), rightInfo.unboxedType());
                    left = binaryNumericPromotion(left, promotedType);
                    right = binaryNumericPromotion(right, promotedType);
                } else if (leftInfo.isBoolean() && rightInfo.isBoolean() && !(leftInfo.isBoxed() && rightInfo.isBoxed())) {
                    // JSL 15.21.2 boolean equality
                    left = unboxAsNeeded(left, leftInfo.isBoxed());
                    right = unboxAsNeeded(right, rightInfo.isBoxed());
                }
                Node node;
                if (kind == Tree.Kind.EQUAL_TO) {
                    node = new EqualToNode(tree, left, right);
                } else {
                    assert kind == Tree.Kind.NOT_EQUAL_TO;
                    node = new NotEqualNode(tree, left, right);
                }
                extendWithNode(node);
                return node;
            }
        case AND:
        case OR:
        case XOR:
            {
                // see JLS 15.22
                TypeMirror leftType = TreeUtils.typeOf(leftTree);
                TypeMirror rightType = TreeUtils.typeOf(rightTree);
                boolean isBooleanOp = TypesUtils.isBooleanType(leftType) && TypesUtils.isBooleanType(rightType);
                Node left;
                Node right;
                if (isBooleanOp) {
                    left = unbox(scan(leftTree, p));
                    right = unbox(scan(rightTree, p));
                } else if (isNumericOrBoxed(leftType) && isNumericOrBoxed(rightType)) {
                    TypeMirror promotedType = binaryPromotedType(leftType, rightType);
                    left = binaryNumericPromotion(scan(leftTree, p), promotedType);
                    right = binaryNumericPromotion(scan(rightTree, p), promotedType);
                } else {
                    left = unbox(scan(leftTree, p));
                    right = unbox(scan(rightTree, p));
                }
                Node node;
                if (kind == Tree.Kind.AND) {
                    node = new BitwiseAndNode(tree, left, right);
                } else if (kind == Tree.Kind.OR) {
                    node = new BitwiseOrNode(tree, left, right);
                } else {
                    assert kind == Tree.Kind.XOR;
                    node = new BitwiseXorNode(tree, left, right);
                }
                extendWithNode(node);
                return node;
            }
        case CONDITIONAL_AND:
        case CONDITIONAL_OR:
            {
                // see JLS 15.23 and 15.24
                // all necessary labels
                Label rightStartL = new Label();
                Label shortCircuitL = new Label();
                // left-hand side
                Node left = scan(leftTree, p);
                ConditionalJump cjump;
                if (kind == Tree.Kind.CONDITIONAL_AND) {
                    cjump = new ConditionalJump(rightStartL, shortCircuitL);
                    cjump.setFalseFlowRule(FlowRule.ELSE_TO_ELSE);
                } else {
                    cjump = new ConditionalJump(shortCircuitL, rightStartL);
                    cjump.setTrueFlowRule(FlowRule.THEN_TO_THEN);
                }
                extendWithExtendedNode(cjump);
                // right-hand side
                addLabelForNextNode(rightStartL);
                Node right = scan(rightTree, p);
                // conditional expression itself
                addLabelForNextNode(shortCircuitL);
                Node node;
                if (kind == Tree.Kind.CONDITIONAL_AND) {
                    node = new ConditionalAndNode(tree, left, right);
                } else {
                    node = new ConditionalOrNode(tree, left, right);
                }
                extendWithNode(node);
                return node;
            }
        default:
            throw new BugInCF("unexpected binary tree: " + kind);
    }
    assert r != null : "unexpected binary tree";
    extendWithNode(r);
    return r;
}
Also used : IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) LeftShiftNode(org.checkerframework.dataflow.cfg.node.LeftShiftNode) PrimitiveTypeNode(org.checkerframework.dataflow.cfg.node.PrimitiveTypeNode) FloatLiteralNode(org.checkerframework.dataflow.cfg.node.FloatLiteralNode) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) BitwiseOrNode(org.checkerframework.dataflow.cfg.node.BitwiseOrNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) EqualToNode(org.checkerframework.dataflow.cfg.node.EqualToNode) NumericalPlusNode(org.checkerframework.dataflow.cfg.node.NumericalPlusNode) ConditionalAndNode(org.checkerframework.dataflow.cfg.node.ConditionalAndNode) VariableDeclarationNode(org.checkerframework.dataflow.cfg.node.VariableDeclarationNode) ClassDeclarationNode(org.checkerframework.dataflow.cfg.node.ClassDeclarationNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) AssertionErrorNode(org.checkerframework.dataflow.cfg.node.AssertionErrorNode) InstanceOfNode(org.checkerframework.dataflow.cfg.node.InstanceOfNode) BooleanLiteralNode(org.checkerframework.dataflow.cfg.node.BooleanLiteralNode) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) ArrayTypeNode(org.checkerframework.dataflow.cfg.node.ArrayTypeNode) LambdaResultExpressionNode(org.checkerframework.dataflow.cfg.node.LambdaResultExpressionNode) IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ConditionalOrNode(org.checkerframework.dataflow.cfg.node.ConditionalOrNode) NotEqualNode(org.checkerframework.dataflow.cfg.node.NotEqualNode) BitwiseXorNode(org.checkerframework.dataflow.cfg.node.BitwiseXorNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ExplicitThisNode(org.checkerframework.dataflow.cfg.node.ExplicitThisNode) StringConcatenateNode(org.checkerframework.dataflow.cfg.node.StringConcatenateNode) NullChkNode(org.checkerframework.dataflow.cfg.node.NullChkNode) CharacterLiteralNode(org.checkerframework.dataflow.cfg.node.CharacterLiteralNode) FloatingDivisionNode(org.checkerframework.dataflow.cfg.node.FloatingDivisionNode) FunctionalInterfaceNode(org.checkerframework.dataflow.cfg.node.FunctionalInterfaceNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) LongLiteralNode(org.checkerframework.dataflow.cfg.node.LongLiteralNode) MarkerNode(org.checkerframework.dataflow.cfg.node.MarkerNode) ImplicitThisNode(org.checkerframework.dataflow.cfg.node.ImplicitThisNode) FloatingRemainderNode(org.checkerframework.dataflow.cfg.node.FloatingRemainderNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) PackageNameNode(org.checkerframework.dataflow.cfg.node.PackageNameNode) DoubleLiteralNode(org.checkerframework.dataflow.cfg.node.DoubleLiteralNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) IntegerLiteralNode(org.checkerframework.dataflow.cfg.node.IntegerLiteralNode) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) ThrowNode(org.checkerframework.dataflow.cfg.node.ThrowNode) GreaterThanOrEqualNode(org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode) StringLiteralNode(org.checkerframework.dataflow.cfg.node.StringLiteralNode) TernaryExpressionNode(org.checkerframework.dataflow.cfg.node.TernaryExpressionNode) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) ParameterizedTypeNode(org.checkerframework.dataflow.cfg.node.ParameterizedTypeNode) CaseNode(org.checkerframework.dataflow.cfg.node.CaseNode) SwitchExpressionNode(org.checkerframework.dataflow.cfg.node.SwitchExpressionNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) BitwiseComplementNode(org.checkerframework.dataflow.cfg.node.BitwiseComplementNode) ConditionalNotNode(org.checkerframework.dataflow.cfg.node.ConditionalNotNode) NumericalMinusNode(org.checkerframework.dataflow.cfg.node.NumericalMinusNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) GreaterThanNode(org.checkerframework.dataflow.cfg.node.GreaterThanNode) LessThanOrEqualNode(org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode) SynchronizedNode(org.checkerframework.dataflow.cfg.node.SynchronizedNode) Node(org.checkerframework.dataflow.cfg.node.Node) BitwiseOrNode(org.checkerframework.dataflow.cfg.node.BitwiseOrNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) BitwiseXorNode(org.checkerframework.dataflow.cfg.node.BitwiseXorNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) ConditionalAndNode(org.checkerframework.dataflow.cfg.node.ConditionalAndNode) TypeMirror(javax.lang.model.type.TypeMirror) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) LiteralTree(com.sun.source.tree.LiteralTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ForLoopTree(com.sun.source.tree.ForLoopTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ThrowTree(com.sun.source.tree.ThrowTree) BlockTree(com.sun.source.tree.BlockTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ReturnTree(com.sun.source.tree.ReturnTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) LabeledStatementTree(com.sun.source.tree.LabeledStatementTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) BreakTree(com.sun.source.tree.BreakTree) ImportTree(com.sun.source.tree.ImportTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) WildcardTree(com.sun.source.tree.WildcardTree) UnionTypeTree(com.sun.source.tree.UnionTypeTree) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ContinueTree(com.sun.source.tree.ContinueTree) CaseTree(com.sun.source.tree.CaseTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) SwitchTree(com.sun.source.tree.SwitchTree) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) AssertTree(com.sun.source.tree.AssertTree) StatementTree(com.sun.source.tree.StatementTree) ModifiersTree(com.sun.source.tree.ModifiersTree) WhileLoopTree(com.sun.source.tree.WhileLoopTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) EmptyStatementTree(com.sun.source.tree.EmptyStatementTree) ClassTree(com.sun.source.tree.ClassTree) IfTree(com.sun.source.tree.IfTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) ErroneousTree(com.sun.source.tree.ErroneousTree) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree) TryTree(com.sun.source.tree.TryTree) LessThanOrEqualNode(org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) FloatingRemainderNode(org.checkerframework.dataflow.cfg.node.FloatingRemainderNode) NotEqualNode(org.checkerframework.dataflow.cfg.node.NotEqualNode) ConditionalOrNode(org.checkerframework.dataflow.cfg.node.ConditionalOrNode) StringConcatenateNode(org.checkerframework.dataflow.cfg.node.StringConcatenateNode) GreaterThanOrEqualNode(org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode) FloatingDivisionNode(org.checkerframework.dataflow.cfg.node.FloatingDivisionNode) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) GreaterThanNode(org.checkerframework.dataflow.cfg.node.GreaterThanNode) LeftShiftNode(org.checkerframework.dataflow.cfg.node.LeftShiftNode) BugInCF(org.checkerframework.javacutil.BugInCF) EqualToNode(org.checkerframework.dataflow.cfg.node.EqualToNode) Kind(com.sun.source.tree.Tree.Kind)

Aggregations

AnnotatedTypeTree (com.sun.source.tree.AnnotatedTypeTree)2 AnnotationTree (com.sun.source.tree.AnnotationTree)2 ArrayAccessTree (com.sun.source.tree.ArrayAccessTree)2 ArrayTypeTree (com.sun.source.tree.ArrayTypeTree)2 AssertTree (com.sun.source.tree.AssertTree)2 AssignmentTree (com.sun.source.tree.AssignmentTree)2 BinaryTree (com.sun.source.tree.BinaryTree)2 BlockTree (com.sun.source.tree.BlockTree)2 BreakTree (com.sun.source.tree.BreakTree)2 CaseTree (com.sun.source.tree.CaseTree)2 CatchTree (com.sun.source.tree.CatchTree)2 ClassTree (com.sun.source.tree.ClassTree)2 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)2 CompoundAssignmentTree (com.sun.source.tree.CompoundAssignmentTree)2 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)2 ContinueTree (com.sun.source.tree.ContinueTree)2 DoWhileLoopTree (com.sun.source.tree.DoWhileLoopTree)2 EmptyStatementTree (com.sun.source.tree.EmptyStatementTree)2 EnhancedForLoopTree (com.sun.source.tree.EnhancedForLoopTree)2 ErroneousTree (com.sun.source.tree.ErroneousTree)2