Skip to content

Commit

Permalink
Merge pull request #1559 from goblint/issue_1558
Browse files Browse the repository at this point in the history
Make `update_offset` idempotent for blobs
  • Loading branch information
michael-schwarz authored Aug 9, 2024
2 parents 0d7ce37 + 3878a22 commit ccca4b2
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 20 deletions.
43 changes: 23 additions & 20 deletions src/cdomain/value/cdomains/valueDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -982,26 +982,29 @@ struct
end
| Blob (x,s,orig), _ ->
begin
let l', o' = shift_one_over l o in
let x = zero_init_calloced_memory orig x t in
(* Strong update of scalar variable is possible if the variable is unique and size of written value matches size of blob being written to. *)
let do_strong_update =
begin match v with
| (Var var, _) ->
let blob_size_opt = ID.to_int s in
not @@ ask.is_multiple var
&& Option.is_some blob_size_opt (* Size of blob is known *)
&& ((
not @@ Cil.isVoidType t (* Size of value is known *)
&& Z.equal (Option.get blob_size_opt) (Z.of_int @@ Cil.alignOf_int t)
) || blob_destructive)
| _ -> false
end
in
if do_strong_update then
Blob ((do_update_offset ask x offs value exp l' o' v t), s, orig)
else
mu (Blob (join x (do_update_offset ask x offs value exp l' o' v t), s, orig))
match offs, value with
| `NoOffset, Blob (x2, s2, orig2) -> mu (Blob (join x x2, ID.join s s2,ZeroInit.join orig orig2))
| _ ->
let l', o' = shift_one_over l o in
let x = zero_init_calloced_memory orig x t in
(* Strong update of scalar variable is possible if the variable is unique and size of written value matches size of blob being written to. *)
let do_strong_update =
begin match v with
| (Var var, _) ->
let blob_size_opt = ID.to_int s in
not @@ ask.is_multiple var
&& Option.is_some blob_size_opt (* Size of blob is known *)
&& ((
not @@ Cil.isVoidType t (* Size of value is known *)
&& Z.equal (Option.get blob_size_opt) (Z.of_int @@ Cil.alignOf_int t)
) || blob_destructive)
| _ -> false
end
in
if do_strong_update then
Blob ((do_update_offset ask x offs value exp l' o' v t), s, orig)
else
mu (Blob (join x (do_update_offset ask x offs value exp l' o' v t), s, orig))
end
| Thread _, _ ->
(* hack for pthread_t variables *)
Expand Down
28 changes: 28 additions & 0 deletions tests/regression/13-privatized/95-mm-calloc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// PARAM: --set ana.base.privatization mutex-meet
#include<pthread.h>
#include<stdlib.h>
#include<stdio.h>
struct a {
void (*b)();
};

int g = 0;

struct a* t;
void m() {
// Reachable!
g = 1;
}

void* j(void* arg) {};

void main() {
pthread_t tid;
pthread_create(&tid, 0, j, NULL);
t = calloc(1, sizeof(struct a));
t->b = &m;
struct a r = *t;
r.b();

__goblint_check(g ==0); //UNKNOWN!
}

0 comments on commit ccca4b2

Please sign in to comment.