Search in sources :

Example 1 with FieldAccess

use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.

the class UpperBoundTransfer method refineNeqSequenceLength.

/**
 * If lengthAccess node is an sequence length field or method access (optionally with a constant
 * offset subtracted) and the other node is less than or equal to that sequence length (minus the
 * offset), then refine the other node's type to less than the sequence length (minus the offset).
 * This is case 12.
 */
private void refineNeqSequenceLength(Node lengthAccess, Node otherNode, AnnotationMirror otherNodeAnno, CFStore store) {
    // If lengthAccess is "receiver.length - c" where c is an integer constant,
    // then lengthOffset is "c".
    int lengthOffset = 0;
    if (lengthAccess instanceof NumericalSubtractionNode) {
        NumericalSubtractionNode subtraction = (NumericalSubtractionNode) lengthAccess;
        Node offsetNode = subtraction.getRightOperand();
        Long offsetValue = ValueCheckerUtils.getExactValue(offsetNode.getTree(), atypeFactory.getValueAnnotatedTypeFactory());
        if (offsetValue != null && offsetValue > Integer.MIN_VALUE && offsetValue <= Integer.MAX_VALUE) {
            lengthOffset = offsetValue.intValue();
            lengthAccess = subtraction.getLeftOperand();
        } else {
            // Subtraction of non-constant expressions is not supported
            return;
        }
    }
    JavaExpression receiver = null;
    if (NodeUtils.isArrayLengthFieldAccess(lengthAccess)) {
        FieldAccess fa = (FieldAccess) JavaExpression.fromNodeFieldAccess((FieldAccessNode) lengthAccess);
        receiver = fa.getReceiver();
    } else if (atypeFactory.getMethodIdentifier().isLengthOfMethodInvocation(lengthAccess)) {
        JavaExpression ma = JavaExpression.fromNode(lengthAccess);
        if (ma instanceof MethodCall) {
            receiver = ((MethodCall) ma).getReceiver();
        }
    }
    if (receiver != null && !receiver.containsUnknown()) {
        UBQualifier otherQualifier = UBQualifier.createUBQualifier(otherNodeAnno, (UpperBoundChecker) atypeFactory.getChecker());
        String sequence = receiver.toString();
        // Check if otherNode + c - 1 < receiver.length
        if (otherQualifier.hasSequenceWithOffset(sequence, lengthOffset - 1)) {
            // Add otherNode + c < receiver.length
            UBQualifier newQualifier = UBQualifier.createUBQualifier(sequence, Integer.toString(lengthOffset));
            otherQualifier = otherQualifier.glb(newQualifier);
            for (Node internal : splitAssignments(otherNode)) {
                JavaExpression leftJe = JavaExpression.fromNode(internal);
                store.insertValue(leftJe, atypeFactory.convertUBQualifierToAnnotation(otherQualifier));
            }
        }
    }
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) 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) IntegerLiteralNode(org.checkerframework.dataflow.cfg.node.IntegerLiteralNode) Node(org.checkerframework.dataflow.cfg.node.Node) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) MethodCall(org.checkerframework.dataflow.expression.MethodCall) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)

Example 2 with FieldAccess

use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.

the class InitializationVisitor method checkContract.

@Override
protected boolean checkContract(JavaExpression expr, AnnotationMirror necessaryAnnotation, AnnotationMirror inferredAnnotation, CFAbstractStore<?, ?> store) {
    // also use the information about initialized fields to check contracts
    final AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
    if (!atypeFactory.getQualifierHierarchy().isSubtype(invariantAnno, necessaryAnnotation) || !(expr instanceof FieldAccess)) {
        return super.checkContract(expr, necessaryAnnotation, inferredAnnotation, store);
    }
    if (expr.containsUnknown()) {
        return false;
    }
    FieldAccess fa = (FieldAccess) expr;
    if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
        @SuppressWarnings("unchecked") Store s = (Store) store;
        if (s.isFieldInitialized(fa.getField())) {
            AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
            // is this an invariant-field?
            if (AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
                return true;
            }
        }
    } else {
        @SuppressWarnings("unchecked") Value value = (Value) store.getValue(fa.getReceiver());
        Set<AnnotationMirror> receiverAnnoSet;
        if (value != null) {
            receiverAnnoSet = value.getAnnotations();
        } else if (fa.getReceiver() instanceof LocalVariable) {
            Element elem = ((LocalVariable) fa.getReceiver()).getElement();
            AnnotatedTypeMirror receiverType = atypeFactory.getAnnotatedType(elem);
            receiverAnnoSet = receiverType.getAnnotations();
        } else {
            // Is there anything better we could do?
            return false;
        }
        boolean isReceiverInitialized = false;
        for (AnnotationMirror anno : receiverAnnoSet) {
            if (atypeFactory.isInitialized(anno)) {
                isReceiverInitialized = true;
            }
        }
        AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
        // has the invariant type.
        if (isReceiverInitialized && AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
            return true;
        }
    }
    return super.checkContract(expr, necessaryAnnotation, inferredAnnotation, store);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ClassName(org.checkerframework.dataflow.expression.ClassName) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) FieldInitialValue(org.checkerframework.framework.flow.CFAbstractAnalysis.FieldInitialValue) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) ThisReference(org.checkerframework.dataflow.expression.ThisReference) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 3 with FieldAccess

