weir/callgraph.rs
1//! DF-5 - call graph with indirect dispatch resolution.
2//!
3//! Direct calls are trivial - the graph is built during AP-2 lowering.
4//! Indirect calls (fnptr tables, vtables, kernel ops-struct dispatch -
5//! `file_operations`, `net_proto_ops`, `proto_ops`, etc.) require
6//! points-to (DF-3) to resolve the callee set.
7//!
8//! The kernel ops-struct pattern is the largest source of false
9//! negatives in competing tools. We track every struct literal whose
10//! fields are function pointers, index by the struct's type, and when
11//! `x->f(...)` appears with `x : struct T *` the callee set is
12//! `{ s.f | s is a struct T literal in the program }`.
13//!
14//! # Implementation
15//!
16//! The final call-graph bitset per call-site is
17//! `direct ∪ (indirect_sites × points_to_closure)`. Both operands are
18//! bitsets in the CSR-frontier shape we already own, so the kernel
19//! is a per-invocation bitwise OR of two loads plus a bounds check.
20//!
21//! Soundness: [`MayOver`](super::Soundness::MayOver) - may-analysis.
22//!
23//! Gate for C19.
24
25#[cfg(any(test, feature = "cpu-parity"))]
26mod cpu_oracle;
27mod dispatch;
28mod program;
29mod scratch;
30mod tag;
31
32#[cfg(test)]
33mod tests;
34
35pub(crate) const OP_ID: &str = "weir::callgraph";
36
37#[cfg(any(test, feature = "cpu-parity"))]
38#[allow(deprecated)]
39pub(crate) use cpu_oracle::callgraph_build_cpu;
40pub use dispatch::{
41 callgraph_build_borrowed_into_result_with_scratch_via, callgraph_build_borrowed_into_via,
42 callgraph_build_borrowed_via, callgraph_build_borrowed_with_scratch_via, callgraph_build_via,
43};
44pub use program::{callgraph_build, callgraph_build_with_count};
45pub use scratch::CallgraphBuildScratch;
46pub use tag::Callgraph;