Skip to content

Commit bacedc7

Browse files
authored
Merge pull request #1323 from goblint/threadEscape-combine_assign
Implement `combine_assign` in `threadEscape`
2 parents 0af26b4 + 34d30fe commit bacedc7

File tree

5 files changed

+50
-18
lines changed

5 files changed

+50
-18
lines changed

src/analyses/base.ml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ open Pretty
66
open Analyses
77
open GobConfig
88
open BaseUtil
9+
open ReturnUtil
910
module A = Analyses
1011
module H = Hashtbl
1112
module Q = Queries
@@ -143,13 +144,6 @@ struct
143144
* Initializing my variables
144145
**************************************************************************)
145146

146-
let return_varstore = ref dummyFunDec.svar
147-
let return_varinfo () = !return_varstore
148-
let return_var () = AD.of_var (return_varinfo ())
149-
let return_lval (): lval = (Var (return_varinfo ()), NoOffset)
150-
151-
let longjmp_return = ref dummyFunDec.svar
152-
153147
let heap_var on_stack ctx =
154148
let info = match (ctx.ask (Q.AllocVar {on_stack})) with
155149
| `Lifted vinfo -> vinfo
@@ -2930,8 +2924,6 @@ end
29302924
module type MainSpec = sig
29312925
include MCPSpec
29322926
include BaseDomain.ExpEvaluator
2933-
val return_lval: unit -> Cil.lval
2934-
val return_varinfo: unit -> Cil.varinfo
29352927
end
29362928

29372929
let main_module: (module MainSpec) Lazy.t =

src/analyses/region.ml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ struct
109109
let old_regpart = ctx.global () in
110110
let regpart, reg = match exp with
111111
| Some exp ->
112-
let module BS = (val Base.get_main ()) in
113-
Reg.assign (BS.return_lval ()) exp (old_regpart, reg)
112+
Reg.assign (ReturnUtil.return_lval ()) exp (old_regpart, reg)
114113
| None -> (old_regpart, reg)
115114
in
116115
let regpart, reg = Reg.kill_vars locals (Reg.remove_vars locals (regpart, reg)) in
@@ -143,12 +142,11 @@ struct
143142
match au with
144143
| `Lifted reg -> begin
145144
let old_regpart = ctx.global () in
146-
let module BS = (val Base.get_main ()) in
147145
let regpart, reg = match lval with
148146
| None -> (old_regpart, reg)
149-
| Some lval -> Reg.assign lval (AddrOf (BS.return_lval ())) (old_regpart, reg)
147+
| Some lval -> Reg.assign lval (AddrOf (ReturnUtil.return_lval ())) (old_regpart, reg)
150148
in
151-
let regpart, reg = Reg.remove_vars [BS.return_varinfo ()] (regpart, reg) in
149+
let regpart, reg = Reg.remove_vars [ReturnUtil.return_varinfo ()] (regpart, reg) in
152150
if not (RegPart.leq regpart old_regpart) then
153151
ctx.sideg () regpart;
154152
`Lifted reg

src/analyses/threadEscape.ml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ struct
117117
end
118118
| _ -> Queries.Result.top q
119119

120-
let escape_rval ctx (rval:exp) =
121-
let ask = Analyses.ask_of_ctx ctx in
120+
let escape_rval ctx ask (rval:exp) =
122121
let escaped = reachable ask rval in
123122
let escaped = D.filter (fun v -> not v.vglob) escaped in
124123

@@ -133,17 +132,26 @@ struct
133132
let ask = Analyses.ask_of_ctx ctx in
134133
let vs = mpt ask (AddrOf lval) in
135134
if D.exists (fun v -> v.vglob || has_escaped ask v) vs then (
136-
let escaped = escape_rval ctx rval in
135+
let escaped = escape_rval ctx ask rval in
137136
D.join ctx.local escaped
138137
) else begin
139138
ctx.local
140139
end
141140

141+
let combine_assign ctx (lval:lval option) (fexp:exp) f args fc au f_ask : D.t =
142+
let ask = Analyses.ask_of_ctx ctx in
143+
match lval with
144+
| Some lval when D.exists (fun v -> v.vglob || has_escaped ask v) (mpt ask (AddrOf lval)) ->
145+
let rval = Lval (ReturnUtil.return_lval ()) in
146+
let escaped = escape_rval ctx f_ask rval in (* Using f_ask because the return value is only accessible in the context of that function at this point *)
147+
D.join ctx.local escaped
148+
| _ -> ctx.local
149+
142150
let special ctx (lval: lval option) (f:varinfo) (args:exp list) : D.t =
143151
let desc = LibraryFunctions.find f in
144152
match desc.special args, f.vname, args with
145153
| _, "pthread_setspecific" , [key; pt_value] ->
146-
let escaped = escape_rval ctx pt_value in
154+
let escaped = escape_rval ctx (Analyses.ask_of_ctx ctx) pt_value in
147155
D.join ctx.local escaped
148156
| _ -> ctx.local
149157

src/util/returnUtil.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
open GoblintCil
2+
module AD = ValueDomain.AD
3+
4+
let return_varstore = ref dummyFunDec.svar
5+
let return_varinfo () = !return_varstore
6+
let return_var () = AD.of_var (return_varinfo ())
7+
let return_lval (): lval = (Var (return_varinfo ()), NoOffset)
8+
9+
let longjmp_return = ref dummyFunDec.svar
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <pthread.h>
2+
#include <goblint.h>
3+
4+
int* gptr;
5+
6+
void *foo(void* p){
7+
*gptr = 17;
8+
return NULL;
9+
}
10+
11+
int* id(int* x) {
12+
return x;
13+
}
14+
15+
int main(){
16+
int x = 0;
17+
gptr = id(&x);
18+
__goblint_check(x==0);
19+
pthread_t thread;
20+
pthread_create(&thread, NULL, foo, NULL);
21+
sleep(3);
22+
__goblint_check(x == 0); // UNKNOWN!
23+
pthread_join(thread, NULL);
24+
return 0;
25+
}

0 commit comments

Comments
 (0)