Skip to content

Commit 2879ebd

Browse files
authored
Merge pull request #1814 from goblint/bitfield-cast-bool
Fix bitfield `_Bool` casts
2 parents 267845c + f485e14 commit 2879ebd

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/cdomain/value/cdomains/int/bitfieldDomain.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,25 @@ module BitfieldFunctor (Ints_t : IntOps.IntOps): Bitfield_SOverflow with type in
281281
let overflow_info = if suppress_ovwarn then {underflow=false; overflow=false} else {underflow=underflow; overflow=overflow} in
282282
(norm ~suppress_ovwarn:(suppress_ovwarn) ~ov:(underflow || overflow) ik (z,o), overflow_info)
283283

284+
let cast_to ?(suppress_ovwarn=false) ?torg ?(no_ov=false) ik (z,o) =
285+
if ik = GoblintCil.IBool then (
286+
let may_zero =
287+
if Ints_t.equal z BArith.one_mask then (* zero bit may be in every position (one_mask) *)
288+
BArith.zero
289+
else
290+
bot () (* must be non-zero, so may not be zero *)
291+
in
292+
let may_one =
293+
if Ints_t.equal o BArith.zero_mask then (* one bit may be in no position (zero_mask) *)
294+
bot () (* must be zero, so may not be one *)
295+
else
296+
BArith.one
297+
in
298+
(BArith.join may_zero may_one, {underflow=false; overflow=false})
299+
)
300+
else
301+
cast_to ~suppress_ovwarn ?torg ~no_ov ik (z,o)
302+
284303
let join ik b1 b2 = norm ik @@ (BArith.join b1 b2)
285304

286305
let meet ik x y = norm ik @@ (BArith.meet x y)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// PARAM: --disable ana.int.def_exc --enable ana.int.bitfield
2+
#include <goblint.h>
3+
4+
int main() {
5+
int i1 = 1;
6+
int i123 = 123;
7+
int im123 = -123;
8+
int i128 = 128;
9+
int im128 = -128;
10+
int i0 = 0;
11+
int irand; // rand
12+
13+
// assigning constant from other variable instead of integer constant, because integer constant swallows implicit cast to _Bool
14+
_Bool b1 = i1;
15+
_Bool b123 = i123; // NOWARN (overflow)
16+
_Bool bm123 = im123; // NOWARN (underflow)
17+
_Bool b128 = i128; // NOWARN (overflow)
18+
_Bool bm128 = im128; // NOWARN (underflow)
19+
_Bool bf = i0;
20+
_Bool brand = irand; // NOWARN (underflow, overflow)
21+
22+
__goblint_check(b1);
23+
__goblint_check(b1 == 1);
24+
__goblint_check(b123);
25+
__goblint_check(b123 == 1);
26+
__goblint_check(bm123);
27+
__goblint_check(bm123 == 1);
28+
__goblint_check(b128);
29+
__goblint_check(b128 == 1);
30+
__goblint_check(bm128);
31+
__goblint_check(bm128 == 1);
32+
__goblint_check(!bf);
33+
__goblint_check(bf == 0);
34+
__goblint_check(brand); // UNKNOWN!
35+
__goblint_check(brand == 0); // UNKNOWN!
36+
__goblint_check(brand == 1); // UNKNOWN!
37+
return 0;
38+
}

0 commit comments

Comments
 (0)