Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何让Frama-C在测试中理解位和?_C_Frama C - Fatal编程技术网

如何让Frama-C在测试中理解位和?

如何让Frama-C在测试中理解位和?,c,frama-c,C,Frama C,我试图使用Frama-C值分析来研究生成的大型C代码,其中绑定检查是使用位AND(&)而不是逻辑AND(&&)来完成的。例如: int t[3]; ... if ((0 <= x) & (x < 3)) t[x] = 0; intt[3]; ... 如果((0在该示例中,&的两侧已经是0或1,那么在这种情况下,使用&而不是&是可以的 有什么理由这样写测试吗 不,我想不出他们会故意这么做的任何原因。一般来说,这是个坏主意,因为如果以后更改了代码,并且&的一侧不再是0-1

我试图使用Frama-C值分析来研究生成的大型C代码,其中绑定检查是使用位AND(&)而不是逻辑AND(&&)来完成的。例如:

int t[3];
...
if ((0 <= x) & (x < 3)) 
  t[x] = 0;
intt[3];
...

如果((0在该示例中,
&
的两侧已经是0或1,那么在这种情况下,使用
&
而不是
&
是可以的

有什么理由这样写测试吗

不,我想不出他们会故意这么做的任何原因。一般来说,这是个坏主意,因为如果以后更改了代码,并且
&
的一侧不再是0-1值,那么代码就会中断

现在转到实际的问题:


intt[3];
是否也多次生成(例如在{}内生成)或仅生成一次?如果只定义一次,则问题的解决方案是对其进行malloc:
int*t=malloc(3*sizeof(int))
。编译器将不再抱怨。

下面的补丁将使Value统一处理
e1&&e1
c1&c2
,其中
c1
c2
是条件(但不是任意表达式)


谢谢你的解释,但我不认为你给出的解决方案是正确的。Frama-C不是一个编译器,而是一个静态分析器,我确实希望它在访问t[x]时检查x是否在0到3之间。问题是,Frama没有捕捉到
((0@eznme)
t[x]这一点再明显不过了当
t
指向一个大小为3 int的malloc分配块时,而
t
是一个数组时,
是一个有效的内存访问,因此使用
malloc
将不会绕过任何检查。Frama-C仍然会发出关于写入
t[x]
的警告,只要它不能看到0≤ x<3.通常静态分析器不看malloc括号中的内容,奇怪。也许你必须更加间接:定义一个全局(甚至可能是易变的),然后在其他地方将计数(3)分配给它,然后调用malloc(thatlobal)。这样静态分析器就不能再计算出有多少内存可用了。@eznme Frama-C中的分析努力做到正确:如果没有发出警告,则保证程序是安全的。相反,一旦对操作的有效性有疑问,它们就会报告警告。不可能使waAnne报道的rning通过混淆程序而消失;你只会得到更多。请继续关注,补丁正在测试中。非常感谢!我会尝试一下,并在我的真实代码中检查后尽快接受答案。
warning: accessing out of bounds index [-2147483648..2147483647]. assert 0 ≤ x < 3;
//@ assert (x < 0 || 0<=x);
//@ assert (x < 3 || 3<=x);
Index: src/value/eval_exprs.ml
===================================================================
--- src/value/eval_exprs.ml (révision 21388)
+++ src/value/eval_exprs.ml (copie de travail)
@@ -1748,11 +1748,23 @@
         reduce_by_comparison ~with_alarms reduce_rel
           cond.positive exp1 binop exp2 state

-      | true, BinOp (LAnd, exp1, exp2, _)
-      | false, BinOp (LOr, exp1, exp2, _) ->
+      | true,
+        ( BinOp (LAnd, exp1, exp2, _)
+        | BinOp (BAnd, (* 'cond1 & cond2' can be treated as 'e1 && e2' *)
+                 ({ enode = BinOp ((Le|Ne|Eq|Gt|Lt|Ge), _, _, _)} as exp1),
+                 ({ enode = BinOp ((Le|Ne|Eq|Gt|Lt|Ge), _, _, _)} as exp2),
+                 _))
+      | false,
+        ( BinOp (LOr, exp1, exp2, _)
+        | BinOp (BOr, (* '!(cond1 | cond2)' can be treated as '!(e1 || e2)' *)
+                 ({ enode = BinOp ((Le|Ne|Eq|Gt|Lt|Ge), _, _, _)} as exp1),
+                 ({ enode = BinOp ((Le|Ne|Eq|Gt|Lt|Ge), _, _, _)} as exp2),
+                 _))
+          ->
           let new_state = aux {cond with exp = exp1} state in
           let result = aux {cond with exp = exp2} new_state in
           result
+
       | false, BinOp (LAnd, exp1, exp2, _)
       | true, BinOp (LOr, exp1, exp2, _) ->
           let new_v1 = try aux {cond with exp = exp1} state