use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.

the class InitializationTransfer method visitAssignment.

@Override
public TransferResult<V, S> visitAssignment(AssignmentNode n, TransferInput<V, S> in) {
    TransferResult<V, S> result = super.visitAssignment(n, in);
    assert result instanceof RegularTransferResult;
    JavaExpression lhs = JavaExpression.fromNode(n.getTarget());
    // If this is an assignment to a field of 'this', then mark the field as initialized.
    if (!lhs.containsUnknown()) {
        if (lhs instanceof FieldAccess) {
            FieldAccess fa = (FieldAccess) lhs;
            result.getRegularStore().addInitializedField(fa);
        }
    }
    return result;
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) RegularTransferResult(org.checkerframework.dataflow.analysis.RegularTransferResult)

Example 4 with FieldAccess

use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.

the class InitializationStore method insertValue.

/**
 * {@inheritDoc}
 *
 * <p>If the receiver is a field, and has an invariant annotation, then it can be considered
 * initialized.
 */
@Override
public void insertValue(JavaExpression je, V value, boolean permitNondeterministic) {
    if (!shouldInsert(je, value, permitNondeterministic)) {
        return;
    }
    InitializationAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory = (InitializationAnnotatedTypeFactory<?, ?, ?, ?>) analysis.getTypeFactory();
    QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
    AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
    // Remember fields that have the 'invariant' annotation in the store.
    if (je instanceof FieldAccess) {
        FieldAccess fieldAccess = (FieldAccess) je;
        if (!fieldValues.containsKey(je)) {
            Set<AnnotationMirror> declaredAnnos = atypeFactory.getAnnotatedType(fieldAccess.getField()).getAnnotations();
            if (AnnotationUtils.containsSame(declaredAnnos, invariantAnno)) {
                if (!invariantFields.containsKey(fieldAccess)) {
                    invariantFields.put(fieldAccess, analysis.createSingleAnnotationValue(invariantAnno, je.getType()));
                }
            }
        }
    }
    super.insertValue(je, value, permitNondeterministic);
    for (AnnotationMirror a : value.getAnnotations()) {
        if (qualifierHierarchy.isSubtype(a, invariantAnno)) {
            if (je instanceof FieldAccess) {
                FieldAccess fa = (FieldAccess) je;
                if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
                    addInitializedField(fa.getField());
                }
            }
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) ClassName(org.checkerframework.dataflow.expression.ClassName) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) ThisReference(org.checkerframework.dataflow.expression.ThisReference)

Example 5 with FieldAccess

use of org.checkerframework.dataflow.expression.FieldAccess in project checker-framework by typetools.

the class InitializationStore method supersetOf.

@Override
protected boolean supersetOf(CFAbstractStore<V, S> o) {
    if (!(o instanceof InitializationStore)) {
        return false;
    }
    @SuppressWarnings("unchecked") S other = (S) o;
    for (Element field : other.initializedFields) {
        if (!initializedFields.contains(field)) {
            return false;
        }
    }
    for (FieldAccess invariantField : other.invariantFields.keySet()) {
        if (!invariantFields.containsKey(invariantField)) {
            return false;
        }
    }
    Map<FieldAccess, V> removedFieldValues = new HashMap<>(invariantFields.size());
    Map<FieldAccess, V> removedOtherFieldValues = new HashMap<>(other.invariantFields.size());
    try {
        // Remove invariant annotated fields to avoid performance issue reported in #1438.
        for (FieldAccess invariantField : invariantFields.keySet()) {
            V v = fieldValues.remove(invariantField);
            removedFieldValues.put(invariantField, v);
        }
        for (FieldAccess invariantField : other.invariantFields.keySet()) {
            V v = other.fieldValues.remove(invariantField);
            removedOtherFieldValues.put(invariantField, v);
        }
        return super.supersetOf(other);
    } finally {
        // Restore removed values.
        fieldValues.putAll(removedFieldValues);
        other.fieldValues.putAll(removedOtherFieldValues);
    }
}
Also used : HashMap(java.util.HashMap) VariableElement(javax.lang.model.element.VariableElement) Element(javax.lang.model.element.Element) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess)

Aggregations

FieldAccess (org.checkerframework.dataflow.expression.FieldAccess)26 LocalVariable (org.checkerframework.dataflow.expression.LocalVariable)11 ClassName (org.checkerframework.dataflow.expression.ClassName)10 JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)9 MethodCall (org.checkerframework.dataflow.expression.MethodCall)9 HashMap (java.util.HashMap)8 ArrayAccess (org.checkerframework.dataflow.expression.ArrayAccess)8 Map (java.util.Map)7 ThisReference (org.checkerframework.dataflow.expression.ThisReference)7 AnnotationMirror (javax.lang.model.element.AnnotationMirror)5 CFValue (org.checkerframework.framework.flow.CFValue)5 Element (javax.lang.model.element.Element)4 ExecutableElement (javax.lang.model.element.ExecutableElement)4 VariableElement (javax.lang.model.element.VariableElement)4 JavaExpressionParseException (org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException)3 MethodTree (com.sun.source.tree.MethodTree)2 Tree (com.sun.source.tree.Tree)2 ArrayList (java.util.ArrayList)2 TypeElement (javax.lang.model.element.TypeElement)2 CFStore (org.checkerframework.framework.flow.CFStore)2