为什么 Frama-C 在基本示例中警告 'accessing uninitialized left-value'?

Why is Frama-C warning about 'accessing uninitialized left-value' in basic example?

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

抽象解释器通过在两个控制流路径相遇时执行抽象 ("joins") 来限制其分析的复杂性。这就是您的第二个示例所发生的情况:在第一个 if 结束后,两个分支的抽象被合并。在由此产生的抽象中,p*p 的初始化之间的关系丢失了。

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