Search in sources :

Example 1 with UnderlyingAST

use of org.checkerframework.dataflow.cfg.UnderlyingAST in project error-prone by google.

the class NullnessPropagationTransfer method fieldInitializerNullnessIfAvailable.

@Nullable
private Nullness fieldInitializerNullnessIfAvailable(ClassAndField accessed) {
    if (!traversed.add(accessed.symbol)) {
        // TODO(kmb): Try to recognize problems with initialization order
        return NULL;
    }
    try {
        JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
        TreePath fieldDeclPath = Trees.instance(javacEnv).getPath(accessed.symbol);
        // missing types.
        if (fieldDeclPath == null || fieldDeclPath.getCompilationUnit() != compilationUnit || !(fieldDeclPath.getLeaf() instanceof VariableTree)) {
            return null;
        }
        ExpressionTree initializer = ((VariableTree) fieldDeclPath.getLeaf()).getInitializer();
        if (initializer == null) {
            return null;
        }
        // Run flow analysis on field initializer.  This is inefficient compared to just walking
        // the initializer expression tree but it avoids duplicating the logic from this transfer
        // function into a method that operates on Javac Nodes.
        TreePath initializerPath = TreePath.getPath(fieldDeclPath, initializer);
        UnderlyingAST ast = new UnderlyingAST.CFGStatement(initializerPath.getLeaf());
        ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
        false, /* assumeAssertionsDisabled */
        false);
        Analysis<Nullness, LocalStore<Nullness>, NullnessPropagationTransfer> analysis = new Analysis<>(javacEnv, this);
        analysis.performAnalysis(cfg);
        return analysis.getValue(initializerPath.getLeaf());
    } finally {
        traversed.remove(accessed.symbol);
    }
}
Also used : TreePath(com.sun.source.util.TreePath) Analysis(org.checkerframework.dataflow.analysis.Analysis) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) VariableTree(com.sun.source.tree.VariableTree) ExpressionTree(com.sun.source.tree.ExpressionTree) LocalStore(com.google.errorprone.dataflow.LocalStore) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST) Nullable(javax.annotation.Nullable)

Example 2 with UnderlyingAST

use of org.checkerframework.dataflow.cfg.UnderlyingAST in project error-prone by google.

the class TrustingNullnessAnalysis method getFieldInitializerNullness.

/**
   * Returns {@link Nullness} of the initializer of the {@link VariableTree} at the leaf of the
   * given {@code fieldDeclPath}.  Returns {@link Nullness#NULL} should there be no initializer.
   */
// TODO(kmb): Fold this functionality into Dataflow.expressionDataflow
public Nullness getFieldInitializerNullness(TreePath fieldDeclPath, Context context) {
    Tree decl = fieldDeclPath.getLeaf();
    checkArgument(decl instanceof VariableTree && ((JCVariableDecl) decl).sym.getKind() == ElementKind.FIELD, "Leaf of fieldDeclPath must be a field declaration: %s", decl);
    ExpressionTree initializer = ((VariableTree) decl).getInitializer();
    if (initializer == null) {
        // An uninitialized field is null or 0 to start :)
        return ((JCVariableDecl) decl).type.isPrimitive() ? Nullness.NONNULL : Nullness.NULL;
    }
    TreePath initializerPath = TreePath.getPath(fieldDeclPath, initializer);
    JavacProcessingEnvironment javacEnv = JavacProcessingEnvironment.instance(context);
    UnderlyingAST ast = new UnderlyingAST.CFGStatement(decl);
    ControlFlowGraph cfg = CFGBuilder.build(initializerPath, javacEnv, ast, /* assumeAssertionsEnabled */
    false, /* assumeAssertionsDisabled */
    false);
    Analysis<Nullness, LocalStore<Nullness>, TrustingNullnessPropagation> analysis = new Analysis<>(javacEnv, nullnessPropagation);
    analysis.performAnalysis(cfg);
    return analysis.getValue(initializer);
}
Also used : VariableTree(com.sun.source.tree.VariableTree) LocalStore(com.google.errorprone.dataflow.LocalStore) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) TreePath(com.sun.source.util.TreePath) Analysis(org.checkerframework.dataflow.analysis.Analysis) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment) ExpressionTree(com.sun.source.tree.ExpressionTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST)

