use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class LessThanTransfer method refineGT.
/**
* Case 1.
*/
@Override
protected void refineGT(Node left, AnnotationMirror leftAnno, Node right, AnnotationMirror rightAnno, CFStore store, TransferInput<CFValue, CFStore> in) {
// left > right so right < left
// Refine right to @LessThan("left")
JavaExpression leftJe = JavaExpression.fromNode(left);
if (leftJe != null && leftJe.isUnassignableByOtherCode()) {
if (isDoubleOrFloatLiteral(leftJe)) {
return;
}
LessThanAnnotatedTypeFactory factory = (LessThanAnnotatedTypeFactory) analysis.getTypeFactory();
List<String> lessThanExpressions = factory.getLessThanExpressions(rightAnno);
if (lessThanExpressions == null) {
// right is already bottom, nothing to refine.
return;
}
String leftString = leftJe.toString();
if (!lessThanExpressions.contains(leftString)) {
lessThanExpressions = CollectionsPlume.append(lessThanExpressions, leftString);
JavaExpression rightJe = JavaExpression.fromNode(right);
store.insertValue(rightJe, factory.createLessThanQualifier(lessThanExpressions));
}
}
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class LessThanTransfer method visitNumericalSubtraction.
/**
* Case 3.
*/
@Override
public TransferResult<CFValue, CFStore> visitNumericalSubtraction(NumericalSubtractionNode n, TransferInput<CFValue, CFStore> in) {
LessThanAnnotatedTypeFactory factory = (LessThanAnnotatedTypeFactory) analysis.getTypeFactory();
JavaExpression leftJe = JavaExpression.fromNode(n.getLeftOperand());
if (leftJe != null && leftJe.isUnassignableByOtherCode()) {
ValueAnnotatedTypeFactory valueFactory = factory.getValueAnnotatedTypeFactory();
Long right = ValueCheckerUtils.getMinValue(n.getRightOperand().getTree(), valueFactory);
if (right != null && 0 < right) {
// left - right < left iff 0 < right
List<String> expressions = getLessThanExpressions(n.getLeftOperand());
if (!isDoubleOrFloatLiteral(leftJe)) {
if (expressions == null) {
expressions = Collections.singletonList(leftJe.toString());
} else {
expressions = CollectionsPlume.append(expressions, leftJe.toString());
}
}
AnnotationMirror refine = factory.createLessThanQualifier(expressions);
CFValue value = analysis.createSingleAnnotationValue(refine, n.getType());
CFStore info = in.getRegularStore();
return new RegularTransferResult<>(finishValue(value, info), info);
}
}
return super.visitNumericalSubtraction(n, in);
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class SameLenTransfer method refineEq.
/**
* Handles refinement of equality comparisons. Assumes "a == b" or "a.length == b.length"
* evaluates to true. The method gives a and b SameLen of each other in the store.
*
* @param left the first argument to the equality operator
* @param right the second argument to the equality operator
* @param store the store in which to perform refinement
*/
private void refineEq(Node left, Node right, CFStore store) {
List<JavaExpression> exprs = new ArrayList<>(2);
List<AnnotationMirror> annos = new ArrayList<>(2);
for (Node internal : splitAssignments(left)) {
exprs.add(JavaExpression.fromNode(internal));
annos.add(getAnno(internal));
}
for (Node internal : splitAssignments(right)) {
exprs.add(JavaExpression.fromNode(internal));
annos.add(getAnno(internal));
}
AnnotationMirror combinedSameLen = aTypeFactory.createCombinedSameLen(exprs, annos);
propagateCombinedSameLen(combinedSameLen, left, store);
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class SameLenTransfer method visitAssignment.
@Override
public TransferResult<CFValue, CFStore> visitAssignment(AssignmentNode node, TransferInput<CFValue, CFStore> in) {
TransferResult<CFValue, CFStore> result = super.visitAssignment(node, in);
// Handle b = new T[a.length]
if (node.getExpression() instanceof ArrayCreationNode) {
ArrayCreationNode acNode = (ArrayCreationNode) node.getExpression();
if (acNode.getDimensions().size() == 1) {
Node lengthNode = acNode.getDimension(0);
Node lengthNodeReceiver = getLengthReceiver(lengthNode);
if (lengthNodeReceiver != null) {
// "new T[a.length]" or "new T[s.length()]" is the right hand side of the assignment.
// lengthNode is known to be "lengthNodeReceiver.length" or "lengthNodeReceiver.length()"
// targetRec is the receiver for the left hand side of the assignment.
JavaExpression targetRec = JavaExpression.fromNode(node.getTarget());
JavaExpression otherRec = JavaExpression.fromNode(lengthNodeReceiver);
AnnotationMirror lengthNodeAnnotation = aTypeFactory.getAnnotatedType(lengthNodeReceiver.getTree()).getAnnotationInHierarchy(UNKNOWN);
AnnotationMirror combinedSameLen = aTypeFactory.createCombinedSameLen(Arrays.asList(targetRec, otherRec), Arrays.asList(UNKNOWN, lengthNodeAnnotation));
propagateCombinedSameLen(combinedSameLen, node, result.getRegularStore());
return result;
}
}
}
AnnotationMirror rightAnno = aTypeFactory.getAnnotatedType(node.getExpression().getTree()).getAnnotationInHierarchy(UNKNOWN);
// If the left side of the assignment is an array or a string, then have both the right and
// left side be SameLen of each other.
JavaExpression targetRec = JavaExpression.fromNode(node.getTarget());
JavaExpression exprRec = JavaExpression.fromNode(node.getExpression());
if (IndexUtil.isSequenceType(node.getTarget().getType()) || (rightAnno != null && aTypeFactory.areSameByClass(rightAnno, SameLen.class))) {
AnnotationMirror rightAnnoOrUnknown = rightAnno == null ? UNKNOWN : rightAnno;
AnnotationMirror combinedSameLen = aTypeFactory.createCombinedSameLen(Arrays.asList(targetRec, exprRec), Arrays.asList(UNKNOWN, rightAnnoOrUnknown));
propagateCombinedSameLen(combinedSameLen, node, result.getRegularStore());
}
return result;
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class CFAbstractStore method removeConflicting.
/**
* Remove any information in the store that might not be true any more after {@code arrayAccess}
* has been assigned a new value (with the abstract value {@code val}). This includes the
* following steps (assume that {@code arrayAccess} is of the form <em>a[i]</em> for some
* <em>a</em>.
*
* <ol>
* <li value="1">Remove any abstract value for other array access <em>b[j]</em> where <em>a</em>
* and <em>b</em> can be aliases, or where either <em>b</em> or <em>j</em> contains a
* modifiable alias of <em>a[i]</em>.
* <li value="2">Remove any abstract values for field accesses <em>b.g</em> where <em>a[i]</em>
* might alias any expression in the receiver <em>b</em> and there is an array expression
* somewhere in the receiver.
* <li value="3">Remove any information about method calls.
* </ol>
*
* @param val the abstract value of the value assigned to {@code n} (or {@code null} if the
* abstract value is not known).
*/
protected void removeConflicting(ArrayAccess arrayAccess, @Nullable V val) {
final Iterator<Map.Entry<ArrayAccess, V>> arrayValuesIterator = arrayValues.entrySet().iterator();
while (arrayValuesIterator.hasNext()) {
Map.Entry<ArrayAccess, V> entry = arrayValuesIterator.next();
ArrayAccess otherArrayAccess = entry.getKey();
// case 1:
if (otherArrayAccess.containsModifiableAliasOf(this, arrayAccess)) {
// remove information completely
arrayValuesIterator.remove();
} else if (canAlias(arrayAccess.getArray(), otherArrayAccess.getArray())) {
// TODO: one could be less strict here, and only raise the abstract
// value for all array expressions with potentially aliasing receivers.
// remove information completely
arrayValuesIterator.remove();
}
}
// case 2:
final Iterator<Map.Entry<FieldAccess, V>> fieldValuesIterator = fieldValues.entrySet().iterator();
while (fieldValuesIterator.hasNext()) {
Map.Entry<FieldAccess, V> entry = fieldValuesIterator.next();
FieldAccess otherFieldAccess = entry.getKey();
JavaExpression otherReceiver = otherFieldAccess.getReceiver();
if (otherReceiver.containsModifiableAliasOf(this, arrayAccess) && otherReceiver.containsOfClass(ArrayAccess.class)) {
// remove information completely
fieldValuesIterator.remove();
}
}
// case 3:
methodValues.clear();
}
Aggregations