“IDE将IFDS的“一个事实在不在集合里”推广为“每个事实携带哪个抽象值”。它取有限事实域D和一个有限高度的完备格L,程序点上的环境为”
形式陈述
IFDS处理一类能够分解为单个事实传播的过程间数据流问题。名字中的四项条件缺一不可:I是过程间,F与S要求有限事实域及其子集,D要求转移函数对合流分配。
固定一张有匹配调用点和返回点的过程间图。取有限事实集D,每个程序点的值为
将函数拆成一张二部图
因为D有限,分配律给出
引入不属于D的零事实
,保持这份可达标记 ,若 ,若
最后一项去掉已由零事实覆盖的输出,只是节省冗余边;保留它们也不会改变结果。把每个程序点v展开成
直觉
普通数据流函数接收一整袋事实,似乎需要为
比如污染传播 y=x 的规则是“保留除y以外的旧污染,若x污染则y污染”。它只需要一条
例子与边界
手算污染事实
取 y=x 对输入S的转移是
它的图含
语句 x=source() 无条件令x污染,所以有 x=clean() 则删除所有到输出x的事实边。其他未被写入变量保留恒等边。使用零事实能区分“没有污染事实但程序可达”和“这个程序点根本不可达”。
两次调用共用摘要,仍各自返回
令 copy(p){ return p; },主程序为
x = source()
y = copy(x) // c1
z = copy(clean()) // c2
sink(z)
调用边将污染的实参x映到copy的形参p;过程体的摘要把入口p映到出口返回值ret。匹配的返回边在
若允许第一调用的p事实经过程出口直接回到
一个不符合IFDS条件的转移
令
则
推论与应用
Tabulation怎样处理递归
求解器保存形如
当某条路径抵达被调过程出口,就生成入口事实到出口事实的摘要。把它接到已登记的匹配调用边和返回边上,继续调用者的同层路径。若摘要先出现、调用者后出现,也必须立即应用已有摘要;若调用者先登记、摘要后出现,则由新摘要唤醒等待者。两种信息到达顺序都处理,才不会漏掉递归迭代中较晚建立的关系。
调用点到返回点的旁路边用于传播不受该调用影响的事实,不能把可能被过程写坏的全局变量也当成无条件保持。实参映射、返回映射与副作用本身属于分析的输入模型;tabulation不能修复这些边上错误的流函数。
有限过程点和有限D使可保存的入口到程序点事实对有限,规则只增不减,所以迭代终止。每条新摘要由匹配调用和已有同层路径构成,保证可靠;反方向按合法路径的嵌套调用结构归纳,保证所有必要摘要最终生成。因此结果恰为给定图和转移的MVP。
成本与可检查输出
设原过程间图有
算法输出可以保留每个摘要的推导来源。检查一个污染告警时,就能沿事实边和匹配调用返回恢复见证;但见证仍是一条抽象合法路径,若分支条件不相容,还需要后续可行性检查。IDE进一步在这些依赖边上附值函数,让事实携带常量等信息。
单元任务与解答
给出上面两次copy调用的全部污染来源,判断sink(z)是否应报警。解答是:唯一源边
验收应另外给出错误普通可达法的假见证:经
参考资料
- Thomas Reps, Susan Horwitz, Mooly Sagiv, “Precise Interprocedural Dataflow Analysis via Graph Reachability”, POPL, 1995,§3的分配函数关系表示与Theorem 3.8;§4的tabulation;§5及附录的复杂度
- Anders Møller and Michael I. Schwartzbach, Static Program Analysis,2026年8月版,§§9.3–9.4:零事实、二部图和IFDS约束