Search in sources :

Example 1 with PolySigned

use of org.checkerframework.checker.signedness.qual.PolySigned in project checker-framework by typetools.

the class SignednessVisitor method visitBinary.

/**
 * Enforces the following rules on binary operations involving Unsigned and Signed types:
 *
 * <ul>
 *   <li>Do not allow any Unsigned types or PolySigned types in {@literal {/, %}} operations.
 *   <li>Do not allow signed right shift {@literal {>>}} on an Unsigned type or a PolySigned type.
 *   <li>Do not allow unsigned right shift {@literal {>>>}} on a Signed type or a PolySigned type.
 *   <li>Allow any left shift {@literal {<<}}.
 *   <li>Do not allow non-equality comparisons {@literal {<, <=, >, >=}} on Unsigned types or
 *       PolySigned types.
 *   <li>Do not allow the mixing of Signed and Unsigned types.
 * </ul>
 */
@Override
public Void visitBinary(BinaryTree node, Void p) {
    // Used in diagnostic messages.
    ExpressionTree leftOp = node.getLeftOperand();
    ExpressionTree rightOp = node.getRightOperand();
    Pair<AnnotatedTypeMirror, AnnotatedTypeMirror> argTypes = atypeFactory.binaryTreeArgTypes(node);
    AnnotatedTypeMirror leftOpType = argTypes.first;
    AnnotatedTypeMirror rightOpType = argTypes.second;
    Tree.Kind kind = node.getKind();
    switch(kind) {
        case DIVIDE:
        case REMAINDER:
            if (hasUnsignedAnnotation(leftOpType)) {
                checker.reportError(leftOp, "operation.unsignedlhs", kind, leftOpType, rightOpType);
            } else if (hasUnsignedAnnotation(rightOpType)) {
                checker.reportError(rightOp, "operation.unsignedrhs", kind, leftOpType, rightOpType);
            }
            break;
        case RIGHT_SHIFT:
            if (hasUnsignedAnnotation(leftOpType) && !atypeFactory.isMaskedShiftEitherSignedness(node, getCurrentPath()) && !atypeFactory.isCastedShiftEitherSignedness(node, getCurrentPath())) {
                checker.reportError(leftOp, "shift.signed", kind, leftOpType, rightOpType);
            }
            break;
        case UNSIGNED_RIGHT_SHIFT:
            if (hasSignedAnnotation(leftOpType) && !atypeFactory.isMaskedShiftEitherSignedness(node, getCurrentPath()) && !atypeFactory.isCastedShiftEitherSignedness(node, getCurrentPath())) {
                checker.reportError(leftOp, "shift.unsigned", kind, leftOpType, rightOpType);
            }
            break;
        case LEFT_SHIFT:
            break;
        case GREATER_THAN:
        case GREATER_THAN_EQUAL:
        case LESS_THAN:
        case LESS_THAN_EQUAL:
            if (hasUnsignedAnnotation(leftOpType)) {
                checker.reportError(leftOp, "comparison.unsignedlhs", leftOpType, rightOpType);
            } else if (hasUnsignedAnnotation(rightOpType)) {
                checker.reportError(rightOp, "comparison.unsignedrhs", leftOpType, rightOpType);
            }
            break;
        case EQUAL_TO:
        case NOT_EQUAL_TO:
            if (leftOpType.hasAnnotation(Unsigned.class) && rightOpType.hasAnnotation(Signed.class)) {
                checker.reportError(node, "comparison.mixed.unsignedlhs", leftOpType, rightOpType);
            } else if (leftOpType.hasAnnotation(Signed.class) && rightOpType.hasAnnotation(Unsigned.class)) {
                checker.reportError(node, "comparison.mixed.unsignedrhs", leftOpType, rightOpType);
            }
            break;
        case PLUS:
            if (TreeUtils.isStringConcatenation(node)) {
                AnnotationMirror leftAnno = leftOpType.getEffectiveAnnotations().iterator().next();
                AnnotationMirror rightAnno = rightOpType.getEffectiveAnnotations().iterator().next();
                if (leftOpType.getKind() != TypeKind.CHAR && !TypesUtils.isDeclaredOfName(leftOpType.getUnderlyingType(), "java.lang.Character") && !atypeFactory.getQualifierHierarchy().isSubtype(leftAnno, atypeFactory.SIGNED)) {
                    checker.reportError(leftOp, "unsigned.concat");
                } else if (rightOpType.getKind() != TypeKind.CHAR && !TypesUtils.isDeclaredOfName(rightOpType.getUnderlyingType(), "java.lang.Character") && !atypeFactory.getQualifierHierarchy().isSubtype(rightAnno, atypeFactory.SIGNED)) {
                    checker.reportError(rightOp, "unsigned.concat");
                }
                break;
            }
        // fall through
        default:
            if (leftOpType.hasAnnotation(Unsigned.class) && rightOpType.hasAnnotation(Signed.class)) {
                checker.reportError(node, "operation.mixed.unsignedlhs", kind, leftOpType, rightOpType);
            } else if (leftOpType.hasAnnotation(Signed.class) && rightOpType.hasAnnotation(Unsigned.class)) {
                checker.reportError(node, "operation.mixed.unsignedrhs", kind, leftOpType, rightOpType);
            }
            break;
    }
    return super.visitBinary(node, p);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) Unsigned(org.checkerframework.checker.signedness.qual.Unsigned) Signed(org.checkerframework.checker.signedness.qual.Signed) PolySigned(org.checkerframework.checker.signedness.qual.PolySigned) ExpressionTree(com.sun.source.tree.ExpressionTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) ExpressionTree(com.sun.source.tree.ExpressionTree) BinaryTree(com.sun.source.tree.BinaryTree) Tree(com.sun.source.tree.Tree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 2 with PolySigned

use of org.checkerframework.checker.signedness.qual.PolySigned in project checker-framework by typetools.

the class SignednessVisitor method visitCompoundAssignment.

/**
 * Enforces the following rules on compound assignments involving Unsigned and Signed types:
 *
 * <ul>
 *   <li>Do not allow any Unsigned types or PolySigned types in {@literal {/=, %=}} assignments.
 *   <li>Do not allow signed right shift {@literal {>>=}} to assign to an Unsigned type or a
 *       PolySigned type.
 *   <li>Do not allow unsigned right shift {@literal {>>>=}} to assign to a Signed type or a
 *       PolySigned type.
 *   <li>Allow any left shift {@literal {<<=}} assignment.
 *   <li>Do not allow mixing of Signed and Unsigned types.
 * </ul>
 */
@Override
public Void visitCompoundAssignment(CompoundAssignmentTree node, Void p) {
    ExpressionTree var = node.getVariable();
    ExpressionTree expr = node.getExpression();
    Pair<AnnotatedTypeMirror, AnnotatedTypeMirror> argTypes = atypeFactory.compoundAssignmentTreeArgTypes(node);
    AnnotatedTypeMirror varType = argTypes.first;
    AnnotatedTypeMirror exprType = argTypes.second;
    Tree.Kind kind = node.getKind();
    switch(kind) {
        case DIVIDE_ASSIGNMENT:
        case REMAINDER_ASSIGNMENT:
            if (hasUnsignedAnnotation(varType)) {
                checker.reportError(var, "compound.assignment.unsigned.variable", kindWithoutAssignment(kind), varType, exprType);
            } else if (hasUnsignedAnnotation(exprType)) {
                checker.reportError(expr, "compound.assignment.unsigned.expression", kindWithoutAssignment(kind), varType, exprType);
            }
            break;
        case RIGHT_SHIFT_ASSIGNMENT:
            if (hasUnsignedAnnotation(varType)) {
                checker.reportError(var, "compound.assignment.shift.signed", kindWithoutAssignment(kind), varType, exprType);
            }
            break;
        case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
            if (hasSignedAnnotation(varType)) {
                checker.reportError(var, "compound.assignment.shift.unsigned", kindWithoutAssignment(kind), varType, exprType);
            }
            break;
        case LEFT_SHIFT_ASSIGNMENT:
            break;
        case PLUS_ASSIGNMENT:
            if (TreeUtils.isStringCompoundConcatenation(node)) {
                if (exprType.getKind() != TypeKind.CHAR && !TypesUtils.isDeclaredOfName(exprType.getUnderlyingType(), "java.lang.Character")) {
                    AnnotationMirror anno = exprType.getEffectiveAnnotations().iterator().next();
                    if (!atypeFactory.getQualifierHierarchy().isSubtype(anno, atypeFactory.SIGNED)) {
                        checker.reportError(node.getExpression(), "unsigned.concat");
                    }
                }
                break;
            }
        // fall through
        default:
            if (varType.hasAnnotation(Unsigned.class) && exprType.hasAnnotation(Signed.class)) {
                checker.reportError(expr, "compound.assignment.mixed.unsigned.variable", kindWithoutAssignment(kind), varType, exprType);
            } else if (varType.hasAnnotation(Signed.class) && exprType.hasAnnotation(Unsigned.class)) {
                checker.reportError(expr, "compound.assignment.mixed.unsigned.expression", kindWithoutAssignment(kind), varType, exprType);
            }
            break;
    }
    return super.visitCompoundAssignment(node, p);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) Unsigned(org.checkerframework.checker.signedness.qual.Unsigned) Signed(org.checkerframework.checker.signedness.qual.Signed) PolySigned(org.checkerframework.checker.signedness.qual.PolySigned) ExpressionTree(com.sun.source.tree.ExpressionTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) ExpressionTree(com.sun.source.tree.ExpressionTree) BinaryTree(com.sun.source.tree.BinaryTree) Tree(com.sun.source.tree.Tree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

BinaryTree (com.sun.source.tree.BinaryTree)2 CompoundAssignmentTree (com.sun.source.tree.CompoundAssignmentTree)2 ExpressionTree (com.sun.source.tree.ExpressionTree)2 Tree (com.sun.source.tree.Tree)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 PolySigned (org.checkerframework.checker.signedness.qual.PolySigned)2 Signed (org.checkerframework.checker.signedness.qual.Signed)2 Unsigned (org.checkerframework.checker.signedness.qual.Unsigned)2 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)2