Search in sources :

Example 1 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class CFAbstractTransfer method strengthenAnnotationOfEqualTo.

/**
 * Refine the annotation of {@code secondNode} if the annotation {@code secondValue} is less
 * precise than {@code firstvalue}. This is possible, if {@code secondNode} is an expression
 * that is tracked by the store (e.g., a local variable or a field).
 *
 * <p>Note that when overriding this method, when a new type is inserted into the store,
 * splitAssignments should be called, and the new type should be inserted into the store for
 * each of the resulting nodes.
 *
 * @param res the previous result
 * @param notEqualTo if true, indicates that the logic is flipped (i.e., the information is
 *     added to the {@code elseStore} instead of the {@code thenStore}) for a not-equal
 *     comparison.
 * @return the conditional transfer result (if information has been added), or {@code null}.
 */
protected TransferResult<V, S> strengthenAnnotationOfEqualTo(TransferResult<V, S> res, Node firstNode, Node secondNode, V firstValue, V secondValue, boolean notEqualTo) {
    if (firstValue != null) {
        // Only need to insert if the second value is actually different.
        if (!firstValue.equals(secondValue)) {
            List<Node> secondParts = splitAssignments(secondNode);
            for (Node secondPart : secondParts) {
                Receiver secondInternal = FlowExpressions.internalReprOf(analysis.getTypeFactory(), secondPart);
                if (CFAbstractStore.canInsertReceiver(secondInternal)) {
                    S thenStore = res.getThenStore();
                    S elseStore = res.getElseStore();
                    if (notEqualTo) {
                        elseStore.insertValue(secondInternal, firstValue);
                    } else {
                        thenStore.insertValue(secondInternal, firstValue);
                    }
                    // To handle `(a = b = c) == x`, repeat for all insertable receivers of
                    // splitted assignments instead of returning.
                    res = new ConditionalTransferResult<>(res.getResultValue(), thenStore, elseStore);
                }
            }
        }
    }
    return res;
}
Also used : ThisLiteralNode(org.checkerframework.dataflow.cfg.node.ThisLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) EqualToNode(org.checkerframework.dataflow.cfg.node.EqualToNode) VariableDeclarationNode(org.checkerframework.dataflow.cfg.node.VariableDeclarationNode) TernaryExpressionNode(org.checkerframework.dataflow.cfg.node.TernaryExpressionNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) CaseNode(org.checkerframework.dataflow.cfg.node.CaseNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) NotEqualNode(org.checkerframework.dataflow.cfg.node.NotEqualNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ConditionalNotNode(org.checkerframework.dataflow.cfg.node.ConditionalNotNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) Node(org.checkerframework.dataflow.cfg.node.Node) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 2 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class CFAbstractTransfer method addFieldValues.

private void addFieldValues(S info, AnnotatedTypeFactory factory, ClassTree classTree, MethodTree methodTree) {
    // Add knowledge about final fields, or values of non-final fields
    // if we are inside a constructor (information about initializers)
    TypeMirror classType = TreeUtils.typeOf(classTree);
    List<Pair<VariableElement, V>> fieldValues = analysis.getFieldValues();
    for (Pair<VariableElement, V> p : fieldValues) {
        VariableElement element = p.first;
        V value = p.second;
        if (ElementUtils.isFinal(element) || TreeUtils.isConstructor(methodTree)) {
            Receiver receiver;
            if (ElementUtils.isStatic(element)) {
                receiver = new ClassName(classType);
            } else {
                receiver = new ThisReference(classType);
            }
            TypeMirror fieldType = ElementUtils.getType(element);
            Receiver field = new FieldAccess(receiver, fieldType, element);
            info.insertValue(field, value);
        }
    }
    // add properties about fields (static information from type)
    boolean isNotFullyInitializedReceiver = isNotFullyInitializedReceiver(methodTree);
    if (isNotFullyInitializedReceiver && !TreeUtils.isConstructor(methodTree)) {
        // and the method isn't a constructor
        return;
    }
    for (Tree member : classTree.getMembers()) {
        if (member instanceof VariableTree) {
            VariableTree vt = (VariableTree) member;
            final VariableElement element = TreeUtils.elementFromDeclaration(vt);
            AnnotatedTypeMirror type = ((GenericAnnotatedTypeFactory<?, ?, ?, ?>) factory).getAnnotatedTypeLhs(vt);
            TypeMirror fieldType = ElementUtils.getType(element);
            Receiver receiver;
            if (ElementUtils.isStatic(element)) {
                receiver = new ClassName(classType);
            } else {
                receiver = new ThisReference(classType);
            }
            V value = analysis.createAbstractValue(type);
            if (value == null)
                continue;
            if (TreeUtils.isConstructor(methodTree)) {
                // if we are in a constructor,
                // then we can still use the static type, but only
                // if there is also an initializer that already does
                // some initialization.
                boolean found = false;
                for (Pair<VariableElement, V> fieldValue : fieldValues) {
                    if (fieldValue.first.equals(element)) {
                        value = value.leastUpperBound(fieldValue.second);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    // no initializer found, cannot use static type
                    continue;
                }
            }
            Receiver field = new FieldAccess(receiver, fieldType, element);
            info.insertValue(field, value);
        }
    }
}
Also used : GenericAnnotatedTypeFactory(org.checkerframework.framework.type.GenericAnnotatedTypeFactory) VariableTree(com.sun.source.tree.VariableTree) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) VariableElement(javax.lang.model.element.VariableElement) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) Pair(org.checkerframework.javacutil.Pair)

Example 3 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class BaseTypeVisitor method checkContractsSubset.

/**
 * Checks that {@code mustSubset} is a subset of {@code set} in the following sense: For every
 * expression in {@code mustSubset} there must be the same expression in {@code set}, with the
 * same (or a stronger) annotation.
 */
