Skip to content

Commit 206f204

Browse files
authored
Merge pull request #495 from goblint/escape-unknown
Fix known addresses not escaping when address set contains unknown
2 parents ed16687 + bb3e8eb commit 206f204

File tree

5 files changed

+42
-9
lines changed

5 files changed

+42
-9
lines changed

src/analyses/base.ml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -985,12 +985,14 @@ struct
985985
match eval_rv_address (Analyses.ask_of_ctx ctx) ctx.global ctx.local e with
986986
| `Top -> Queries.Result.top q
987987
| `Bot -> Queries.Result.bot q (* TODO: remove *)
988-
| `Address a when AD.is_top a || AD.mem Addr.UnknownPtr a ->
989-
Q.LS.top ()
990988
| `Address a ->
991-
let xs = List.map addrToLvalSet (reachable_vars (Analyses.ask_of_ctx ctx) [a] ctx.global ctx.local) in
989+
let a' = AD.remove Addr.UnknownPtr a in (* run reachable_vars without unknown just to be safe *)
990+
let xs = List.map addrToLvalSet (reachable_vars (Analyses.ask_of_ctx ctx) [a'] ctx.global ctx.local) in
992991
let addrs = List.fold_left (Q.LS.join) (Q.LS.empty ()) xs in
993-
addrs
992+
if AD.mem Addr.UnknownPtr a then
993+
Q.LS.add (dummyFunDec.svar, `NoOffset) addrs (* add unknown back *)
994+
else
995+
addrs
994996
| _ -> Q.LS.empty ()
995997
end
996998
| Q.ReachableUkTypes e -> begin

src/analyses/malloc_null.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ struct
108108
match ask.f (Queries.ReachableFrom e) with
109109
| a when not (Queries.LS.is_top a) ->
110110
let to_extra (v,o) xs = AD.from_var_offset (v,(conv_offset o)) :: xs in
111-
Queries.LS.fold to_extra a []
111+
Queries.LS.fold to_extra (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) []
112112
(* Ignore soundness warnings, as invalidation proper will raise them. *)
113113
| _ -> []
114114
in

src/analyses/threadEscape.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ struct
6060
| a when not (Queries.LS.is_top a) ->
6161
(* let to_extra (v,o) set = D.add (Addr.from_var_offset (v, cut_offset o)) set in *)
6262
let to_extra (v,o) set = D.add v set in
63-
Queries.LS.fold to_extra a (D.empty ())
63+
Queries.LS.fold to_extra (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) (D.empty ())
6464
(* Ignore soundness warnings, as invalidation proper will raise them. *)
65-
| _ -> D.empty ()
65+
| a ->
66+
if M.tracing then M.tracel "escape" "reachable %a: %a\n" d_exp e Queries.LS.pretty a;
67+
D.empty ()
6668

6769
let special ctx (lval: lval option) (f:varinfo) (arglist:exp list) : D.t =
6870
ctx.local
@@ -84,6 +86,7 @@ struct
8486
match args with
8587
| [ptc_arg] ->
8688
let escaped = fctx.local in (* reuse reachable computation from threadenter *)
89+
if M.tracing then M.tracel "escape" "%a: %a\n" d_exp ptc_arg D.pretty escaped;
8790
if not (D.is_empty escaped) then (* avoid emitting unnecessary event *)
8891
ctx.emit (Events.Escape escaped);
8992
escaped

src/analyses/uninit.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ struct
8989
match ask (Queries.ReachableFrom e) with
9090
| a when not (Queries.LS.is_top a) ->
9191
let to_extra (v,o) xs = (v, Base.Offs.from_offset (conv_offset o), true) :: xs in
92-
Queries.LS.fold to_extra a []
92+
Queries.LS.fold to_extra (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) []
9393
(* Ignore soundness warnings, as invalidation proper will raise them. *)
9494
| _ -> []
9595
in
@@ -227,7 +227,7 @@ struct
227227
match ask.f (Queries.ReachableFrom e) with
228228
| a when not (Queries.LS.is_top a) ->
229229
let to_extra (v,o) xs = AD.from_var_offset (v,(conv_offset o)) :: xs in
230-
Queries.LS.fold to_extra a []
230+
Queries.LS.fold to_extra (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) []
231231
(* Ignore soundness warnings, as invalidation proper will raise them. *)
232232
| _ -> []
233233
in
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <pthread.h>
2+
#include <assert.h>
3+
4+
int *p;
5+
6+
void *t_fun(void *arg) {
7+
if (arg != NULL) {
8+
*((int*)arg) = 42;
9+
}
10+
return NULL;
11+
}
12+
13+
int main() {
14+
pthread_t id, id2;
15+
int *r; // unknown
16+
int i = 5;
17+
18+
pthread_create(&id, NULL, t_fun, NULL); // enter multithreaded
19+
20+
p = r;
21+
p = &i;
22+
23+
pthread_create(&id2, NULL, t_fun, p); // i should escape, even if p contains unknown
24+
25+
assert(i == 5); // UNKNOWN!
26+
27+
return 0;
28+
}

0 commit comments

Comments
 (0)