Search in sources :

Example 1 with NullLiteralNode

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

the class CFGTranslationPhaseOne method visitLiteral.

@Override
public Node visitLiteral(LiteralTree tree, Void p) {
    Node r = null;
    switch(tree.getKind()) {
        case BOOLEAN_LITERAL:
            r = new BooleanLiteralNode(tree);
            break;
        case CHAR_LITERAL:
            r = new CharacterLiteralNode(tree);
            break;
        case DOUBLE_LITERAL:
            r = new DoubleLiteralNode(tree);
            break;
        case FLOAT_LITERAL:
            r = new FloatLiteralNode(tree);
            break;
        case INT_LITERAL:
            r = new IntegerLiteralNode(tree);
            break;
        case LONG_LITERAL:
            r = new LongLiteralNode(tree);
            break;
        case NULL_LITERAL:
            r = new NullLiteralNode(tree);
            break;
        case STRING_LITERAL:
            r = new StringLiteralNode(tree);
            break;
        default:
            throw new BugInCF("unexpected literal tree");
    }
    assert r != null : "unexpected literal tree";
    extendWithNode(r);
    return r;
}
Also used : LongLiteralNode(org.checkerframework.dataflow.cfg.node.LongLiteralNode) CharacterLiteralNode(org.checkerframework.dataflow.cfg.node.CharacterLiteralNode) BooleanLiteralNode(org.checkerframework.dataflow.cfg.node.BooleanLiteralNode) FloatLiteralNode(org.checkerframework.dataflow.cfg.node.FloatLiteralNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) LeftShiftNode(org.checkerframework.dataflow.cfg.node.LeftShiftNode) PrimitiveTypeNode(org.checkerframework.dataflow.cfg.node.PrimitiveTypeNode) FloatLiteralNode(org.checkerframework.dataflow.cfg.node.FloatLiteralNode) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) BitwiseOrNode(org.checkerframework.dataflow.cfg.node.BitwiseOrNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) EqualToNode(org.checkerframework.dataflow.cfg.node.EqualToNode) NumericalPlusNode(org.checkerframework.dataflow.cfg.node.NumericalPlusNode) ConditionalAndNode(org.checkerframework.dataflow.cfg.node.ConditionalAndNode) VariableDeclarationNode(org.checkerframework.dataflow.cfg.node.VariableDeclarationNode) ClassDeclarationNode(org.checkerframework.dataflow.cfg.node.ClassDeclarationNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) AssertionErrorNode(org.checkerframework.dataflow.cfg.node.AssertionErrorNode) InstanceOfNode(org.checkerframework.dataflow.cfg.node.InstanceOfNode) BooleanLiteralNode(org.checkerframework.dataflow.cfg.node.BooleanLiteralNode) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) ArrayTypeNode(org.checkerframework.dataflow.cfg.node.ArrayTypeNode) LambdaResultExpressionNode(org.checkerframework.dataflow.cfg.node.LambdaResultExpressionNode) IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ConditionalOrNode(org.checkerframework.dataflow.cfg.node.ConditionalOrNode) NotEqualNode(org.checkerframework.dataflow.cfg.node.NotEqualNode) BitwiseXorNode(org.checkerframework.dataflow.cfg.node.BitwiseXorNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ExplicitThisNode(org.checkerframework.dataflow.cfg.node.ExplicitThisNode) StringConcatenateNode(org.checkerframework.dataflow.cfg.node.StringConcatenateNode) NullChkNode(org.checkerframework.dataflow.cfg.node.NullChkNode) CharacterLiteralNode(org.checkerframework.dataflow.cfg.node.CharacterLiteralNode) FloatingDivisionNode(org.checkerframework.dataflow.cfg.node.FloatingDivisionNode) FunctionalInterfaceNode(org.checkerframework.dataflow.cfg.node.FunctionalInterfaceNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) LongLiteralNode(org.checkerframework.dataflow.cfg.node.LongLiteralNode) MarkerNode(org.checkerframework.dataflow.cfg.node.MarkerNode) ImplicitThisNode(org.checkerframework.dataflow.cfg.node.ImplicitThisNode) FloatingRemainderNode(org.checkerframework.dataflow.cfg.node.FloatingRemainderNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) PackageNameNode(org.checkerframework.dataflow.cfg.node.PackageNameNode) DoubleLiteralNode(org.checkerframework.dataflow.cfg.node.DoubleLiteralNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) IntegerLiteralNode(org.checkerframework.dataflow.cfg.node.IntegerLiteralNode) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) ThrowNode(org.checkerframework.dataflow.cfg.node.ThrowNode) GreaterThanOrEqualNode(org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode) StringLiteralNode(org.checkerframework.dataflow.cfg.node.StringLiteralNode) TernaryExpressionNode(org.checkerframework.dataflow.cfg.node.TernaryExpressionNode) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) ParameterizedTypeNode(org.checkerframework.dataflow.cfg.node.ParameterizedTypeNode) CaseNode(org.checkerframework.dataflow.cfg.node.CaseNode) SwitchExpressionNode(org.checkerframework.dataflow.cfg.node.SwitchExpressionNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) BitwiseComplementNode(org.checkerframework.dataflow.cfg.node.BitwiseComplementNode) ConditionalNotNode(org.checkerframework.dataflow.cfg.node.ConditionalNotNode) NumericalMinusNode(org.checkerframework.dataflow.cfg.node.NumericalMinusNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) GreaterThanNode(org.checkerframework.dataflow.cfg.node.GreaterThanNode) LessThanOrEqualNode(org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode) SynchronizedNode(org.checkerframework.dataflow.cfg.node.SynchronizedNode) Node(org.checkerframework.dataflow.cfg.node.Node) IntegerLiteralNode(org.checkerframework.dataflow.cfg.node.IntegerLiteralNode) DoubleLiteralNode(org.checkerframework.dataflow.cfg.node.DoubleLiteralNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) BugInCF(org.checkerframework.javacutil.BugInCF) StringLiteralNode(org.checkerframework.dataflow.cfg.node.StringLiteralNode)

