Search in sources :

Example 1 with MethodInvocationNode

use of org.checkerframework.dataflow.cfg.node.MethodInvocationNode in project bazel by bazelbuild.

the class FlowExpressions method internalReprOf.

/**
     * We ignore operations such as widening and
     * narrowing when computing the internal representation.
     *
     * @return The internal representation (as {@link Receiver}) of any
     *         {@link Node}. Might contain {@link Unknown}.
     */
public static Receiver internalReprOf(AnnotationProvider provider, Node receiverNode, boolean allowNonDeterminitic) {
    Receiver receiver = null;
    if (receiverNode instanceof FieldAccessNode) {
        FieldAccessNode fan = (FieldAccessNode) receiverNode;
        if (fan.getFieldName().equals("this")) {
            // For some reason, "className.this" is considered a field access.
            // We right this wrong here.
            receiver = new ThisReference(fan.getReceiver().getType());
        } else {
            receiver = internalReprOfFieldAccess(provider, fan);
        }
    } else if (receiverNode instanceof ExplicitThisLiteralNode) {
        receiver = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof ThisLiteralNode) {
        receiver = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof SuperNode) {
        receiver = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof LocalVariableNode) {
        LocalVariableNode lv = (LocalVariableNode) receiverNode;
        receiver = new LocalVariable(lv);
    } else if (receiverNode instanceof ArrayAccessNode) {
        ArrayAccessNode a = (ArrayAccessNode) receiverNode;
        receiver = internalReprOfArrayAccess(provider, a);
    } else if (receiverNode instanceof StringConversionNode) {
        // ignore string conversion
        return internalReprOf(provider, ((StringConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof WideningConversionNode) {
        // ignore widening
        return internalReprOf(provider, ((WideningConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof NarrowingConversionNode) {
        // ignore narrowing
        return internalReprOf(provider, ((NarrowingConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof ClassNameNode) {
        ClassNameNode cn = (ClassNameNode) receiverNode;
        receiver = new ClassName(cn.getType());
    } else if (receiverNode instanceof ValueLiteralNode) {
        ValueLiteralNode vn = (ValueLiteralNode) receiverNode;
        receiver = new ValueLiteral(vn.getType(), vn);
    } else if (receiverNode instanceof MethodInvocationNode) {
        MethodInvocationNode mn = (MethodInvocationNode) receiverNode;
        ExecutableElement invokedMethod = TreeUtils.elementFromUse(mn.getTree());
        // check if this represents a boxing operation of a constant, in which
        // case we treat the method call as deterministic, because there is no way
        // to behave differently in two executions where two constants are being used.
        boolean considerDeterministic = false;
        if (invokedMethod.toString().equals("valueOf(long)") && mn.getTarget().getReceiver().toString().equals("Long")) {
            Node arg = mn.getArgument(0);
            if (arg instanceof ValueLiteralNode) {
                considerDeterministic = true;
            }
        }
        if (PurityUtils.isDeterministic(provider, invokedMethod) || allowNonDeterminitic || considerDeterministic) {
            List<Receiver> parameters = new ArrayList<>();
            for (Node p : mn.getArguments()) {
                parameters.add(internalReprOf(provider, p));
            }
            Receiver methodReceiver;
            if (ElementUtils.isStatic(invokedMethod)) {
                methodReceiver = new ClassName(mn.getTarget().getReceiver().getType());
            } else {
                methodReceiver = internalReprOf(provider, mn.getTarget().getReceiver());
            }
            receiver = new PureMethodCall(mn.getType(), invokedMethod, methodReceiver, parameters);
        }
    }
    if (receiver == null) {
        receiver = new Unknown(receiverNode.getType());
    }
    return receiver;
}
Also used : MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ExecutableElement(javax.lang.model.element.ExecutableElement) ThisLiteralNode(org.checkerframework.dataflow.cfg.node.ThisLiteralNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) ExplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode) Node(org.checkerframework.dataflow.cfg.node.Node) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ExplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) ThisLiteralNode(org.checkerframework.dataflow.cfg.node.ThisLiteralNode) ExplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode) ArrayList(java.util.ArrayList) List(java.util.List)

Example 2 with MethodInvocationNode

use of org.checkerframework.dataflow.cfg.node.MethodInvocationNode 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 3 with MethodInvocationNode

use of org.checkerframework.dataflow.cfg.node.MethodInvocationNode in project checker-framework by typetools.

the class AliasingTransfer method processPostconditions.

/**
 * Handling pseudo-assignments. Called by {@code CFAbstractTransfer.visitMethodInvocation()}.
 *
 * <p>Case 2: Given a method call, traverses all formal parameters of the method declaration,
 * and if it doesn't have the {@literal @}NonLeaked or {@literal @}LeakedToResult annotations,
 * we remove the node of the respective argument in the method call from the store. If parameter
 * has {@literal @}LeakedToResult, {@code visitMethodInvocation()} handles it.
 */
@Override
protected void processPostconditions(MethodInvocationNode n, CFStore store, ExecutableElement methodElement, Tree tree) {
    super.processPostconditions(n, store, methodElement, tree);
    if (TreeUtils.isEnumSuper(n.getTree())) {
        // Skipping the init() method for enums.
        return;
    }
    List<Node> args = n.getArguments();
    List<? extends VariableElement> params = methodElement.getParameters();
    assert (args.size() == params.size()) : "Number of arguments in " + "the method call " + n.toString() + " is different from the" + " number of parameters for the method declaration: " + methodElement.getSimpleName().toString();
    AnnotatedExecutableType annotatedType = factory.getAnnotatedType(methodElement);
    List<AnnotatedTypeMirror> paramTypes = annotatedType.getParameterTypes();
    for (int i = 0; i < args.size(); i++) {
        Node arg = args.get(i);
        AnnotatedTypeMirror paramType = paramTypes.get(i);
        if (!paramType.hasAnnotation(NonLeaked.class) && !paramType.hasAnnotation(LeakedToResult.class)) {
            store.clearValue(FlowExpressions.internalReprOf(factory, arg));
        }
    }
    // Now, doing the same as above for the receiver parameter
    Node receiver = n.getTarget().getReceiver();
    AnnotatedDeclaredType receiverType = annotatedType.getReceiverType();
    if (receiverType != null && !receiverType.hasAnnotation(LeakedToResult.class) && !receiverType.hasAnnotation(NonLeaked.class)) {
        store.clearValue(FlowExpressions.internalReprOf(factory, receiver));
    }
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) LeakedToResult(org.checkerframework.common.aliasing.qual.LeakedToResult) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 4 with MethodInvocationNode

use of org.checkerframework.dataflow.cfg.node.MethodInvocationNode in project checker-framework by typetools.

the class KeyForTransfer method visitMethodInvocation.

/*
     * Provided that m is of a type that implements interface java.util.Map:
     * <ul>
     * <li>Given a call m.containsKey(k), ensures that k is @KeyFor("m") in the thenStore of the transfer result.
     * <li>Given a call m.put(k, ...), ensures that k is @KeyFor("m") in the thenStore and elseStore of the transfer result.
     * </ul>
     */
@Override
public TransferResult<KeyForValue, KeyForStore> visitMethodInvocation(MethodInvocationNode node, TransferInput<KeyForValue, KeyForStore> in) {
    TransferResult<KeyForValue, KeyForStore> result = super.visitMethodInvocation(node, in);
    KeyForAnnotatedTypeFactory factory = (KeyForAnnotatedTypeFactory) analysis.getTypeFactory();
    if (factory.isInvocationOfMapMethod(node, "containsKey") || factory.isInvocationOfMapMethod(node, "put")) {
        Node receiver = node.getTarget().getReceiver();
        Receiver internalReceiver = FlowExpressions.internalReprOf(factory, receiver);
        String mapName = internalReceiver.toString();
        Receiver keyReceiver = FlowExpressions.internalReprOf(factory, node.getArgument(0));
        LinkedHashSet<String> keyForMaps = new LinkedHashSet<>();
        keyForMaps.add(mapName);
        final KeyForValue previousKeyValue = in.getValueOfSubNode(node.getArgument(0));
        if (previousKeyValue != null) {
            for (AnnotationMirror prevAm : previousKeyValue.getAnnotations()) {
                if (prevAm != null && AnnotationUtils.areSameByClass(prevAm, KeyFor.class)) {
                    keyForMaps.addAll(getKeys(prevAm));
                }
            }
        }
        AnnotationMirror am = factory.createKeyForAnnotationMirrorWithValue(keyForMaps);
        if (factory.getMethodName(node).equals("containsKey")) {
            result.getThenStore().insertValue(keyReceiver, am);
        } else {
            // method name is "put"
            result.getThenStore().insertValue(keyReceiver, am);
            result.getElseStore().insertValue(keyReceiver, am);
        }
    }
    return result;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) AnnotationMirror(javax.lang.model.element.AnnotationMirror) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) KeyFor(org.checkerframework.checker.nullness.qual.KeyFor) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 5 with MethodInvocationNode

use of org.checkerframework.dataflow.cfg.node.MethodInvocationNode in project checker-framework by typetools.

the class RegexTransfer method visitMethodInvocation.

// TODO: These are special cases for isRegex(String, int) and asRegex(String, int).
// They should be replaced by adding an @EnsuresQualifierIf annotation that supports
// specifying attributes.
@Override
public TransferResult<CFValue, CFStore> visitMethodInvocation(MethodInvocationNode n, TransferInput<CFValue, CFStore> in) {
    TransferResult<CFValue, CFStore> result = super.visitMethodInvocation(n, in);
    // refine result for some helper methods
    MethodAccessNode target = n.getTarget();
    ExecutableElement method = target.getMethod();
    Node receiver = target.getReceiver();
    if (receiver instanceof ClassNameNode) {
        ClassNameNode cnn = (ClassNameNode) receiver;
        String receiverName = cnn.getElement().toString();
        if (isRegexUtil(receiverName)) {
            result = handleRegexUtil(n, method, result);
        }
    }
    return result;
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) CFStore(org.checkerframework.framework.flow.CFStore) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) ExecutableElement(javax.lang.model.element.ExecutableElement) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) IntegerLiteralNode(org.checkerframework.dataflow.cfg.node.IntegerLiteralNode) GreaterThanNode(org.checkerframework.dataflow.cfg.node.GreaterThanNode) LessThanOrEqualNode(org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode) GreaterThanOrEqualNode(org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode) Node(org.checkerframework.dataflow.cfg.node.Node) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode)

Aggregations

MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)19 Node (org.checkerframework.dataflow.cfg.node.Node)17 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)10 ExecutableElement (javax.lang.model.element.ExecutableElement)8 MethodAccessNode (org.checkerframework.dataflow.cfg.node.MethodAccessNode)7 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)6 AnnotationMirror (javax.lang.model.element.AnnotationMirror)5 ClassNameNode (org.checkerframework.dataflow.cfg.node.ClassNameNode)5 GreaterThanNode (org.checkerframework.dataflow.cfg.node.GreaterThanNode)5 GreaterThanOrEqualNode (org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode)5 LessThanNode (org.checkerframework.dataflow.cfg.node.LessThanNode)5 LessThanOrEqualNode (org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode)5 ArrayCreationNode (org.checkerframework.dataflow.cfg.node.ArrayCreationNode)4 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)4 StringConversionNode (org.checkerframework.dataflow.cfg.node.StringConversionNode)4 CFStore (org.checkerframework.framework.flow.CFStore)4 ArrayList (java.util.ArrayList)3 ArrayAccessNode (org.checkerframework.dataflow.cfg.node.ArrayAccessNode)3 ObjectCreationNode (org.checkerframework.dataflow.cfg.node.ObjectCreationNode)3 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)3