Search in sources :

Example 11 with Range

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

the class ValueTransfer method createAnnotationForStringConcatenation.

/**
 * Creates an annotation for a result of string concatenation.
 */
private AnnotationMirror createAnnotationForStringConcatenation(Node leftOperand, Node rightOperand, TransferInput<CFValue, CFStore> p) {
    // Try using sets of string values
    List<String> leftValues = getStringValues(leftOperand, p);
    List<String> rightValues = getStringValues(rightOperand, p);
    if (leftValues != null && rightValues != null) {
        // Both operands have known string values, compute set of results
        List<String> concatValues = new ArrayList<>();
        if (leftValues.isEmpty()) {
            leftValues = Collections.singletonList("null");
        }
        if (rightValues.isEmpty()) {
            rightValues = Collections.singletonList("null");
        }
        for (String left : leftValues) {
            for (String right : rightValues) {
                concatValues.add(left + right);
            }
        }
        return atypefactory.createStringAnnotation(concatValues);
    }
    // Try using sets of lengths
    List<Integer> leftLengths = leftValues != null ? ValueCheckerUtils.getLengthsForStringValues(leftValues) : getStringLengths(leftOperand, p);
    List<Integer> rightLengths = rightValues != null ? ValueCheckerUtils.getLengthsForStringValues(rightValues) : getStringLengths(rightOperand, p);
    if (leftLengths != null && rightLengths != null) {
        // Both operands have known lengths, compute set of result lengths
        List<Integer> concatLengths = calculateLengthAddition(leftLengths, rightLengths);
        return atypefactory.createArrayLenAnnotation(concatLengths);
    }
    // Try using ranges of lengths
    Range leftLengthRange = leftLengths != null ? ValueCheckerUtils.getRangeFromValues(leftLengths) : getStringLengthRange(leftOperand, p);
    Range rightLengthRange = rightLengths != null ? ValueCheckerUtils.getRangeFromValues(rightLengths) : getStringLengthRange(rightOperand, p);
    if (leftLengthRange != null && rightLengthRange != null) {
        // Both operands have a length from a known range, compute a range of result lengths
        Range concatLengthRange = calculateLengthRangeAddition(leftLengthRange, rightLengthRange);
        return atypefactory.createArrayLenRangeAnnotation(concatLengthRange);
    }
    return atypefactory.UNKNOWNVAL;
}
Also used : ArrayList(java.util.ArrayList) ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) Range(org.checkerframework.common.value.util.Range)

Example 12 with Range

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

the class ValueTransfer method refineIntRanges.

/**
 * Calculates the result of a binary comparison on a pair of intRange annotations, and refines
 * annotations appropriately.
 */
private List<Boolean> refineIntRanges(Node leftNode, AnnotationMirror leftAnno, Node rightNode, AnnotationMirror rightAnno, ComparisonOperators op, CFStore thenStore, CFStore elseStore) {
    Range leftRange = getIntRangeFromAnnotation(leftNode, leftAnno);
    Range rightRange = getIntRangeFromAnnotation(rightNode, rightAnno);
    final Range thenRightRange;
    final Range thenLeftRange;
    final Range elseRightRange;
    final Range elseLeftRange;
    switch(op) {
        case EQUAL:
            thenRightRange = rightRange.refineEqualTo(leftRange);
            // Only needs to be computed once.
            thenLeftRange = thenRightRange;
            elseRightRange = rightRange.refineNotEqualTo(leftRange);
            elseLeftRange = leftRange.refineNotEqualTo(rightRange);
            break;
        case GREATER_THAN:
            thenLeftRange = leftRange.refineGreaterThan(rightRange);
            thenRightRange = rightRange.refineLessThan(leftRange);
            elseRightRange = rightRange.refineGreaterThanEq(leftRange);
            elseLeftRange = leftRange.refineLessThanEq(rightRange);
            break;
        case GREATER_THAN_EQ:
            thenRightRange = rightRange.refineLessThanEq(leftRange);
            thenLeftRange = leftRange.refineGreaterThanEq(rightRange);
            elseLeftRange = leftRange.refineLessThan(rightRange);
            elseRightRange = rightRange.refineGreaterThan(leftRange);
            break;
        case LESS_THAN:
            thenLeftRange = leftRange.refineLessThan(rightRange);
            thenRightRange = rightRange.refineGreaterThan(leftRange);
            elseRightRange = rightRange.refineLessThanEq(leftRange);
            elseLeftRange = leftRange.refineGreaterThanEq(rightRange);
            break;
        case LESS_THAN_EQ:
            thenRightRange = rightRange.refineGreaterThanEq(leftRange);
            thenLeftRange = leftRange.refineLessThanEq(rightRange);
            elseLeftRange = leftRange.refineGreaterThan(rightRange);
            elseRightRange = rightRange.refineLessThan(leftRange);
            break;
        case NOT_EQUAL:
            thenRightRange = rightRange.refineNotEqualTo(leftRange);
            thenLeftRange = leftRange.refineNotEqualTo(rightRange);
            elseRightRange = rightRange.refineEqualTo(leftRange);
            // Equality only needs to be computed once.
            elseLeftRange = elseRightRange;
            break;
        default:
            ErrorReporter.errorAbort("ValueTransfer: unsupported operation: " + op);
            throw new RuntimeException("this is impossible, but javac issues a warning");
    }
    createAnnotationFromRangeAndAddToStore(thenStore, thenRightRange, rightNode);
    createAnnotationFromRangeAndAddToStore(thenStore, thenLeftRange, leftNode);
    createAnnotationFromRangeAndAddToStore(elseStore, elseRightRange, rightNode);
    createAnnotationFromRangeAndAddToStore(elseStore, elseLeftRange, leftNode);
    // TODO: Refine the type of the comparison.
    return null;
}
Also used : ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) Range(org.checkerframework.common.value.util.Range)

