Search in sources :

Example 1 with ControlFlowGraph

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

the class DataFlow method methodDataflow.

/**
   * Run the {@code transfer} dataflow analysis over the method or lambda which is the leaf of the
   * {@code methodPath}.
   *
   * <p>For caching, we make the following assumptions:
   * - if two paths to methods are {@code equal}, their control flow graph is the same.
   * - if two transfer functions are {@code equal}, and are run over the same control flow graph,
   *   the analysis result is the same.
   * - for all contexts, the analysis result is the same.
   */
private static <A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>> Result<A, S, T> methodDataflow(TreePath methodPath, Context context, T transfer) {
    final ProcessingEnvironment env = JavacProcessingEnvironment.instance(context);
    final ControlFlowGraph cfg = cfgCache.getUnchecked(CfgParams.create(methodPath, env));
    final AnalysisParams aparams = AnalysisParams.create(transfer, cfg, env);
    @SuppressWarnings("unchecked") final Analysis<A, S, T> analysis = (Analysis<A, S, T>) analysisCache.getUnchecked(aparams);
    return new Result<A, S, T>() {

        @Override
        public Analysis<A, S, T> getAnalysis() {
            return analysis;
        }

        @Override
        public ControlFlowGraph getControlFlowGraph() {
            return cfg;
        }
    };
}
Also used : UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST) Analysis(org.checkerframework.dataflow.analysis.Analysis) ControlFlowGraph(org.checkerframework.dataflow.cfg.ControlFlowGraph) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) JavacProcessingEnvironment(com.sun.tools.javac.processing.JavacProcessingEnvironment)

Example 2 with ControlFlowGraph

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

use of org.checkerframework.dataflow.cfg.ControlFlowGraph 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)

Aggregations

JavacProcessingEnvironment (com.sun.tools.javac.processing.JavacProcessingEnvironment)3 Analysis (org.checkerframework.dataflow.analysis.Analysis)3 ControlFlowGraph (org.checkerframework.dataflow.cfg.ControlFlowGraph)3 UnderlyingAST (org.checkerframework.dataflow.cfg.UnderlyingAST)3 LocalStore (com.google.errorprone.dataflow.LocalStore)2 ExpressionTree (com.sun.source.tree.ExpressionTree)2 VariableTree (com.sun.source.tree.VariableTree)2 TreePath (com.sun.source.util.TreePath)2 Tree (com.sun.source.tree.Tree)1 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)1 Nullable (javax.annotation.Nullable)1 ProcessingEnvironment (javax.annotation.processing.ProcessingEnvironment)1