Skip to content

Commit c44a591

Browse files
Merge pull request #1644 from goblint/issue_1558_master
Make `update_offset` idempotent for blobs
2 parents ab54be8 + f85f8a3 commit c44a591

File tree

2 files changed

+52
-21
lines changed

2 files changed

+52
-21
lines changed

src/cdomain/value/cdomains/valueDomain.ml

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,28 +1001,31 @@ struct
10011001
else
10021002
mu (Blob (join x (do_update_offset ask x offs value exp l' o' v t), s, zeroinit))
10031003
end
1004-
| Blob (x,s,zeroinit), _ ->
1004+
| Blob (x,s,zeroinit), `NoOffset -> (* `NoOffset is only remaining possibility for Blob here *)
10051005
begin
1006-
let l', o' = shift_one_over l o in
1007-
let x = zero_init_calloced_memory zeroinit x t in
1008-
(* Strong update of scalar variable is possible if the variable is unique and size of written value matches size of blob being written to. *)
1009-
let do_strong_update =
1010-
begin match v with
1011-
| (Var var, _) ->
1012-
let blob_size_opt = ID.to_int s in
1013-
not @@ ask.is_multiple var
1014-
&& GobOption.exists (fun blob_size -> (* Size of blob is known *)
1015-
(not @@ Cil.isVoidType t (* Size of value is known *)
1016-
&& Z.equal blob_size (Z.of_int @@ Cil.alignOf_int t))
1017-
|| blob_destructive
1018-
) blob_size_opt
1019-
| _ -> false
1020-
end
1021-
in
1022-
if do_strong_update then
1023-
Blob ((do_update_offset ask x offs value exp l' o' v t), s, zeroinit)
1024-
else
1025-
mu (Blob (join x (do_update_offset ask x offs value exp l' o' v t), s, zeroinit))
1006+
match value with
1007+
| Blob (x2, s2, zeroinit2) -> mu (Blob (join x x2, ID.join s s2, zeroinit))
1008+
| _ ->
1009+
let l', o' = shift_one_over l o in
1010+
let x = zero_init_calloced_memory zeroinit x t in
1011+
(* Strong update of scalar variable is possible if the variable is unique and size of written value matches size of blob being written to. *)
1012+
let do_strong_update =
1013+
begin match v with
1014+
| (Var var, _) ->
1015+
let blob_size_opt = ID.to_int s in
1016+
not @@ ask.is_multiple var
1017+
&& GobOption.exists (fun blob_size -> (* Size of blob is known *)
1018+
(not @@ Cil.isVoidType t (* Size of value is known *)
1019+
&& Z.equal blob_size (Z.of_int @@ Cil.alignOf_int t))
1020+
|| blob_destructive
1021+
) blob_size_opt
1022+
| _ -> false
1023+
end
1024+
in
1025+
if do_strong_update then
1026+
Blob ((do_update_offset ask x offs value exp l' o' v t), s, zeroinit)
1027+
else
1028+
mu (Blob (join x (do_update_offset ask x offs value exp l' o' v t), s, zeroinit))
10261029
end
10271030
| Thread _, _ ->
10281031
(* hack for pthread_t variables *)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// PARAM: --set ana.base.privatization mutex-meet
2+
#include<pthread.h>
3+
#include<stdlib.h>
4+
#include<stdio.h>
5+
struct a {
6+
void (*b)();
7+
};
8+
9+
int g = 0;
10+
11+
struct a* t;
12+
void m() {
13+
// Reachable!
14+
g = 1;
15+
}
16+
17+
void* j(void* arg) {};
18+
19+
void main() {
20+
pthread_t tid;
21+
pthread_create(&tid, 0, j, NULL);
22+
t = calloc(1, sizeof(struct a));
23+
t->b = &m;
24+
struct a r = *t;
25+
r.b();
26+
27+
__goblint_check(g ==0); //UNKNOWN!
28+
}

0 commit comments

Comments
 (0)