Search in sources :

Example 21 with Range

use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.

the class ValueTransfer method calculateRangeBinaryOp.

/**
 * Calculate the result range after a binary operation between two numerical type nodes
 */
private Range calculateRangeBinaryOp(Node leftNode, Node rightNode, NumericalBinaryOps op, TransferInput<CFValue, CFStore> p) {
    if (TypesUtils.isIntegral(leftNode.getType()) && TypesUtils.isIntegral(rightNode.getType())) {
        Range leftRange = getIntRange(leftNode, p);
        Range rightRange = getIntRange(rightNode, p);
        Range resultRange;
        switch(op) {
            case ADDITION:
                resultRange = leftRange.plus(rightRange);
                break;
            case SUBTRACTION:
                resultRange = leftRange.minus(rightRange);
                break;
            case MULTIPLICATION:
                resultRange = leftRange.times(rightRange);
                break;
            case DIVISION:
                resultRange = leftRange.divide(rightRange);
                break;
            case REMAINDER:
                resultRange = leftRange.remainder(rightRange);
                break;
            case SHIFT_LEFT:
                resultRange = leftRange.shiftLeft(rightRange);
                break;
            case SIGNED_SHIFT_RIGHT:
                resultRange = leftRange.signedShiftRight(rightRange);
                break;
            case UNSIGNED_SHIFT_RIGHT:
                resultRange = leftRange.unsignedShiftRight(rightRange);
                break;
            case BITWISE_AND:
                resultRange = leftRange.bitwiseAnd(rightRange);
                break;
            case BITWISE_OR:
                resultRange = leftRange.bitwiseOr(rightRange);
                break;
            case BITWISE_XOR:
                resultRange = leftRange.bitwiseXor(rightRange);
                break;
            default:
                ErrorReporter.errorAbort("ValueTransfer: unsupported operation: " + op);
                throw new RuntimeException("this can't happen");
        }
        // operations.
        return leftNode.getType().getKind() == TypeKind.LONG || rightNode.getType().getKind() == TypeKind.LONG ? resultRange : resultRange.intRange();
    } else {
        return Range.EVERYTHING;
    }
}
Also used : ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) Range(org.checkerframework.common.value.util.Range)

Example 22 with Range

use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.

the class ValueVisitor method visitTypeCast.

@Override
public Void visitTypeCast(TypeCastTree node, Void p) {
    if (node.getExpression().getKind() == Kind.NULL_LITERAL) {
        return null;
    }
    AnnotatedTypeMirror castType = atypeFactory.getAnnotatedType(node);
    AnnotationMirror castAnno = castType.getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL);
    AnnotationMirror exprAnno = atypeFactory.getAnnotatedType(node.getExpression()).getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL);
    // to a @IntRange(from = Byte.MIN_VALUE, to = Byte.MAX_VALUE byte).
    if (castAnno != null && exprAnno != null && atypeFactory.isIntRange(castAnno) && atypeFactory.isIntRange(exprAnno)) {
        Range castRange = ValueAnnotatedTypeFactory.getRange(castAnno);
        if (castType.getKind() == TypeKind.BYTE && castRange.isByteEverything()) {
            return p;
        }
        if (castType.getKind() == TypeKind.SHORT && castRange.isShortEverything()) {
            return p;
        }
        if (castType.getKind() == TypeKind.INT && castRange.isIntEverything()) {
            return p;
        }
        if (castType.getKind() == TypeKind.LONG && castRange.isLongEverything()) {
            return p;
        }
        if (Range.IGNORE_OVERFLOW) {
            // Range.IGNORE_OVERFLOW is only set if this checker is ignoring overflow.
            // In that case, do not warn if the range of the expression encompasses
            // the whole type being casted to (i.e. the warning is actually about overflow).
            Range exprRange = ValueAnnotatedTypeFactory.getRange(exprAnno);
            switch(castType.getKind()) {
                case BYTE:
                    exprRange = exprRange.byteRange();
                    break;
                case SHORT:
                    exprRange = exprRange.shortRange();
                    break;
                case INT:
                    exprRange = exprRange.intRange();
                    break;
                default:
            }
            if (castRange.equals(exprRange)) {
                return p;
            }
        }
    }
    return super.visitTypeCast(node, p);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) Range(org.checkerframework.common.value.util.Range) IntRange(org.checkerframework.common.value.qual.IntRange) ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

Range (org.checkerframework.common.value.util.Range)22 ArrayLenRange (org.checkerframework.common.value.qual.ArrayLenRange)15 IntRange (org.checkerframework.common.value.qual.IntRange)7 ArrayList (java.util.ArrayList)6 AnnotationMirror (javax.lang.model.element.AnnotationMirror)6 CFValue (org.checkerframework.framework.flow.CFValue)4 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)4 List (java.util.List)3 StringConversionNode (org.checkerframework.dataflow.cfg.node.StringConversionNode)3 TypeKind (javax.lang.model.type.TypeKind)2 IntVal (org.checkerframework.common.value.qual.IntVal)2 Test (org.junit.Test)2 ArrayLen (org.checkerframework.common.value.qual.ArrayLen)1 BottomVal (org.checkerframework.common.value.qual.BottomVal)1 DoubleVal (org.checkerframework.common.value.qual.DoubleVal)1 StringVal (org.checkerframework.common.value.qual.StringVal)1 UnknownVal (org.checkerframework.common.value.qual.UnknownVal)1