1 / 14

Ridiculously Generic Program Analysis

An analysis tool for static analysis of programs, focusing on nullness and control flow graph analysis. Provides automated sharing of knowledge between analyzers.

Download Presentation

Ridiculously Generic Program Analysis

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Ridiculously Generic Program Analysis James Koppel, MIT

  2. Actually writing a static analyzer Value val=null;if (left==NullConstant.v()) {if (right!=NullConstant.v()) {val = right; }} else if (right==NullConstant.v()) {if (left!=NullConstant.v()) {val = left; }}if (val!=null && valinstanceofLocal) {if (eqExprinstanceofJEqExpr) //a==nullhandleEquality(val,outBranch); else if…….. } NullnessAnalysis Source: Soot Framework

  3. Problems • Syntactic pattern-matching • Runs on IR • Lots of cases; easy to miss • Specific to one version of one language • Must hard-code use of other analyzers

  4. Goals • Define analyzers semantically • Derive most of tool automatically • Reuse work between languages • Reuse work between tools • Analyzers can automatically share knowledge

  5. Ideas • Parametric interpretation, parametric syntax • From one program, multiple tools for multiple languages • Type-level obligations • Constrain what analyzers and languages may combine • Generalized nodes • One type definition gives AST, CFG, etc • Modular monadic semantics • Automatically combine different analyzers • Monads without lambdas!

  6. General Type public interface Exp<C,L,S> { ….} Language Sort Eval Context

  7. Parametric Interpretation Interpreter cond.eval(); // returns false elseBranch.eval(); ConcreteEvalContext Compiler <cond code> testeax jnzelse_branch <stmt 1 code> jmp end else_branch: <stmt2 code> end: Single Source of Truth public class If { …. public void eval(EvalContextctx) { ctx.eval(cond).branch( () -> ctx.eval(thenBranch), () -> ctx.eval(elseBranch)); } } DeferredEvalContext Abstract boolean type Control flow graph FlowGraphContext thenBranch . . . . . . . Dataflow analysis Symbolic execution

  8. Parametric Syntax (C_PP, Assign) ∈ Has (C_PP, Deref) )∈ Has (Java, Assign) ∈ Has public class Assign<L> { …. public Assign(Var<L> lhs, Exp<L> rhs, Has<L, Assign> h) { …. } }

  9. Statically checking compatibility prog :: ∀c ⊆ Stateful[c] ∩ Cont[c], Exp[c] Assign[U ⊆ Stateful[U]] CallCC[U ⊆ Cont [U]] Each expression constrains what EvalContext’s the program can run in prog[ConcreteEvalContext] prog[FlowGraphContext]

  10. Generalized representation 1 + * x ConcreteExp public class BinOp extendsConcreteExp { private Exp lhs; private Exprhs; … } y z DataflowExp t1 := y *z t2 := x + t1

  11. Generalized Representation 2 public class Seq<C> extendsConcreteExp<C, Void> { … publicContextVal<C, Void> eval(C c) { … } } public class IntLit<C> extendsConcreteExp<C, Integer> { … publicContextVal<C, Integer> eval(C c) { … } }

  12. Monadic Combination Transfer: (Label -> Bool, Var -> NullnessLattice) -> (Var -> NullnessLattice, Label -> Bool) ReachabilityAnalyzer lift NullnessAnalyzer Transfer: (Var-> NullnessLattice) -> (Var -> NullnessLattice)

  13. Monads without Lambdas public class Seq { … public void eval(EvalContextctx) { ctx.eval(stmt1); ctx.eval(stmt2); } } Could both be nondeterministic

  14. Result: Nullness Analysis Analyzer a = new Analyzer(); a.addDataflowState( newNullnessLattice()); a.overrideTransferFunction( newBooleanConstantProp()); Evaluation will automatically case-split on (x == null) if(x != null || y != null) { … } else{ … } Evaluate condition; propagate states to branches

More Related