如何在Frama-C + EVA中证明不确定性值的简单等式?

时间:2019-05-16 19:31:59

标签: c static-analysis frama-c abstract-interpretation

我对Frama-C 18.0版(Argon)的行为感到有些困惑。

给出以下程序:

#include <assert.h>
#include <limits.h>


/*@ requires order: min <= max;
    assigns \result \from min, max;
    ensures result_bounded: min <= \result <= max ;
 */
extern int Frama_C_interval(int min, int max);


int main() {

  int i,j;

  i = Frama_C_interval(INT_MIN, INT_MAX);

  j = i;

  assert(j == i);

  return 0;
}

我希望断言可以很容易地用任何跟踪相等性的抽象域来证明。但是,调用

  

frama-c -eva -eva-equality-domain -eva-polka-equalities foo.c

礼物:

[eva] Warning: The Apron domains binding is experimental.
[kernel] Parsing stupid_test.c (with preprocessing)
[eva] Analyzing a complete application starting at main
[eva] Computing initial state
[eva] Initial state computed
[eva:initial-state] Values of globals at initialization

[eva] using specification for function Frama_C_interval
[eva] using specification for function __FC_assert
[eva:alarm] foo.c:20: Warning: 
  function __FC_assert: precondition 'nonnull_c' got status unknown.
[eva] done for function main
[eva] ====== VALUES COMPUTED ======
[eva:final-states] Values at end of function main:
  i ∈ [--..--]
  j ∈ [--..--]
  __retres ∈ {0}

我想念什么吗?

1 个答案:

答案 0 :(得分:4)

有趣。您的示例未由-eva -eva-equality-domain处理,而编写此示例是出于其他目的。这样,尚未编写x == yx相等时y的特殊情况。这将相当容易添加。

(给出域的名称,这可能会令人惊讶。当我们使用不感兴趣的别名(例如内核添加的临时变量)时,相等域更适合于实现更多的向后传播。)

关于来自围裙的域名,这更令人惊讶。我这样修改了您的示例:

  j = i;

  int b = j - i;
  int c = j == i;
  Frama_C_dump_each_domain();

运行frama-c -eva -eva-polka-equalities foo.c -value-msg-key d-apron得到以下结果:

[eva] c/eq.c:23: 
  Frama_C_dump_each_domain:
  # Cvalue domain:
  i ∈ [--..--]
  j ∈ [--..--]
  b ∈ {0}
  c ∈ {0; 1}
  __retres ∈ UNINITIALIZED
  # Polka linear equalities domain:
  [|-i_44+j_45=0; b_46=0|]

如您所见,Apron推断了ij之间的关系(后缀是行号),将b简化为0,但没有简化{{1 }}到1。这令我惊讶,但可以解释您观察到的不精确性。八边形域也不起作用。

我对关系域上的抽象转换器不那么熟悉,所以这是可以预期的,但这无疑令人困惑。用于处理关系运算符的代码存在于Frama-C / Eva / Apron中,但部分是本地编写的(它不仅是对Apron原语的简单调用)。特别是,它调用运算符进行减法运算,并分析结果与0的相等性。很难理解为什么c会是精确的,而b却不是。