Example 13 with Range

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

the class ValueTransfer method getIntRangeFromAnnotation.

private Range getIntRangeFromAnnotation(Node node, AnnotationMirror val) {
    Range range;
    if (val == null || AnnotationUtils.areSameByClass(val, UnknownVal.class)) {
        range = Range.EVERYTHING;
    } else if (atypefactory.isIntRange(val)) {
        range = ValueAnnotatedTypeFactory.getRange(val);
    } else if (AnnotationUtils.areSameByClass(val, IntVal.class)) {
        List<Long> values = ValueAnnotatedTypeFactory.getIntValues(val);
        range = ValueCheckerUtils.getRangeFromValues(values);
    } else if (AnnotationUtils.areSameByClass(val, DoubleVal.class)) {
        List<Double> values = ValueAnnotatedTypeFactory.getDoubleValues(val);
        range = ValueCheckerUtils.getRangeFromValues(values);
    } else if (AnnotationUtils.areSameByClass(val, BottomVal.class)) {
        return Range.NOTHING;
    } else {
        range = Range.EVERYTHING;
    }
    return NumberUtils.castRange(node.getType(), range);
}
Also used : DoubleVal(org.checkerframework.common.value.qual.DoubleVal) UnknownVal(org.checkerframework.common.value.qual.UnknownVal) List(java.util.List) ArrayList(java.util.ArrayList) ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) Range(org.checkerframework.common.value.util.Range)

Example 14 with Range

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

the class IndexUtil method getMinValue.

/**
 * Finds the minimum value in a Value Checker type. If there is no information (such as when the
 * list of possible values is empty or null), returns null. Otherwise, returns the smallest
 * value in the list of possible values.
 */
public static Long getMinValue(Tree tree, ValueAnnotatedTypeFactory factory) {
    AnnotatedTypeMirror valueType = factory.getAnnotatedType(tree);
    Range possibleValues = getPossibleValues(valueType, factory);
    if (possibleValues != null) {
        return possibleValues.from;
    } else {
        return null;
    }
}
Also used : Range(org.checkerframework.common.value.util.Range) IntRange(org.checkerframework.common.value.qual.IntRange) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 15 with Range

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

the class LowerBoundAnnotatedTypeFactory method getLowerBoundAnnotationFromValueType.

/**
 * Returns the type in the lower bound hierarchy that a Value Checker type corresponds to.
 */
private AnnotationMirror getLowerBoundAnnotationFromValueType(AnnotatedTypeMirror valueType) {
    Range possibleValues = getPossibleValues(valueType, getValueAnnotatedTypeFactory());
    // possibleValues is null if the Value Checker does not have any estimate.
    if (possibleValues == null) {
        // when there is a BottomVal annotation. In that case, give this the LBC's bottom type.
        if (AnnotationUtils.containsSameByClass(valueType.getAnnotations(), BottomVal.class)) {
            return BOTTOM;
        }
        return UNKNOWN;
    }
    // The annotation of the whole list is the min of the list.
    long lvalMin = possibleValues.from;
    // Turn it into an integer.
    int valMin = (int) Math.max(Math.min(Integer.MAX_VALUE, lvalMin), Integer.MIN_VALUE);
    return anmFromVal(valMin);
}
Also used : Range(org.checkerframework.common.value.util.Range)

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