Search in sources :

Example 1 with LessThanLengthOf

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;
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) CFStore(org.checkerframework.framework.flow.CFStore) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) CaseNode(org.checkerframework.dataflow.cfg.node.CaseNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) LessThanLengthOf(org.checkerframework.checker.index.upperbound.UBQualifier.LessThanLengthOf) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode)

Example 2 with LessThanLengthOf

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);
}
Also used : AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) LessThanLengthOf(org.checkerframework.checker.index.upperbound.UBQualifier.LessThanLengthOf) ExpressionTree(com.sun.source.tree.ExpressionTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

LessThanLengthOf (org.checkerframework.checker.index.upperbound.UBQualifier.LessThanLengthOf)2 ExpressionTree (com.sun.source.tree.ExpressionTree)1 AnnotationMirror (javax.lang.model.element.AnnotationMirror)1 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)1 ArrayCreationNode (org.checkerframework.dataflow.cfg.node.ArrayCreationNode)1 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)1 CaseNode (org.checkerframework.dataflow.cfg.node.CaseNode)1 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)1 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)1 Node (org.checkerframework.dataflow.cfg.node.Node)1 NumericalAdditionNode (org.checkerframework.dataflow.cfg.node.NumericalAdditionNode)1 NumericalMultiplicationNode (org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode)1 NumericalSubtractionNode (org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)1 TypeCastNode (org.checkerframework.dataflow.cfg.node.TypeCastNode)1 CFStore (org.checkerframework.framework.flow.CFStore)1 CFValue (org.checkerframework.framework.flow.CFValue)1 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)1 AnnotatedArrayType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType)1