在基本示例中,为什么Frama-C警告有关“访问未初始化的左值”?

时间:2018-06-26 16:41:59

标签: frama-c

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

1 个答案:

答案 0 :(得分:2)

当两个控制流路径相遇时,抽象解释器通过执行抽象(“联接”)来限制分析的复杂性。这就是您的第二个示例所发生的情况:在第一个if结束之后,两个分支的抽象被连接在一起。在最终的抽象中,p*p的初始化之间的关系丢失了。

在Frama-C / Eva中,当多个控制流路径相遇时,可能执行连接,而是并行传播状态集。这些集合的最大基数由参数-slevel控制。这里-slevel 2足以证明您的第二个例子。