Skip to content

Commit c1b7284

Browse files
Add amenable_to_meet and test for it
1 parent 7186571 commit c1b7284

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

src/cdomain/value/cdomains/addressDomain.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ struct
110110
| StrPtr _, UnknownPtr -> None
111111
| _, _ -> Some false
112112

113+
let amenable_to_meet x y = match x,y with
114+
| StrPtr _, StrPtr _ -> true
115+
| _ -> false
116+
113117
let leq x y = match x, y with
114118
| StrPtr s1, StrPtr s2 -> SD.leq s1 s2
115119
| Addr x, Addr y -> Mval.leq x y
@@ -178,6 +182,7 @@ struct
178182
struct
179183
include SetDomain.Joined (Addr)
180184
let may_be_equal a b = Option.value (Addr.semantic_equal a b) ~default:true
185+
let amenable_to_meet = Addr.amenable_to_meet
181186
end
182187
module OffsetSplit = DisjointDomain.ProjectiveSetPairwiseMeet (Addr) (J) (Addr.UnitOffsetRepr)
183188

src/cdomain/value/cdomains/addressDomain_intf.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,11 @@ sig
8080

8181
val semantic_equal: t -> t -> bool option
8282
(** Check semantic equality of two addresses.
83-
8483
@return [Some true] if definitely equal, [Some false] if definitely not equal, [None] if unknown. *)
84+
85+
val amenable_to_meet: t -> t -> bool
86+
(** Whether two addresses are amenable to meet operation, i.e., their lattice meet overapproximates the intersection
87+
of concretizations. If true, meet is used instead of semantic_equal *)
8588
end
8689

8790
(** Address lattice with sublattice representatives for {!DisjointDomain}. *)

src/domain/disjointDomain.ml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,26 @@ module type MayEqualSetDomain =
182182
sig
183183
include SetDomain.S
184184
val may_be_equal: elt -> elt -> bool
185+
val amenable_to_meet: elt -> elt -> bool
185186
end
186187

187-
module ProjectiveSetPairwiseMeet (E: Printable.S) (B: MayEqualSetDomain with type elt = E.t) (R: Representative with type elt = E.t): SetDomain.S with type elt = E.t = struct
188+
module ProjectiveSetPairwiseMeet (E: Lattice.S) (B: MayEqualSetDomain with type elt = E.t) (R: Representative with type elt = E.t): SetDomain.S with type elt = E.t = struct
188189
include ProjectiveSet (E) (B) (R)
189190

190191
let meet m1 m2 =
191192
let meet_buckets b1 b2 acc =
192193
B.fold (fun e1 acc ->
193194
B.fold (fun e2 acc ->
194-
if B.may_be_equal e1 e2 then
195+
if B.amenable_to_meet e1 e2 then
196+
try
197+
let m = E.meet e1 e2 in
198+
if not (E.is_bot m) then
199+
add m acc
200+
else
201+
acc
202+
with Lattice.Uncomparable ->
203+
failwith (GobPretty.sprintf "amenable_to_meet %a %a returned true, but meet throws!" E.pretty e1 E.pretty e2)
204+
else if B.may_be_equal e1 e2 then
195205
add e1 (add e2 acc)
196206
else
197207
acc
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// PARAM: --set ana.base.privatization write
2+
#include<pthread.h>
3+
struct a {
4+
char* b;
5+
};
6+
7+
struct a *c;
8+
struct a h = {""};
9+
struct a i = {"string"};
10+
11+
void* d(void* args) {
12+
struct a r;
13+
if (c->b) {
14+
__goblint_check(strlen(h.b) == 0); // Should also work for write!
15+
}
16+
}
17+
18+
int main() {
19+
int top;
20+
21+
if(top) {
22+
c = &h;
23+
} else {
24+
c = &i;
25+
}
26+
27+
pthread_t t;
28+
pthread_create(&t, 0, d, 0);
29+
return 0;
30+
}

0 commit comments

Comments
 (0)