Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make meet in AddressDomain more precise #1468

Merged
merged 9 commits into from
Jan 17, 2025
2 changes: 1 addition & 1 deletion src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1613,7 +1613,7 @@ struct
let set ~(ctx: _ ctx) ?(invariant=false) ?(blob_destructive=false) ?lval_raw ?rval_raw ?t_override (st: store) (lval: AD.t) (lval_type: Cil.typ) (value: value) : store =
let update_variable x t y z =
if M.tracing then M.tracel "set" ~var:x.vname "update_variable: start '%s' '%a'\nto\n%a" x.vname VD.pretty y CPA.pretty z;
let r = update_variable x t y z in (* refers to defintion that is outside of set *)
let r = update_variable x t y z in (* refers to definition that is outside of set *)
if M.tracing then M.tracel "set" ~var:x.vname "update_variable: start '%s' '%a'\nto\n%a\nresults in\n%a" x.vname VD.pretty y CPA.pretty z CPA.pretty r;
r
in
Expand Down
14 changes: 12 additions & 2 deletions src/domain/disjointDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -184,14 +184,24 @@ sig
val may_be_equal: elt -> elt -> bool
end

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
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
include ProjectiveSet (E) (B) (R)

let meet m1 m2 =
let meet_buckets b1 b2 acc =
B.fold (fun e1 acc ->
B.fold (fun e2 acc ->
if B.may_be_equal e1 e2 then
(* If they have the same representative, we use the normal meet within this bucket *)
if R.equal (R.of_elt e1) (R.of_elt e2) then
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
try
let m = E.meet e1 e2 in
if not (E.is_bot m) then
add m acc
else
acc
with Lattice.Uncomparable ->
failwith (GobPretty.sprintf "Elements %a and %a are in same bucket, but meet throws!" E.pretty e1 E.pretty e2)
sim642 marked this conversation as resolved.
Show resolved Hide resolved
else if B.may_be_equal e1 e2 then
add e1 (add e2 acc)
else
acc
Expand Down
30 changes: 30 additions & 0 deletions tests/regression/13-privatized/89-write-lacking-precision.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// PARAM: --set ana.base.privatization write
#include<pthread.h>
struct a {
char* b;
};

struct a *c;
struct a h = {""};
struct a i = {"string"};

void* d(void* args) {
struct a r;
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
if (c->b) {
__goblint_check(strlen(h.b) == 0); // Should also work for write!
sim642 marked this conversation as resolved.
Show resolved Hide resolved
}
}

int main() {
int top;

if(top) {
c = &h;
} else {
c = &i;
}

pthread_t t;
pthread_create(&t, 0, d, 0);
return 0;
}
51 changes: 51 additions & 0 deletions tests/regression/27-inv_invariants/23-meet-ptrs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//PARAM: --enable ana.int.interval
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int more_intricate() {
int arr[20];

int top;

int i = 2;
int j = 8;
if(top) {
i = 8;
j = 9;
}

int* imprecise1 = &arr[i]; // &arr[2..8]
int* imprecise2 = &arr[j]; // &arr[8..9]

if(imprecise1 == imprecise2) {
__goblint_check(imprecise1 == &arr[8]);
__goblint_check(imprecise2 == &arr[8]); //TODO (Refinement should happen in both directions!)
}

if(imprecise1 == &arr[j]) {
__goblint_check(imprecise1 == &arr[8]);
}

}


int main() {
int arr[20];

int top;

int i = 2;
if(top) {
i = 8;
}

int* imprecise = &arr[i];

if(imprecise == &arr[2]) {
__goblint_check(imprecise == &arr[2]);
}

more_intricate();
return 0;
}
Loading