Example 2 with NullLiteralNode

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

the class MustCallConsistencyAnalyzer method checkReassignmentToField.

/**
 * Issues an error if the given re-assignment to a non-final, owning field is not valid. A
 * re-assignment is valid if the called methods type of the lhs before the assignment satisfies
 * the must-call obligations of the field.
 *
 * @param obligations current tracked Obligations
 * @param node an assignment to a non-final, owning field
 */
private void checkReassignmentToField(Set<Obligation> obligations, AssignmentNode node) {
    Node lhsNode = node.getTarget();
    if (!(lhsNode instanceof FieldAccessNode)) {
        throw new TypeSystemError("checkReassignmentToField: non-field node " + node + " of class " + node.getClass());
    }
    FieldAccessNode lhs = (FieldAccessNode) lhsNode;
    Node receiver = lhs.getReceiver();
    // TODO: it would be better to defer getting the path until after checking
    // for a CreatesMustCallFor annotation, because getting the path can be expensive.
    // It might be possible to exploit the CFG structure to find the containing
    // method (rather than using the path, as below), because if a method is being
    // analyzed then it should be the root of the CFG (I think).
    TreePath currentPath = typeFactory.getPath(node.getTree());
    MethodTree enclosingMethodTree = TreePathUtil.enclosingMethod(currentPath);
    if (enclosingMethodTree == null) {
        // also a declaration must be a field initializer.
        if (node.getTree().getKind() == Tree.Kind.VARIABLE) {
            return;
        } else {
            // Issue an error if the field has a non-empty must-call type.
            MustCallAnnotatedTypeFactory mcTypeFactory = typeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
            AnnotationMirror mcAnno = mcTypeFactory.getAnnotatedType(lhs.getElement()).getAnnotation(MustCall.class);
            List<String> mcValues = AnnotationUtils.getElementValueArray(mcAnno, mcTypeFactory.getMustCallValueElement(), String.class);
            if (mcValues.isEmpty()) {
                return;
            }
            Element lhsElement = TreeUtils.elementFromTree(lhs.getTree());
            checker.reportError(node.getTree(), "required.method.not.called", formatMissingMustCallMethods(mcValues), "field " + lhsElement.getSimpleName().toString(), lhsElement.asType().toString(), "Field assignment outside method or declaration might overwrite field's current value");
            return;
        }
    }
    // on the method declaration), or 2) the rhs is a null literal (so there's nothing to reset).
    if (!(receiver instanceof LocalVariableNode && varTrackedInObligations(obligations, (LocalVariableNode) receiver)) && !(node.getExpression() instanceof NullLiteralNode)) {
        checkEnclosingMethodIsCreatesMustCallFor(node, enclosingMethodTree);
    }
    MustCallAnnotatedTypeFactory mcTypeFactory = typeFactory.getTypeFactoryOfSubchecker(MustCallChecker.class);
    // Get the Must Call type for the field. If there's info about this field in the store, use
    // that. Otherwise, use the declared type of the field
    CFStore mcStore = mcTypeFactory.getStoreBefore(lhs);
    CFValue mcValue = mcStore.getValue(lhs);
    AnnotationMirror mcAnno;
    if (mcValue == null) {
        // No store value, so use the declared type.
        mcAnno = mcTypeFactory.getAnnotatedType(lhs.getElement()).getAnnotation(MustCall.class);
    } else {
        mcAnno = AnnotationUtils.getAnnotationByClass(mcValue.getAnnotations(), MustCall.class);
    }
    List<String> mcValues = AnnotationUtils.getElementValueArray(mcAnno, mcTypeFactory.getMustCallValueElement(), String.class);
    if (mcValues.isEmpty()) {
        return;
    }
    // Get the store before the RHS rather than the assignment node, because the CFG always has
    // the RHS first. If the RHS has side-effects, then the assignment node's store will have
    // had its inferred types erased.
    Node rhs = node.getExpression();
    CFStore cmStoreBefore = typeFactory.getStoreBefore(rhs);
    CFValue cmValue = cmStoreBefore == null ? null : cmStoreBefore.getValue(lhs);
    AnnotationMirror cmAnno = null;
    if (cmValue != null) {
        for (AnnotationMirror anno : cmValue.getAnnotations()) {
            if (AnnotationUtils.areSameByName(anno, "org.checkerframework.checker.calledmethods.qual.CalledMethods")) {
                cmAnno = anno;
                break;
            }
        }
    }
    if (cmAnno == null) {
        cmAnno = typeFactory.top;
    }
    if (!calledMethodsSatisfyMustCall(mcValues, cmAnno)) {
        Element lhsElement = TreeUtils.elementFromTree(lhs.getTree());
        if (!checker.shouldSkipUses(lhsElement)) {
            checker.reportError(node.getTree(), "required.method.not.called", formatMissingMustCallMethods(mcValues), "field " + lhsElement.getSimpleName().toString(), lhsElement.asType().toString(), " Non-final owning field might be overwritten");
        }
    }
}
Also used : CFStore(org.checkerframework.framework.flow.CFStore) MethodTree(com.sun.source.tree.MethodTree) TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) ObjectCreationNode(org.checkerframework.dataflow.cfg.node.ObjectCreationNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) ThisNode(org.checkerframework.dataflow.cfg.node.ThisNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) Node(org.checkerframework.dataflow.cfg.node.Node) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) TypeSystemError(org.checkerframework.javacutil.TypeSystemError) MustCallAnnotatedTypeFactory(org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreePath(com.sun.source.util.TreePath) MustCall(org.checkerframework.checker.mustcall.qual.MustCall) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode)

