use of org.checkerframework.checker.index.upperbound.UBQualifier.LessThanLengthOf in project checker-framework by typetools.
the class UpperBoundTransfer method visitAssignment.
/**
* Case 1: Refine the type of expressions used as an array dimension to be less than length of
* the array to which the new array is assigned. For example, in "int[] array = new int[expr];",
* the type of expr is @LTEqLength("array").
*/
@Override
public TransferResult<CFValue, CFStore> visitAssignment(AssignmentNode node, TransferInput<CFValue, CFStore> in) {
TransferResult<CFValue, CFStore> result = super.visitAssignment(node, in);
Node expNode = node.getExpression();
// strip off typecast if any
Node expNodeSansCast = (expNode instanceof TypeCastNode) ? ((TypeCastNode) expNode).getOperand() : expNode;
// null if right-hand-side is not an array creation expression
ArrayCreationNode acNode = (expNodeSansCast instanceof ArrayCreationNode) ? acNode = (ArrayCreationNode) expNodeSansCast : null;
if (acNode != null) {
// Right-hand side of assignment is an array creation expression
List<Node> nodeList = acNode.getDimensions();
if (nodeList.size() < 1) {
return result;
}
Node dim = acNode.getDimension(0);
UBQualifier previousQualifier = getUBQualifier(dim, in);
Receiver arrayRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), node.getTarget());
String arrayString = arrayRec.toString();
LessThanLengthOf newInfo = (LessThanLengthOf) UBQualifier.createUBQualifier(arrayString, "-1");
UBQualifier combined = previousQualifier.glb(newInfo);
AnnotationMirror newAnno = atypeFactory.convertUBQualifierToAnnotation(combined);
Receiver dimRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), dim);
result.getRegularStore().insertValue(dimRec, newAnno);
propagateToOperands(newInfo, dim, in, result.getRegularStore());
}
return result;
}
use of org.checkerframework.checker.index.upperbound.UBQualifier.LessThanLengthOf in project checker-framework by typetools.
the class UpperBoundVisitor method relaxedCommonAssignment.
/**
* Returns whether the assignment is legal based on the relaxed assignment rules.
*
* <p>The relaxed assignment rules is the following: Assuming the varType (left-hand side) is
* less than the length of some array given some offset
*
* <p>1. If both the offset and the value expression (rhs) are ints known at compile time, and
* if the min length of the array is greater than offset + value, then the assignment is legal.
* (This method returns true.)
*
* <p>2. If the value expression (rhs) is less than the length of an array that is the same
* length as the array in the varType, and if the offsets are equal, then the assignment is
* legal. (This method returns true.)
*
* <p>3. Otherwise the assignment is only legal if the usual assignment rules are true, so this
* method returns false.
*
* <p>If the varType is less than the length of multiple arrays, then the this method only
* returns true if the relaxed rules above apply for each array.
*
* <p>If the varType is an array type and the value express is an array initializer, then the
* above rules are applied for expression in the initializer where the varType is the component
* type of the array.
*/
private boolean relaxedCommonAssignment(AnnotatedTypeMirror varType, ExpressionTree valueExp) {
List<? extends ExpressionTree> expressions;
if (valueExp.getKind() == Kind.NEW_ARRAY && varType.getKind() == TypeKind.ARRAY) {
expressions = ((NewArrayTree) valueExp).getInitializers();
if (expressions == null || expressions.isEmpty()) {
return false;
}
// The qualifier we need for an array is in the component type, not varType.
AnnotatedTypeMirror componentType = ((AnnotatedArrayType) varType).getComponentType();
UBQualifier qualifier = UBQualifier.createUBQualifier(componentType, atypeFactory.UNKNOWN);
if (!qualifier.isLessThanLengthQualifier()) {
return false;
}
for (ExpressionTree expressionTree : expressions) {
if (!relaxedCommonAssignmentCheck((LessThanLengthOf) qualifier, expressionTree)) {
return false;
}
}
return true;
}
UBQualifier qualifier = UBQualifier.createUBQualifier(varType, atypeFactory.UNKNOWN);
return qualifier.isLessThanLengthQualifier() && relaxedCommonAssignmentCheck((LessThanLengthOf) qualifier, valueExp);
}
Aggregations