Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -985,12 +985,14 @@ struct
match eval_rv_address (Analyses.ask_of_ctx ctx) ctx.global ctx.local e with
| `Top -> Queries.Result.top q
| `Bot -> Queries.Result.bot q (* TODO: remove *)
| `Address a when AD.is_top a || AD.mem Addr.UnknownPtr a ->
Q.LS.top ()
| `Address a ->
let xs = List.map addrToLvalSet (reachable_vars (Analyses.ask_of_ctx ctx) [a] ctx.global ctx.local) in
let a' = AD.remove Addr.UnknownPtr a in (* run reachable_vars without unknown just to be safe *)
let xs = List.map addrToLvalSet (reachable_vars (Analyses.ask_of_ctx ctx) [a'] ctx.global ctx.local) in
let addrs = List.fold_left (Q.LS.join) (Q.LS.empty ()) xs in
addrs
if AD.mem Addr.UnknownPtr a then
Q.LS.add (dummyFunDec.svar, `NoOffset) addrs (* add unknown back *)
else
addrs
| _ -> Q.LS.empty ()
end
| Q.ReachableUkTypes e -> begin
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/malloc_null.ml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct
match ask.f (Queries.ReachableFrom e) with
| a when not (Queries.LS.is_top a) ->
let to_extra (v,o) xs = AD.from_var_offset (v,(conv_offset o)) :: xs in
Queries.LS.fold to_extra a []
Queries.LS.fold to_extra (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) []
(* Ignore soundness warnings, as invalidation proper will raise them. *)
| _ -> []
in
Expand Down
7 changes: 5 additions & 2 deletions src/analyses/threadEscape.ml
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ struct
| a when not (Queries.LS.is_top a) ->
(* let to_extra (v,o) set = D.add (Addr.from_var_offset (v, cut_offset o)) set in *)
let to_extra (v,o) set = D.add v set in
Queries.LS.fold to_extra a (D.empty ())
Queries.LS.fold to_extra (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) (D.empty ())
(* Ignore soundness warnings, as invalidation proper will raise them. *)
| _ -> D.empty ()
| a ->
if M.tracing then M.tracel "escape" "reachable %a: %a\n" d_exp e Queries.LS.pretty a;
D.empty ()

let special ctx (lval: lval option) (f:varinfo) (arglist:exp list) : D.t =
ctx.local
Expand All @@ -84,6 +86,7 @@ struct
match args with
| [ptc_arg] ->
let escaped = fctx.local in (* reuse reachable computation from threadenter *)
if M.tracing then M.tracel "escape" "%a: %a\n" d_exp ptc_arg D.pretty escaped;
if not (D.is_empty escaped) then (* avoid emitting unnecessary event *)
ctx.emit (Events.Escape escaped);
escaped
Expand Down
4 changes: 2 additions & 2 deletions src/analyses/uninit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ struct
match ask (Queries.ReachableFrom e) with
| a when not (Queries.LS.is_top a) ->
let to_extra (v,o) xs = (v, Base.Offs.from_offset (conv_offset o), true) :: xs in
Queries.LS.fold to_extra a []
Queries.LS.fold to_extra (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) []
(* Ignore soundness warnings, as invalidation proper will raise them. *)
| _ -> []
in
Expand Down Expand Up @@ -227,7 +227,7 @@ struct
match ask.f (Queries.ReachableFrom e) with
| a when not (Queries.LS.is_top a) ->
let to_extra (v,o) xs = AD.from_var_offset (v,(conv_offset o)) :: xs in
Queries.LS.fold to_extra a []
Queries.LS.fold to_extra (Queries.LS.remove (dummyFunDec.svar, `NoOffset) a) []
(* Ignore soundness warnings, as invalidation proper will raise them. *)
| _ -> []
in
Expand Down
28 changes: 28 additions & 0 deletions tests/regression/02-base/70-escape-unknown.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <pthread.h>
#include <assert.h>

int *p;

void *t_fun(void *arg) {
if (arg != NULL) {
*((int*)arg) = 42;
}
return NULL;
}

int main() {
pthread_t id, id2;
int *r; // unknown
int i = 5;

pthread_create(&id, NULL, t_fun, NULL); // enter multithreaded

p = r;
p = &i;

pthread_create(&id2, NULL, t_fun, p); // i should escape, even if p contains unknown

assert(i == 5); // UNKNOWN!

return 0;
}