如何证明此Assigns子句第2部分?

时间:2018-11-02 21:41:54

标签: frama-c

我想不出任何想法来证明foo的assigns子句。我尝试了assigns var;,因为foo()间接修改了全局var变量,但是它不起作用。有没有一种方法可以获取本地assigns的{​​{1}}子句或从p返回的位置?这是代码:

a()

frama-c命令:

int var; //@ assigns \nothing; int *a(){ return &var; } //@ assigns *p; void b(int* p){ *p = 1; } //@ assigns \nothing; void foo(){ int *p = a(); b(p); } //@ assigns var; void main(){ var = 0; foo(); return; }

frama-c -wp test.c

1 个答案:

答案 0 :(得分:1)

如您所料,foo确实分配了一些东西,而assigns \nothing是此函数的无效子句。正确的子句确实是assigns var。在assigns子句中,您必须列出所有已修改的全局变量,以及所有在调用者本地且可以通过形式引用的变量。

现在,为什么不使用assigns var进行变体证明?好吧,按照foo的说法,WP无法猜测p指向的位置,因为它无法知道它实际上等于&a。您必须将此信息添加到功能a的规范中。通过此修改,证明是即时的。

完整代码:

int var;

/*@ assigns \nothing;
    ensures \result == &var; */
int *a(){
    return &var;
}

//@ assigns *p;
void b(int* p){
  *p = 1;
}

//@ assigns var;
void foo(){
   int *p = a();
   b(p);
}

//@ assigns var;
void main(){
    var = 0;
    foo();
    return;
}