Example 3 with NullLiteralNode

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

the class NullnessTransfer method strengthenAnnotationOfEqualTo.

/**
 * {@inheritDoc}
 *
 * <p>Furthermore, this method refines the type to {@code NonNull} for the appropriate branch if
 * an expression is compared to the {@code null} literal (listed as case 1 in the class
 * description).
 */
@Override
protected TransferResult<NullnessValue, NullnessStore> strengthenAnnotationOfEqualTo(TransferResult<NullnessValue, NullnessStore> res, Node firstNode, Node secondNode, NullnessValue firstValue, NullnessValue secondValue, boolean notEqualTo) {
    res = super.strengthenAnnotationOfEqualTo(res, firstNode, secondNode, firstValue, secondValue, notEqualTo);
    if (firstNode instanceof NullLiteralNode) {
        NullnessStore thenStore = res.getThenStore();
        NullnessStore elseStore = res.getElseStore();
        List<Node> secondParts = splitAssignments(secondNode);
        for (Node secondPart : secondParts) {
            JavaExpression secondInternal = JavaExpression.fromNode(secondPart);
            if (CFAbstractStore.canInsertJavaExpression(secondInternal)) {
                thenStore = thenStore == null ? res.getThenStore() : thenStore;
                elseStore = elseStore == null ? res.getElseStore() : elseStore;
                if (notEqualTo) {
                    thenStore.insertValue(secondInternal, NONNULL);
                } else {
                    elseStore.insertValue(secondInternal, NONNULL);
                }
            }
        }
        Set<AnnotationMirror> secondAnnos = secondValue != null ? secondValue.getAnnotations() : AnnotationUtils.createAnnotationSet();
        if (nullnessTypeFactory.containsSameByClass(secondAnnos, PolyNull.class)) {
            thenStore = thenStore == null ? res.getThenStore() : thenStore;
            elseStore = elseStore == null ? res.getElseStore() : elseStore;
            // TODO: methodTree is null for lambdas.  Handle that case.  See Issue3850.java.
            MethodTree methodTree = analysis.getContainingMethod(secondNode.getTree());
            ExecutableElement methodElem = methodTree == null ? null : TreeUtils.elementFromDeclaration(methodTree);
            if (notEqualTo) {
                elseStore.setPolyNullNull(true);
                if (methodElem != null && polyNullIsNonNull(methodElem, thenStore)) {
                    thenStore.setPolyNullNonNull(true);
                }
            } else {
                thenStore.setPolyNullNull(true);
                if (methodElem != null && polyNullIsNonNull(methodElem, elseStore)) {
                    elseStore.setPolyNullNonNull(true);
                }
            }
        }
        if (thenStore != null) {
            return new ConditionalTransferResult<>(res.getResultValue(), thenStore, elseStore);
        }
    }
    return res;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) MethodTree(com.sun.source.tree.MethodTree) ConditionalTransferResult(org.checkerframework.dataflow.analysis.ConditionalTransferResult) InstanceOfNode(org.checkerframework.dataflow.cfg.node.InstanceOfNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) ThrowNode(org.checkerframework.dataflow.cfg.node.ThrowNode) Node(org.checkerframework.dataflow.cfg.node.Node) ExecutableElement(javax.lang.model.element.ExecutableElement) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode)

Aggregations

FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)3 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)3 Node (org.checkerframework.dataflow.cfg.node.Node)3 NullLiteralNode (org.checkerframework.dataflow.cfg.node.NullLiteralNode)3 ReturnNode (org.checkerframework.dataflow.cfg.node.ReturnNode)3 MethodTree (com.sun.source.tree.MethodTree)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 ArrayAccessNode (org.checkerframework.dataflow.cfg.node.ArrayAccessNode)2 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)2 LocalVariableNode (org.checkerframework.dataflow.cfg.node.LocalVariableNode)2 ObjectCreationNode (org.checkerframework.dataflow.cfg.node.ObjectCreationNode)2 ThisNode (org.checkerframework.dataflow.cfg.node.ThisNode)2 TypeCastNode (org.checkerframework.dataflow.cfg.node.TypeCastNode)2 TreePath (com.sun.source.util.TreePath)1 Element (javax.lang.model.element.Element)1 TypeElement (javax.lang.model.element.TypeElement)1 VariableElement (javax.lang.model.element.VariableElement)1 MustCallAnnotatedTypeFactory (org.checkerframework.checker.mustcall.MustCallAnnotatedTypeFactory)1 MustCall (org.checkerframework.checker.mustcall.qual.MustCall)1