Search in sources :

Example 1 with LessThanAnnotatedTypeFactory

use of org.checkerframework.checker.index.inequality.LessThanAnnotatedTypeFactory in project checker-framework by typetools.

the class UpperBoundTransfer method visitNumericalSubtraction.

/**
 * If some Node a is known to be less than the length of some sequence x, then the type of a - b
 * is @LTLengthOf(value="x", offset="b"). If b is known to be less than the length of some other
 * sequence, this doesn't add any information about the type of a - b. But, if b is non-negative
 * or positive, then a - b should keep the types of a. This corresponds to cases 16 and 17.
 */
@Override
public TransferResult<CFValue, CFStore> visitNumericalSubtraction(NumericalSubtractionNode n, TransferInput<CFValue, CFStore> in) {
    UBQualifier left = getUBQualifier(n.getLeftOperand(), in);
    UBQualifier leftWithOffset = left.plusOffset(n.getRightOperand(), atypeFactory);
    if (atypeFactory.hasLowerBoundTypeByClass(n.getRightOperand(), NonNegative.class) || atypeFactory.hasLowerBoundTypeByClass(n.getRightOperand(), Positive.class)) {
        // annotations should be kept.
        if (left.isLessThanLengthQualifier()) {
            leftWithOffset = left.glb(leftWithOffset);
        }
    }
    if (leftWithOffset.isLessThanLengthQualifier()) {
        LessThanLengthOf subtractionResult = (LessThanLengthOf) leftWithOffset;
        for (String b : subtractionResult.getSequences()) {
            if (subtractionResult.hasSequenceWithOffset(b, -1) || subtractionResult.hasSequenceWithOffset(b, 0)) {
                TreePath currentPath = this.atypeFactory.getPath(n.getTree());
                JavaExpression je;
                try {
                    je = UpperBoundVisitor.parseJavaExpressionString(b, atypeFactory, currentPath);
                } catch (NullPointerException npe) {
                    // optional, but useful elsewhere, catching this NPE here and returning is always safe.
                    return createTransferResult(n, in, leftWithOffset);
                }
                Subsequence subsequence = Subsequence.getSubsequenceFromReceiver(je, atypeFactory);
                if (subsequence != null) {
                    String from = subsequence.from;
                    String to = subsequence.to;
                    String a = subsequence.array;
                    JavaExpression leftOp = JavaExpression.fromNode(n.getLeftOperand());
                    JavaExpression rightOp = JavaExpression.fromNode(n.getRightOperand());
                    if (rightOp.toString().equals(from)) {
                        LessThanAnnotatedTypeFactory lessThanAtypeFactory = atypeFactory.getLessThanAnnotatedTypeFactory();
                        AnnotationMirror lessThanType = lessThanAtypeFactory.getAnnotatedType(n.getLeftOperand().getTree()).getAnnotation(LessThan.class);
                        if (lessThanType != null && lessThanAtypeFactory.isLessThan(lessThanType, to)) {
                            UBQualifier ltlA = UBQualifier.createUBQualifier(a, "0");
                            leftWithOffset = leftWithOffset.glb(ltlA);
                        } else if (leftOp.toString().equals(to) || (lessThanType != null && lessThanAtypeFactory.isLessThanOrEqual(lessThanType, to))) {
                            // It's necessary to check if leftOp == to because LessThan doesn't
                            // infer that things are less than or equal to themselves.
                            UBQualifier ltelA = UBQualifier.createUBQualifier(a, "-1");
                            leftWithOffset = leftWithOffset.glb(ltelA);
                        }
                    }
                }
            }
        }
    }
    return createTransferResult(n, in, leftWithOffset);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) TreePath(com.sun.source.util.TreePath) Positive(org.checkerframework.checker.index.qual.Positive) LessThanLengthOf(org.checkerframework.checker.index.upperbound.UBQualifier.LessThanLengthOf) Subsequence(org.checkerframework.checker.index.Subsequence) NonNegative(org.checkerframework.checker.index.qual.NonNegative) LessThanAnnotatedTypeFactory(org.checkerframework.checker.index.inequality.LessThanAnnotatedTypeFactory)

Aggregations

TreePath (com.sun.source.util.TreePath)1 AnnotationMirror (javax.lang.model.element.AnnotationMirror)1 Subsequence (org.checkerframework.checker.index.Subsequence)1 LessThanAnnotatedTypeFactory (org.checkerframework.checker.index.inequality.LessThanAnnotatedTypeFactory)1 NonNegative (org.checkerframework.checker.index.qual.NonNegative)1 Positive (org.checkerframework.checker.index.qual.Positive)1 LessThanLengthOf (org.checkerframework.checker.index.upperbound.UBQualifier.LessThanLengthOf)1 JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)1