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);
}
Aggregations