Example 3 with UnderlyingAST

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

the class Analysis method init.

/** Initialize the analysis with a new control flow graph. */
protected void init(ControlFlowGraph cfg) {
    this.cfg = cfg;
    thenStores = new IdentityHashMap<>();
    elseStores = new IdentityHashMap<>();
    inputs = new IdentityHashMap<>();
    storesAtReturnStatements = new IdentityHashMap<>();
    worklist = new Worklist(cfg);
    nodeValues = new IdentityHashMap<>();
    finalLocalValues = new HashMap<>();
    worklist.add(cfg.getEntryBlock());
    List<LocalVariableNode> parameters = null;
    UnderlyingAST underlyingAST = cfg.getUnderlyingAST();
    if (underlyingAST.getKind() == Kind.METHOD) {
        MethodTree tree = ((CFGMethod) underlyingAST).getMethod();
        parameters = new ArrayList<>();
        for (VariableTree p : tree.getParameters()) {
            LocalVariableNode var = new LocalVariableNode(p);
            parameters.add(var);
        // TODO: document that LocalVariableNode has no block that it
        // belongs to
        }
    } else if (underlyingAST.getKind() == Kind.LAMBDA) {
        LambdaExpressionTree lambda = ((CFGLambda) underlyingAST).getLambdaTree();
        parameters = new ArrayList<>();
        for (VariableTree p : lambda.getParameters()) {
            LocalVariableNode var = new LocalVariableNode(p);
            parameters.add(var);
        // TODO: document that LocalVariableNode has no block that it
        // belongs to
        }
    } else {
    // nothing to do
    }
    S initialStore = transferFunction.initialStore(underlyingAST, parameters);
    Block entry = cfg.getEntryBlock();
    thenStores.put(entry, initialStore);
    elseStores.put(entry, initialStore);
    inputs.put(entry, new TransferInput<>(null, this, initialStore));
}
Also used : MethodTree(com.sun.source.tree.MethodTree) CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) VariableTree(com.sun.source.tree.VariableTree) ArrayList(java.util.ArrayList) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ExceptionBlock(org.checkerframework.dataflow.cfg.block.ExceptionBlock) SpecialBlock(org.checkerframework.dataflow.cfg.block.SpecialBlock) Block(org.checkerframework.dataflow.cfg.block.Block) RegularBlock(org.checkerframework.dataflow.cfg.block.RegularBlock) ConditionalBlock(org.checkerframework.dataflow.cfg.block.ConditionalBlock) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST)

Aggregations

VariableTree (com.sun.source.tree.VariableTree)3 UnderlyingAST (org.checkerframework.dataflow.cfg.UnderlyingAST)3 LocalStore (com.google.errorprone.dataflow.LocalStore)2 ExpressionTree (com.sun.source.tree.ExpressionTree)2 TreePath (com.sun.source.util.TreePath)2 JavacProcessingEnvironment (com.sun.tools.javac.processing.JavacProcessingEnvironment)2 Analysis (org.checkerframework.dataflow.analysis.Analysis)2 ControlFlowGraph (org.checkerframework.dataflow.cfg.ControlFlowGraph)2 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)1 MethodTree (com.sun.source.tree.MethodTree)1 Tree (com.sun.source.tree.Tree)1 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)1 ArrayList (java.util.ArrayList)1 Nullable (javax.annotation.Nullable)1 CFGMethod (org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod)1 Block (org.checkerframework.dataflow.cfg.block.Block)1 ConditionalBlock (org.checkerframework.dataflow.cfg.block.ConditionalBlock)1 ExceptionBlock (org.checkerframework.dataflow.cfg.block.ExceptionBlock)1 RegularBlock (org.checkerframework.dataflow.cfg.block.RegularBlock)1 SpecialBlock (org.checkerframework.dataflow.cfg.block.SpecialBlock)1