Frama-C认为以下代码正确(无警告,无错误):
#include <stdio.h>
#include <stdlib.h>
int *p;
int main() {
p = malloc(sizeof(int));
if (p!=NULL) {
*p = 9;
printf("*p = %d\n",(int) (*p));
}
return(1);
}
但是,如果我通过分割if-then-else来稍微更改代码:
#include <stdio.h>
#include <stdlib.h>
int *p;
int main() {
p = malloc(sizeof(int));
if (p!=NULL) {
*p = 9;
}
if (p!=NULL) {
printf("*p = %d\n",(int) (*p));
}
return(1);
}
我收到消息:
test6.c:13:[value] warning: accessing uninitialized left-value. assert \initialized(p);
问题是,为什么Frama-C考虑p
可能会访问未初始化的左值?我想念什么?
我使用以下命令调用Frama-C:
frama-c-gui -val test.c
答案 0 :(得分:2)
当两个控制流路径相遇时,抽象解释器通过执行抽象(“联接”)来限制分析的复杂性。这就是您的第二个示例所发生的情况:在第一个if
结束之后,两个分支的抽象被连接在一起。在最终的抽象中,p
和*p
的初始化之间的关系丢失了。
在Frama-C / Eva中,当多个控制流路径相遇时,可能不执行连接,而是并行传播状态集。这些集合的最大基数由参数-slevel
控制。这里-slevel 2
足以证明您的第二个例子。