Search in sources :

Example 1 with Subsequence

use of org.checkerframework.checker.index.Subsequence 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)

Example 2 with Subsequence

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

the class UpperBoundVisitor method processSubsequenceForLHS.

/* Returns the new value of the left hand side after processing the arrays named in the lhs.
   * Iff varLtlQual includes LTL(lhsSeq),
   * lhsSeq has HSS, and expQual includes LTL(a, -from), then the LTL(lhsSeq) will be removed from varLtlQual
   */
private UBQualifier processSubsequenceForLHS(LessThanLengthOf varLtlQual, UBQualifier expQual) {
    UBQualifier newLHS = varLtlQual;
    for (String lhsSeq : varLtlQual.getSequences()) {
        // check is lhsSeq is an actual LTL
        if (varLtlQual.hasSequenceWithOffset(lhsSeq, 0)) {
            JavaExpression lhsSeqExpr = parseJavaExpressionString(lhsSeq, atypeFactory, getCurrentPath());
            Subsequence subSeq = Subsequence.getSubsequenceFromReceiver(lhsSeqExpr, atypeFactory);
            if (subSeq != null) {
                String from = subSeq.from;
                String a = subSeq.array;
                if (expQual.hasSequenceWithOffset(a, Subsequence.negateString(from))) {
                    // This cast is safe because LTLs cannot contain duplicates.
                    // Note that this updates newLHS on each iteration from its old value,
                    // so even if there are multiple HSS arrays the result will be correct.
                    newLHS = ((LessThanLengthOf) newLHS).removeOffset(lhsSeq, 0);
                }
            }
        }
    }
    return newLHS;
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) HasSubsequence(org.checkerframework.checker.index.qual.HasSubsequence) Subsequence(org.checkerframework.checker.index.Subsequence)

Example 3 with Subsequence

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

the class UpperBoundVisitor method commonAssignmentCheck.

@Override
protected void commonAssignmentCheck(Tree varTree, ExpressionTree valueTree, @CompilerMessageKey String errorKey, Object... extraArgs) {
    // check that when an assignment to a variable b declared as @HasSubsequence(a, from, to)
    // occurs, to <= a.length, i.e. to is @LTEqLengthOf(a).
    Subsequence subSeq = Subsequence.getSubsequenceFromTree(varTree, atypeFactory);
    if (subSeq != null) {
        AnnotationMirror anm;
        try {
            anm = atypeFactory.getAnnotationMirrorFromJavaExpressionString(subSeq.to, varTree, getCurrentPath());
        } catch (JavaExpressionParseException e) {
            anm = null;
        }
        boolean ltelCheckFailed = true;
        if (anm != null) {
            UBQualifier qual = UBQualifier.createUBQualifier(anm, (UpperBoundChecker) checker);
            ltelCheckFailed = !qual.isLessThanOrEqualTo(subSeq.array);
        }
        if (ltelCheckFailed) {
            // issue an error
            checker.reportError(valueTree, TO_NOT_LTEL, subSeq.to, subSeq.array, anm == null ? "@UpperBoundUnknown" : anm, subSeq.array, subSeq.array, subSeq.array);
        } else {
            checker.reportWarning(valueTree, HSS, subSeq.array, subSeq.from, subSeq.from, subSeq.to, subSeq.to, subSeq.array, subSeq.array);
        }
    }
    super.commonAssignmentCheck(varTree, valueTree, errorKey, extraArgs);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) HasSubsequence(org.checkerframework.checker.index.qual.HasSubsequence) Subsequence(org.checkerframework.checker.index.Subsequence) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException)

Example 4 with Subsequence

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

the class LowerBoundVisitor method commonAssignmentCheck.

@Override
protected void commonAssignmentCheck(Tree varTree, ExpressionTree valueTree, @CompilerMessageKey String errorKey, Object... extraArgs) {
    // check that when an assignment to a variable declared as @HasSubsequence(a, from, to)
    // occurs, from is non-negative.
    Subsequence subSeq = Subsequence.getSubsequenceFromTree(varTree, atypeFactory);
    if (subSeq != null) {
        AnnotationMirror anm;
        try {
            anm = atypeFactory.getAnnotationMirrorFromJavaExpressionString(subSeq.from, varTree, getCurrentPath());
        } catch (JavaExpressionParseUtil.JavaExpressionParseException e) {
            anm = null;
        }
        if (anm == null || !(atypeFactory.areSameByClass(anm, NonNegative.class) || atypeFactory.areSameByClass(anm, Positive.class))) {
            checker.reportError(valueTree, FROM_NOT_NN, subSeq.from, anm == null ? "@LowerBoundUnknown" : anm);
        }
    }
    super.commonAssignmentCheck(varTree, valueTree, errorKey, extraArgs);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpressionParseUtil(org.checkerframework.framework.util.JavaExpressionParseUtil) Subsequence(org.checkerframework.checker.index.Subsequence)

Example 5 with Subsequence

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

the class LessThanVisitor method commonAssignmentCheck.

@Override
protected void commonAssignmentCheck(Tree varTree, ExpressionTree valueTree, @CompilerMessageKey String errorKey, Object... extraArgs) {
    // check that when an assignment to a variable declared as @HasSubsequence(a, from, to)
    // occurs, from <= to.
    Subsequence subSeq = Subsequence.getSubsequenceFromTree(varTree, atypeFactory);
    if (subSeq != null) {
        AnnotationMirror anm;
        try {
            anm = atypeFactory.getAnnotationMirrorFromJavaExpressionString(subSeq.from, varTree, getCurrentPath());
        } catch (JavaExpressionParseUtil.JavaExpressionParseException e) {
            anm = null;
        }
        LessThanAnnotatedTypeFactory factory = getTypeFactory();
        if (anm == null || !factory.isLessThanOrEqual(anm, subSeq.to)) {
            // issue an error
            checker.reportError(valueTree, FROM_GT_TO, subSeq.from, subSeq.to, anm == null ? "@LessThanUnknown" : anm, subSeq.to, subSeq.to);
        }
    }
    super.commonAssignmentCheck(varTree, valueTree, errorKey, extraArgs);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpressionParseUtil(org.checkerframework.framework.util.JavaExpressionParseUtil) Subsequence(org.checkerframework.checker.index.Subsequence)

Aggregations

Subsequence (org.checkerframework.checker.index.Subsequence)5 AnnotationMirror (javax.lang.model.element.AnnotationMirror)4 HasSubsequence (org.checkerframework.checker.index.qual.HasSubsequence)2 JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)2 JavaExpressionParseUtil (org.checkerframework.framework.util.JavaExpressionParseUtil)2 TreePath (com.sun.source.util.TreePath)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 JavaExpressionParseException (org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException)1 StringToJavaExpression (org.checkerframework.framework.util.StringToJavaExpression)1