|
Static Value-Flow Analysis
|
#include <AbstractInterpretation.h>
Classes | |
| struct | AllocationSizeBounds |
Public Types | |
| enum | AESparsity { Dense , SemiSparse , Sparse } |
| enum | HandleRecur { TOP , WIDEN_ONLY , WIDEN_NARROW } |
| enum | AEFunEntryMode { MAIN , NO_MAIN } |
Static Public Member Functions | |
| static AbstractInterpretation & | getAEInstance () |
Protected Member Functions | |
| AbstractInterpretation () | |
| bool | isStrongUpdate (const AddressValue &targets, const AbstractState &state) const |
| virtual AbstractState | getFullCycleHeadState (const ICFGCycleWTO *cycle) |
| virtual bool | widenCycleState (const AbstractState &prev, const AbstractState &cur, const ICFGCycleWTO *cycle) |
| virtual bool | narrowCycleState (const AbstractState &prev, const AbstractState &cur, const ICFGCycleWTO *cycle) |
| virtual bool | mergeStatesFromPredecessors (const ICFGNode *node) |
| bool | isBranchEdgeFeasible (const IntraCFGEdge *edge, AbstractState &as) |
| bool | applyBranchRefinement (const IntraCFGEdge *edge, AbstractState &as) |
| bool | shouldApplyNarrowing (const FunObjVar *fun) |
| Check if narrowing should be applied: always for regular loops, mode-dependent for recursion. | |
Protected Attributes | |
| SVFIR * | svfir {nullptr} |
| Data and helpers reachable from SparseAbstractInterpretation. | |
| AEWTO * | preAnalysis {nullptr} |
| Map< const ICFGNode *, AbstractState > | abstractTrace |
| per-node trace; owned here | |
Private Attributes | |
| AEAPI * | api {nullptr} |
| Execution State, used to store the Interval Value of every SVF variable. | |
| ICFG * | icfg |
| CallGraph * | callGraph |
| AEStat * | stat |
| Map< std::string, std::function< void(const CallICFGNode *)> > | func_map |
| Set< const ICFGNode * > | allAnalyzedNodes |
| std::string | moduleName |
| std::vector< std::unique_ptr< AEDetector > > | detectors |
| AbsExtAPI * | utils |
Friends | |
| class | AEStat |
| class | AEAPI |
| class | BufOverflowDetector |
| class | NullptrDerefDetector |
AbstractInterpretation is same as Abstract Execution.
Owns the per-node abstract trace and exposes the read/write API directly (no separate state-manager indirection). Sparse modes are implemented as subclasses that override the virtual hooks below (cycle helpers, ValVar accessors, joinStates, def/use queries).
Definition at line 60 of file AbstractInterpretation.h.
| Enumerator | |
|---|---|
| MAIN | |
| NO_MAIN | |
Definition at line 97 of file AbstractInterpretation.h.
| Enumerator | |
|---|---|
| Dense | |
| SemiSparse | |
| Sparse | |
Definition at line 83 of file AbstractInterpretation.h.
| Enumerator | |
|---|---|
| TOP | |
| WIDEN_ONLY | |
| WIDEN_NARROW | |
Definition at line 90 of file AbstractInterpretation.h.
|
virtual |
|
protected |
Factory-only construction. External callers must use getAEInstance(); SparseAbstractInterpretation reaches this via its own ctor.
Definition at line 61 of file AbstractInterpretation.cpp.
|
inline |
Definition at line 124 of file AbstractInterpretation.h.
| void AbstractInterpretation::analyse | ( | ) |
Program entry.
Program entry - entry policy is selected by -ae-fun-entry.
Definition at line 200 of file AbstractInterpretation.cpp.
| void AbstractInterpretation::analyzeFromAllProgEntries | ( | ) |
Analyze all entry points (functions without callers)
Analyze the entry functions selected by collectProgEntryFuns(). Abstract state is shared across entry points so that functions analyzed from earlier entries are not re-analyzed from scratch.
Definition at line 208 of file AbstractInterpretation.cpp.
|
protected |
Derive cmp/switch constraints and apply them to this temporary input. Narrow only carried interval Obj values reached through one known pointer target, without changing the backing load's trace. Return false when a carried value contradicts the selected branch.
Definition at line 566 of file AbstractInterpretation.cpp.
| FIFOWorkList< const FunObjVar * > AbstractInterpretation::collectProgEntryFuns | ( | ) |
Get all entry point functions (functions without callers)
Collect entry point functions for analysis. In main mode, entry is main/svf.main. In no-main mode, entries are SCCs with no external caller in the Andersen-resolved CallGraph.
Definition at line 122 of file AbstractInterpretation.cpp.
|
private |
Definition at line 1191 of file AbstractInterpretation.cpp.
|
private |
Evaluate a pointer-typed ICMP over abstract points-to alternatives. Object IDs identify targets but their numeric order does not model runtime address order, so only equality and inequality can produce a definite result.
Definition at line 1145 of file AbstractInterpretation.cpp.
| AbstractState & AbstractInterpretation::getAbsState | ( | const ICFGNode * | node | ) |
Definition at line 44 of file AbstractStateManager.cpp.
| void AbstractInterpretation::getAbsState | ( | const Set< const ObjVar * > & | vars, |
| AbstractState & | result, | ||
| const ICFGNode * | node | ||
| ) |
Definition at line 171 of file AbstractStateManager.cpp.
| void AbstractInterpretation::getAbsState | ( | const Set< const SVFVar * > & | vars, |
| AbstractState & | result, | ||
| const ICFGNode * | node | ||
| ) |
Definition at line 181 of file AbstractStateManager.cpp.
| void AbstractInterpretation::getAbsState | ( | const Set< const ValVar * > & | vars, |
| AbstractState & | result, | ||
| const ICFGNode * | node | ||
| ) |
Definition at line 161 of file AbstractStateManager.cpp.
|
virtual |
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 93 of file AbstractStateManager.cpp.
|
virtual |
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 100 of file AbstractStateManager.cpp.
|
virtual |
Read a top-level variable's abstract value. Dense base does a direct trace lookup; sparse subclasses override with their own resolution chain (def-site walk, call-result fallback, etc.). All three overloads are virtual so full-sparse can route ObjVar reads through the SVFG.
Dense base: direct trace lookup, with a type-directed top value for genuinely missing entries (e.g. function parameters never written before first read). Sparse subclasses override with a def-site resolution chain.
The "in map" check is a raw map.count — NOT inVarToValTable / inVarToAddrsTable, which gate on isInterval / isAddr. SVF canonically represents uninit and null-pointer shapes as (interval=bottom ∧ addrs=∅); those predicates would falsely report such an entry as "not present", and the top fallback below would then clobber the very signal NullptrDerefDetector::isUninit keys off.
Reimplemented in SVF::SemiSparseAbstractInterpretation, and SVF::SemiSparseAbstractInterpretation.
Definition at line 79 of file AbstractStateManager.cpp.
|
static |
Factory: returns the singleton instance. The concrete class is chosen once, on first call, from Options::AESparsity(): SemiSparseAbstractInterpretation for SemiSparse, FullSparseAbstractInterpretation for Sparse, otherwise the dense base. Must be called only after the option parser has run.
Factory: first call allocates the concrete subclass based on Options::AESparsity(); all subsequent calls return the same instance. Must only be called after the option parser has populated AESparsity.
Definition at line 76 of file AbstractInterpretation.cpp.
| AbstractInterpretation::AllocationSizeBounds AbstractInterpretation::getAllocaInstByteSize | ( | const AddrStmt * | addr | ) |
Definition at line 430 of file AbstractStateManager.cpp.
|
private |
Get callee function: directly for direct calls, via pointer analysis for indirect calls.
Definition at line 842 of file AbstractInterpretation.cpp.
|
protectedvirtual |
Build a full cycle-head AbstractState. Dense default: trace[cycle_head] as-is. Semi-sparse subclass: also pull cycle ValVars from def-sites.
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 162 of file AELoopRecursion.cpp.
| IntervalValue AbstractInterpretation::getGepByteOffset | ( | const GepStmt * | gep | ) |
Definition at line 256 of file AbstractStateManager.cpp.
| IntervalValue AbstractInterpretation::getGepElementIndex | ( | const GepStmt * | gep | ) |
Definition at line 199 of file AbstractStateManager.cpp.
| AddressValue AbstractInterpretation::getGepObjAddrs | ( | const ValVar * | pointer, |
| IntervalValue | offset | ||
| ) |
Definition at line 316 of file AbstractStateManager.cpp.
| const SVFType * AbstractInterpretation::getPointeeElement | ( | const ObjVar * | var, |
| const ICFGNode * | node | ||
| ) |
Definition at line 414 of file AbstractStateManager.cpp.
|
inline |
Definition at line 201 of file AbstractInterpretation.h.
|
inlineprivate |
Definition at line 336 of file AbstractInterpretation.h.
Handle a call site node: dispatch to ext-call, direct-call, or indirect-call handling.
Definition at line 809 of file AbstractInterpretation.cpp.
|
privatevirtual |
Definition at line 832 of file AbstractInterpretation.cpp.
|
privatevirtual |
Handle direct or indirect call: get callee(s), process function body, set return state.
For direct calls, the callee is known statically. For indirect calls, the previous implementation resolved callees from the abstract state's address domain, which only picked the first address and missed other targets. Since the abstract state's address domain is not an over-approximation for function pointers (it may be uninitialized or incomplete), we now use Andersen's pointer analysis results from the pre-computed call graph, which soundly resolves all possible indirect call targets.
Definition at line 876 of file AbstractInterpretation.cpp.
|
private |
Handle a function body via worklist-driven WTO traversal starting from funEntry.
Handle a function using worklist algorithm guided by WTO order. All top-level WTO components are pushed into the worklist upfront, so the traversal order is exactly the WTO order — each node is visited once, and cycles are handled as whole components.
Definition at line 782 of file AbstractInterpretation.cpp.
|
privatevirtual |
Initialize abstract state for the global ICFG node and process global statements
handle global node Initializes the abstract state for the global ICFG node and processes all global statements. This includes setting up the null pointer and black hole pointer (blkPtr). BlkPtr is initialized to point to the BlackHole object, representing an unknown memory location that cannot be statically resolved.
Definition at line 235 of file AbstractInterpretation.cpp.
Handle an ICFG node: execute statements; return true if state changed.
Handle an ICFG node: execute statements on the current abstract state. The node's pre-state must already be in getAbsState(node) (set by mergeStatesFromPredecessors, or by handleGlobalNode for the global node). Returns true if the abstract state has changed, false if fixpoint reached or unreachable.
Definition at line 723 of file AbstractInterpretation.cpp.
|
privatevirtual |
Handle a WTO cycle (loop or recursive function) using widening/narrowing iteration.
Definition at line 235 of file AELoopRecursion.cpp.
Dispatch an SVF statement (Addr/Binary/Cmp/Load/Store/Copy/Gep/Select/Phi/Call/Ret) to its handler.
Definition at line 911 of file AbstractInterpretation.cpp.
Definition at line 64 of file AbstractStateManager.cpp.
|
virtual |
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 122 of file AbstractStateManager.cpp.
|
virtual |
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 130 of file AbstractStateManager.cpp.
|
virtual |
Side-effect-free existence check.
Dense base: direct existence check at node. Mirrors the simplified getAbsValue lookup — uses raw map.contains rather than inVar*Table predicates, which would falsely report neutral (interval=bottom ∧ addrs=∅) entries as "not present".
Reimplemented in SVF::SemiSparseAbstractInterpretation, and SVF::SemiSparseAbstractInterpretation.
Definition at line 114 of file AbstractStateManager.cpp.
|
protected |
Returns true if the branch edge is reachable under the current state. Pure query: does not update abstract states.
Definition at line 706 of file AbstractInterpretation.cpp.
|
private |
Returns true if the cmp-conditional branch is feasible.
Definition at line 494 of file AbstractInterpretation.cpp.
|
privatevirtual |
Definition at line 827 of file AbstractInterpretation.cpp.
|
privatevirtual |
Check if caller and callee are in the same CallGraph SCC (i.e. a recursive callsite)
Definition at line 104 of file AELoopRecursion.cpp.
Check if a function is recursive (part of a call graph SCC)
Definition at line 47 of file AELoopRecursion.cpp.
|
protected |
One abstract address need not denote one concrete cell. Heap allocation sites and recursive locals summarize multiple instances and need weak updates, just like multi-target pointers and merged fields. A separate array element can be strongly updated if elements are modeled separately and its address is unique.
state is needed because getIDFromAddr checks its freed-address set, not just the address bits. An address recorded as freed resolves to the BlackHole Obj and must not receive a strong update.
int x=1, y=3; p=cond ? &x : &y; *p=2; // x:[1,2], y:[2,3] a=foo(); b=foo(); // foo returns malloc: a/b may name one heap summary
Definition at line 359 of file AbstractStateManager.cpp.
|
private |
Check whether any input value can take this switch edge; do not refine it.
Definition at line 522 of file AbstractInterpretation.cpp.
|
private |
True when the edge enters the switch's default destination. LLVM provides this destination even without a source-level default. Explicit cases may share it; this checks the destination only.
Definition at line 511 of file AbstractInterpretation.cpp.
|
virtual |
Join src into dst with sparsity-aware semantics. Dense merges everything; semi-sparse skips ValVars.
Reimplemented in SVF::SemiSparseAbstractInterpretation, and SVF::FullSparseAbstractInterpretation.
Definition at line 59 of file AbstractStateManager.cpp.
|
virtual |
Read memory through the pointer's address targets.
Definition at line 343 of file AbstractStateManager.cpp.
Pull-based state merge: read abstractTrace[pred] for each predecessor, apply branch refinement for conditional IntraCFGEdges, and join into abstractTrace[node]. Returns true if at least one predecessor had state. FullSparse additionally assembles inputs from direct SVFG predecessors.
Pull-based state merge: for each predecessor that has an abstract state, copy its state, apply branch refinement for conditional IntraCFGEdges, and join all feasible states into getAbsState(node). Dense/semi-sparse use their state JOIN; full-sparse merges only freed addresses here and collects Obj values separately through SVFG inputs. Returns true if at least one predecessor contributed state.
Reimplemented in SVF::FullSparseAbstractInterpretation.
Definition at line 268 of file AbstractInterpretation.cpp.
|
protectedvirtual |
Narrow prev with cur; write the narrowed state back. Returns true when narrowing is disabled or the narrowed state equals prev. Semi-sparse subclass scatters the narrowed ValVars on non-fixpoint.
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 183 of file AELoopRecursion.cpp.
|
inline |
Definition at line 205 of file AbstractInterpretation.h.
|
virtual |
collect checkpoint
Definition at line 44 of file AbstractInterpretation.cpp.
Check if narrowing should be applied: always for regular loops, mode-dependent for recursion.
Definition at line 130 of file AELoopRecursion.cpp.
|
privatevirtual |
TOP mode for recursive calls: skip the function body entirely and conservatively set all reachable stores and the return value to TOP.
Definition at line 54 of file AELoopRecursion.cpp.
|
private |
Skip recursive callsites (within SCC); entry calls from outside SCC are not skipped.
Definition at line 112 of file AELoopRecursion.cpp.
|
virtual |
Shared by all sparsity modes: a strong update replaces one concrete cell; a weak update JOINs the old and new values at every possible target.
Definition at line 389 of file AbstractStateManager.cpp.
|
virtual |
Replace the state at node. Sparse subclasses replace only the ObjVar map (ValVars live at def-sites).
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 54 of file AbstractStateManager.cpp.
|
virtual |
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 144 of file AbstractStateManager.cpp.
|
virtual |
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 151 of file AbstractStateManager.cpp.
|
virtual |
Write a variable's abstract value. Sparse subclasses re-route ValVar writes to the def-site.
Reimplemented in SVF::SemiSparseAbstractInterpretation, and SVF::SemiSparseAbstractInterpretation.
Definition at line 139 of file AbstractStateManager.cpp.
Definition at line 1067 of file AbstractInterpretation.cpp.
|
private |
Definition at line 1085 of file AbstractInterpretation.cpp.
Handle CallPE: phi-like merging of actual parameters from all call sites into the formal parameter at FunEntryICFGNode (e.g., formal = join(actual1@cs1, actual2@cs2, ...))
Definition at line 1042 of file AbstractInterpretation.cpp.
Definition at line 1248 of file AbstractInterpretation.cpp.
Definition at line 1291 of file AbstractInterpretation.cpp.
Definition at line 980 of file AbstractInterpretation.cpp.
Definition at line 1276 of file AbstractInterpretation.cpp.
Definition at line 1007 of file AbstractInterpretation.cpp.
Definition at line 1059 of file AbstractInterpretation.cpp.
|
private |
Definition at line 988 of file AbstractInterpretation.cpp.
Definition at line 1284 of file AbstractInterpretation.cpp.
|
protectedvirtual |
Widen prev with cur; write the widened state to trace[cycle_head]. Returns true when next == prev (fixpoint). Semi-sparse subclass additionally scatters ValVars to their def-sites.
Reimplemented in SVF::SemiSparseAbstractInterpretation.
Definition at line 171 of file AELoopRecursion.cpp.
Definition at line 63 of file AbstractInterpretation.h.
Definition at line 62 of file AbstractInterpretation.h.
|
friend |
Definition at line 64 of file AbstractInterpretation.h.
|
friend |
Definition at line 65 of file AbstractInterpretation.h.
|
protected |
per-node trace; owned here
Definition at line 365 of file AbstractInterpretation.h.
Definition at line 355 of file AbstractInterpretation.h.
Execution State, used to store the Interval Value of every SVF variable.
Definition at line 330 of file AbstractInterpretation.h.
|
private |
Definition at line 333 of file AbstractInterpretation.h.
|
private |
Definition at line 358 of file AbstractInterpretation.h.
|
private |
Definition at line 353 of file AbstractInterpretation.h.
|
private |
Definition at line 332 of file AbstractInterpretation.h.
|
private |
Definition at line 356 of file AbstractInterpretation.h.
Definition at line 364 of file AbstractInterpretation.h.
|
private |
Definition at line 334 of file AbstractInterpretation.h.
Data and helpers reachable from SparseAbstractInterpretation.
Definition at line 363 of file AbstractInterpretation.h.
|
private |
Definition at line 359 of file AbstractInterpretation.h.