“0 CFA像只按变量名字设邮箱:identity的形参x收到过哪些函数,全放进同一箱。1 CFA再按“从哪个调用点送来的”分箱。它与调用串上下文敏感性共享截断思想,但还必须处理高阶闭包的词法…”
形式陈述
过程间分析把多个控制流图通过调用边与返回边连接起来。对调用点
如果多个调用点都调用f,出口便连接多个返回位置。但一条真实执行只能返回当前栈顶那次调用的后继,不能任意选出口的另一条边。给每条调用边标记
路径可以在函数内部结束,因此最后栈不一定为空。若开始和结束在同一调用层,而且中间不弹出起始层,称同层合法路径。下推栈使这个定义能够表达任意深递归。
上下文敏感分析以某种表示区分不同调用环境。常见接口是
直觉
过程内分析把信息沿后继边传走就够了。跨函数后,一条出口边还承诺“我属于哪次尚未完成的调用”。如果把这层配对丢掉,就像把两次电话的回答接给错误的来电者。
调用图决定有哪些可能的被调函数;上下文敏感分析决定这些调用的事实如何传入、怎样回到对应调用者。目标集合精确不代表返回已经匹配,反之亦然。
例子与边界
同一个恒等函数也会被分析“串线”
考虑纯函数 identity(z){ return z; },以及
a = identity(0) // c1,返回到r1
b = identity(1) // c2,返回到r2
assert(a == 0 && b == 1)
真实执行分别把0交给a、1交给b。若只为identity入口保存一个抽象状态,参数z可能被合并为“0或1”;出口的统一结果再流到两个返回点,分析可能无法证明断言。
更明显的假路径是:从
调用串如何区分,又如何合并
长度1的调用串把identity的两次入口分别记为
截断不是把栈简单弹一次就能求逆。例如长度1上下文
长度k的调用串有至多
摘要可以不逐个复制所有调用上下文
对identity,入口到出口摘要就是函数
对于有全局状态的过程,摘要要描述可能影响的全局量;对堆写入,还要接入别名信息。递归使摘要互相依赖,需要求解不动点。单调数据流分析提供迭代骨架,具体摘要的表示决定是否有限、能否高效合成。
推论与应用
应区分三个精度维度。流敏感性按程序点保留顺序;上下文敏感性区分调用环境;路径敏感性保留足以区别分支条件的信息。一个分析可以上下文敏感但流不敏感,也可以在每个函数内很精确却把所有调用者合并。
即便只合流调用返回合法路径,仍可能包含不可行分支。例如先判断x>0,随后在没有改变x时又走x≤0分支,这是一条调用返回配对正确、但数值条件矛盾的图路径。因此“对所有合法过程间路径精确”不能写成“对真实程序执行精确”。
对一般有限抽象域,复制每个
单元任务入口:识别三种不同的伪告警
给一个有两次identity调用、一个共享指针和一处分支的程序,先画出调用点配对,再标出三种不确定性:错误返回边、指针may-alias、多条分支合流。只有第一种能仅靠调用返回匹配解决;第二种需要指针抽象,第三种需要更强的路径条件。
对本页程序,验收解答必须给出
参考资料
- Anders Møller and Michael I. Schwartzbach, Static Program Analysis,2026年8月版,Chapter 8:过程间图、调用串、函数摘要;Chapter 9:合法路径与摘要求解
- Thomas Reps, Susan Horwitz, Mooly Sagiv, “Precise Interprocedural Dataflow Analysis via Graph Reachability”, POPL, 1995,§§2–3:valid path与same-level path