private void checkContractsSubset(String overriderMeth, String overriderTyp, String overriddenMeth, String overriddenTyp, Set<Pair<Receiver, AnnotationMirror>> mustSubset, Set<Pair<Receiver, AnnotationMirror>> set, @CompilerMessageKey String messageKey) {
    for (Pair<Receiver, AnnotationMirror> weak : mustSubset) {
        boolean found = false;
        for (Pair<Receiver, AnnotationMirror> strong : set) {
            // are we looking at a contract of the same receiver?
            if (weak.first.equals(strong.first)) {
                // check subtyping relationship of annotations
                QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
                if (qualifierHierarchy.isSubtype(strong.second, weak.second)) {
                    found = true;
                    break;
                }
            }
        }
        if (!found) {
            MethodTree method = visitorState.getMethodTree();
            checker.report(Result.failure(messageKey, overriderMeth, overriderTyp, overriddenMeth, overriddenTyp, weak.second, weak.first), method);
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) MethodTree(com.sun.source.tree.MethodTree) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 4 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class ValueTransfer method addAnnotationToStore.

private void addAnnotationToStore(CFStore store, AnnotationMirror anno, Node node) {
    for (Node internal : splitAssignments(node)) {
        AnnotationMirror currentAnno = atypefactory.getAnnotatedType(internal.getTree()).getAnnotationInHierarchy(atypefactory.BOTTOMVAL);
        Receiver rec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), internal);
        // Combine the new annotations based on the results of the comparison with the existing
        // type.
        store.insertValue(rec, atypefactory.getQualifierHierarchy().greatestLowerBound(anno, currentAnno));
        if (node instanceof FieldAccessNode) {
            refineArrayAtLengthAccess((FieldAccessNode) internal, store);
        } else if (node instanceof MethodInvocationNode) {
            refineStringAtLengthInvocation((MethodInvocationNode) internal, store);
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) LeftShiftNode(org.checkerframework.dataflow.cfg.node.LeftShiftNode) FloatingRemainderNode(org.checkerframework.dataflow.cfg.node.FloatingRemainderNode) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) BitwiseOrNode(org.checkerframework.dataflow.cfg.node.BitwiseOrNode) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) NumericalPlusNode(org.checkerframework.dataflow.cfg.node.NumericalPlusNode) ConditionalAndNode(org.checkerframework.dataflow.cfg.node.ConditionalAndNode) GreaterThanOrEqualNode(org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ConditionalOrNode(org.checkerframework.dataflow.cfg.node.ConditionalOrNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) BitwiseXorNode(org.checkerframework.dataflow.cfg.node.BitwiseXorNode) BitwiseComplementNode(org.checkerframework.dataflow.cfg.node.BitwiseComplementNode) ConditionalNotNode(org.checkerframework.dataflow.cfg.node.ConditionalNotNode) NumericalMinusNode(org.checkerframework.dataflow.cfg.node.NumericalMinusNode) StringConcatenateNode(org.checkerframework.dataflow.cfg.node.StringConcatenateNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) FloatingDivisionNode(org.checkerframework.dataflow.cfg.node.FloatingDivisionNode) GreaterThanNode(org.checkerframework.dataflow.cfg.node.GreaterThanNode) LessThanOrEqualNode(org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) Node(org.checkerframework.dataflow.cfg.node.Node) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode)

Example 5 with Receiver

use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.

the class FlowExpressionParseUtil method getReceiverField.

private static Receiver getReceiverField(String s, FlowExpressionContext context, boolean originalReceiver, VariableElement fieldElem) throws FlowExpressionParseException {
    TypeMirror receiverType = context.receiver.getType();
    TypeMirror fieldType = ElementUtils.getType(fieldElem);
    if (ElementUtils.isStatic(fieldElem)) {
        Element classElem = fieldElem.getEnclosingElement();
        Receiver staticClassReceiver = new ClassName(ElementUtils.getType(classElem));
        return new FieldAccess(staticClassReceiver, fieldType, fieldElem);
    }
    Receiver locationOfField;
    if (originalReceiver) {
        locationOfField = context.receiver;
    } else {
        locationOfField = FlowExpressions.internalReprOf(context.checkerContext.getAnnotationProvider(), new ImplicitThisLiteralNode(receiverType));
    }
    if (locationOfField instanceof ClassName) {
        throw constructParserException(s, "a non-static field cannot have a class name as a receiver.");
    }
    return new FieldAccess(locationOfField, fieldType, fieldElem);
}
Also used : ImplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ImplicitThisLiteralNode) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)

Aggregations

Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)55 AnnotationMirror (javax.lang.model.element.AnnotationMirror)19 Node (org.checkerframework.dataflow.cfg.node.Node)15 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)14 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)10 CFValue (org.checkerframework.framework.flow.CFValue)9 FlowExpressions (org.checkerframework.dataflow.analysis.FlowExpressions)8 FieldAccess (org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)8 NumericalAdditionNode (org.checkerframework.dataflow.cfg.node.NumericalAdditionNode)8 NumericalSubtractionNode (org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)8 ArrayList (java.util.ArrayList)7 TypeMirror (javax.lang.model.type.TypeMirror)7 ClassName (org.checkerframework.dataflow.analysis.FlowExpressions.ClassName)7 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)7 Tree (com.sun.source.tree.Tree)6 TreePath (com.sun.source.util.TreePath)6 ArrayCreationNode (org.checkerframework.dataflow.cfg.node.ArrayCreationNode)6 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)6 MethodTree (com.sun.source.tree.MethodTree)5 CaseNode (org.checkerframework.dataflow.cfg.node.CaseNode)5