Skip to content

Commit ccb13c1

Browse files
Merge pull request #21 from ManuelLerchner/invariant
Invariant
2 parents 8d7faf9 + e2568fd commit ccb13c1

File tree

5 files changed

+266
-22
lines changed

5 files changed

+266
-22
lines changed

src/analyses/baseInvariant.ml

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -395,27 +395,55 @@ struct
395395
| Le, Some false -> meet_bin (ID.starting ikind (Z.succ l2)) (ID.ending ikind (Z.pred u1))
396396
| _, _ -> a, b)
397397
| _ -> a, b)
398-
| BOr | BXor as op->
399-
if M.tracing then M.tracel "inv" "Unhandled operator %a" d_binop op;
398+
| BOr ->
400399
(* Be careful: inv_exp performs a meet on both arguments of the BOr / BXor. *)
401-
a, b
400+
if PrecisionUtil.get_bitfield () then
401+
let a', b' = ID.meet a (ID.logand a c), ID.meet b (ID.logand b c) in
402+
let (cz, co) = ID.to_bitfield ikind c in
403+
let (az, ao) = ID.to_bitfield ikind a' in
404+
let (bz, bo) = ID.to_bitfield ikind b' in
405+
let cDef1 = Z.logand co (Z.lognot cz) in
406+
let aDef0 = Z.logand az (Z.lognot ao) in
407+
let bDef0 = Z.logand bz (Z.lognot bo) in
408+
let az = Z.logand az (Z.lognot (Z.logand bDef0 cDef1)) in
409+
let bz = Z.logand bz (Z.lognot (Z.logand aDef0 cDef1)) in
410+
ID.meet a' (ID.of_bitfield ikind (az, ao)), ID.meet b' (ID.of_bitfield ikind (bz, bo))
411+
else a, b
412+
| BXor ->
413+
(* Be careful: inv_exp performs a meet on both arguments of the BOr / BXor. *)
414+
if PrecisionUtil.get_bitfield () then
415+
let a' = ID.meet a (ID.logxor c b)
416+
in let b' = ID.meet b (ID.logxor a c)
417+
in a', b'
418+
else a,b
402419
| LAnd ->
403420
if ID.to_bool c = Some true then
404421
meet_bin c c
405422
else
406423
a, b
407-
| BAnd as op ->
424+
| BAnd ->
408425
(* we only attempt to refine a here *)
409426
let a =
410427
match ID.to_int b with
411428
| Some x when Z.equal x Z.one ->
412429
(match ID.to_bool c with
413430
| Some true -> ID.meet a (ID.of_congruence ikind (Z.one, Z.of_int 2))
414431
| Some false -> ID.meet a (ID.of_congruence ikind (Z.zero, Z.of_int 2))
415-
| None -> if M.tracing then M.tracel "inv" "Unhandled case for operator x %a 1 = %a" d_binop op ID.pretty c; a)
416-
| _ -> if M.tracing then M.tracel "inv" "Unhandled case for operator x %a %a = %a" d_binop op ID.pretty b ID.pretty c; a
432+
| None -> a)
433+
| _ -> a
417434
in
418-
a, b
435+
if PrecisionUtil.get_bitfield () then
436+
let a', b' = ID.meet a (ID.logor a c), ID.meet b (ID.logor b c) in
437+
let (cz, co) = ID.to_bitfield ikind c in
438+
let (az, ao) = ID.to_bitfield ikind a' in
439+
let (bz, bo) = ID.to_bitfield ikind b' in
440+
let cDef0 = Z.logand cz (Z.lognot co) in
441+
let aDef1 = Z.logand ao (Z.lognot az) in
442+
let bDef1 = Z.logand bo (Z.lognot bz) in
443+
let ao = Z.logand ao (Z.lognot (Z.logand bDef1 cDef0)) in
444+
let bo = Z.logand bo (Z.lognot (Z.logand aDef1 cDef0)) in
445+
ID.meet a' (ID.of_bitfield ikind (az, ao)), ID.meet b' (ID.of_bitfield ikind (bz, bo))
446+
else a, b
419447
| op ->
420448
if M.tracing then M.tracel "inv" "Unhandled operator %a" d_binop op;
421449
a, b

0 commit comments

Comments
 (0)