use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class UpperBoundTransfer method refineSubtrahendWithOffset.
/**
* Refines the subtrahend in a subtraction which is greater than or equal to a certain offset.
* The type of the subtrahend is refined to the type of the minuend with the offset added. This
* is case 10.
*
* <p>This is based on the fact that if {@code (minuend - subtrahend) >= offset}, and {@code
* minuend + o < l}, then {@code subtrahend + o + offset < l}.
*
* <p>If {@code gtNode} is not a {@link NumericalSubtractionNode}, the method does nothing.
*
* @param gtNode the node that is greater or equal to the offset
* @param offsetNode a node part of the offset
* @param offsetAddOne whether to add one to the offset
* @param in input of the transfer function
* @param store location to store the refined types
*/
private void refineSubtrahendWithOffset(Node gtNode, Node offsetNode, boolean offsetAddOne, TransferInput<CFValue, CFStore> in, CFStore store) {
if (gtNode instanceof NumericalSubtractionNode) {
NumericalSubtractionNode subtractionNode = (NumericalSubtractionNode) gtNode;
Node minuend = subtractionNode.getLeftOperand();
UBQualifier minuendQual = getUBQualifier(minuend, in);
Node subtrahend = subtractionNode.getRightOperand();
UBQualifier subtrahendQual = getUBQualifier(subtrahend, in);
UBQualifier newQual = subtrahendQual.glb(minuendQual.plusOffset(offsetNode, atypeFactory).plusOffset(offsetAddOne ? 1 : 0));
Receiver subtrahendRec = FlowExpressions.internalReprOf(atypeFactory, subtrahend);
store.insertValue(subtrahendRec, atypeFactory.convertUBQualifierToAnnotation(newQual));
}
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class UpperBoundTransfer method getUBQualifier.
/**
* Returns the UBQualifier for node. It does this by finding a {@link CFValue} for node. First
* it checks the store in the transfer input. If one isn't there, the analysis is checked. If
* the UNKNOWN qualifier is returned, then the AnnotatedTypeMirror from the type factory is
* used.
*
* @param n node
* @param in transfer input
* @return the UBQualifier for node
*/
private UBQualifier getUBQualifier(Node n, TransferInput<CFValue, CFStore> in) {
QualifierHierarchy hierarchy = analysis.getTypeFactory().getQualifierHierarchy();
Receiver rec = FlowExpressions.internalReprOf(atypeFactory, n);
CFValue value = null;
if (CFAbstractStore.canInsertReceiver(rec)) {
value = in.getRegularStore().getValue(rec);
}
if (value == null) {
value = analysis.getValue(n);
}
UBQualifier qualifier = getUBQualifier(hierarchy, value);
if (qualifier.isUnknown()) {
// The qualifier from the store or analysis might be UNKNOWN if there was some error.
// For example,
// @LTLength("a") int i = 4; // error
// The type of i in the store is @UpperBoundUnknown, but the type of i as computed by
// the type factory is @LTLength("a"), so use that type.
CFValue valueFromFactory = getValueFromFactory(n.getTree(), n);
return getUBQualifier(hierarchy, valueFromFactory);
}
return qualifier;
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class UpperBoundTransfer method refineGTE.
/**
* Case 9: if x ≤ y, and y has a type that is related to the length of an array, then x has
* the same type.
*/
@Override
protected void refineGTE(Node left, AnnotationMirror leftAnno, Node right, AnnotationMirror rightAnno, CFStore store, TransferInput<CFValue, CFStore> in) {
UBQualifier leftQualifier = UBQualifier.createUBQualifier(leftAnno);
UBQualifier rightQualifier = UBQualifier.createUBQualifier(rightAnno);
UBQualifier refinedRight = rightQualifier.glb(leftQualifier);
if (leftQualifier.isLessThanLengthQualifier()) {
propagateToOperands((LessThanLengthOf) leftQualifier, right, in, store);
}
refineSubtrahendWithOffset(left, right, false, in, store);
Receiver rightRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), right);
store.insertValue(rightRec, atypeFactory.convertUBQualifierToAnnotation(refinedRight));
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class UpperBoundTransfer method propagateToMultiplicationOperand.
/**
* {@code other} times {@code node} is known to be {@code typeOfMultiplication}.
*
* <p>This implies that if {@code other} is positive, then {@code node} is {@code
* typeOfMultiplication}. If {@code other} is greater than 1, then {@code node} is {@code
* typeOfMultiplication} plus 1. These are cases 2 and 3, respectively.
*/
private void propagateToMultiplicationOperand(LessThanLengthOf typeOfMultiplication, Node node, Node other, TransferInput<CFValue, CFStore> in, CFStore store) {
if (atypeFactory.hasLowerBoundTypeByClass(other, Positive.class)) {
Long minValue = IndexUtil.getMinValue(other.getTree(), atypeFactory.getValueAnnotatedTypeFactory());
if (minValue != null && minValue > 1) {
typeOfMultiplication = (LessThanLengthOf) typeOfMultiplication.plusOffset(1);
}
UBQualifier qual = getUBQualifier(node, in);
UBQualifier newQual = qual.glb(typeOfMultiplication);
Receiver rec = FlowExpressions.internalReprOf(atypeFactory, node);
store.insertValue(rec, atypeFactory.convertUBQualifierToAnnotation(newQual));
}
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class UpperBoundTransfer method propagateToSubtractionOperands.
/**
* The subtraction node, {@code node}, is known to be {@code typeOfSubtraction}.
*
* <p>This means that the left node is less than or equal to the length of the array when the
* right node is subtracted from the left node. Note that unlike {@link
* #propagateToAdditionOperand(LessThanLengthOf, Node, Node, TransferInput, CFStore)} and {@link
* #propagateToMultiplicationOperand(LessThanLengthOf, Node, Node, TransferInput, CFStore)},
* this method takes the NumericalSubtractionNode instead of the two operand nodes. This
* implements case 4.
*
* @param typeOfSubtraction type of node
* @param node subtraction node that has typeOfSubtraction
* @param in TransferInput
* @param store location to store the refined type
*/
private void propagateToSubtractionOperands(LessThanLengthOf typeOfSubtraction, NumericalSubtractionNode node, TransferInput<CFValue, CFStore> in, CFStore store) {
UBQualifier left = getUBQualifier(node.getLeftOperand(), in);
UBQualifier newInfo = typeOfSubtraction.minusOffset(node.getRightOperand(), atypeFactory);
UBQualifier newLeft = left.glb(newInfo);
Receiver leftRec = FlowExpressions.internalReprOf(atypeFactory, node.getLeftOperand());
store.insertValue(leftRec, atypeFactory.convertUBQualifierToAnnotation(newLeft));
}
Aggregations