Skip to content

Commit 563a5b1

Browse files
Support for threadenter for unknown function
1 parent 406ad22 commit 563a5b1

File tree

1 file changed

+38
-34
lines changed

1 file changed

+38
-34
lines changed

src/analyses/apron/relationAnalysis.apron.ml

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,36 @@ struct
512512
if RD.is_bot_env res then raise Deadcode;
513513
{st with rel = res}
514514

515+
516+
let special_unknown_invalidate ctx f args =
517+
(* No warning here, base already prodcues the appropriate warnings *)
518+
let desc = LibraryFunctions.find f in
519+
let shallow_addrs = LibraryDesc.Accesses.find desc.accs { kind = Write; deep = false } args in
520+
let deep_addrs = LibraryDesc.Accesses.find desc.accs { kind = Write; deep = true } args in
521+
let deep_addrs =
522+
if List.mem LibraryDesc.InvalidateGlobals desc.attrs then (
523+
foldGlobals !Cilfacade.current_file (fun acc global ->
524+
match global with
525+
| GVar (vi, _, _) when not (BaseUtil.is_static vi) ->
526+
mkAddrOf (Var vi, NoOffset) :: acc
527+
(* TODO: what about GVarDecl? *)
528+
| _ -> acc
529+
) deep_addrs
530+
)
531+
else
532+
deep_addrs
533+
in
534+
let lvallist e =
535+
match ctx.ask (Queries.MayPointTo e) with
536+
| ad when Queries.AD.is_top ad -> []
537+
| ad ->
538+
Queries.AD.to_mval ad
539+
|> List.map ValueDomain.Addr.Mval.to_cil
540+
in
541+
let st' = forget_reachable ctx ctx.local deep_addrs in
542+
let shallow_lvals = List.concat_map lvallist shallow_addrs in
543+
List.fold_left (invalidate_one (Analyses.ask_of_ctx ctx) ctx) st' shallow_lvals
544+
515545
let special ctx r f args =
516546
let ask = Analyses.ask_of_ctx ctx in
517547
let st = ctx.local in
@@ -547,31 +577,7 @@ struct
547577
assert_fn {ctx with local = st} (BinOp (Ge, Lval lv, zero, intType)) true
548578
| None -> st)
549579
| _, _ ->
550-
let lvallist e =
551-
match ask.f (Queries.MayPointTo e) with
552-
| ad when Queries.AD.is_top ad -> []
553-
| ad ->
554-
Queries.AD.to_mval ad
555-
|> List.map ValueDomain.Addr.Mval.to_cil
556-
in
557-
let shallow_addrs = LibraryDesc.Accesses.find desc.accs { kind = Write; deep = false } args in
558-
let deep_addrs = LibraryDesc.Accesses.find desc.accs { kind = Write; deep = true } args in
559-
let deep_addrs =
560-
if List.mem LibraryDesc.InvalidateGlobals desc.attrs then (
561-
foldGlobals !Cilfacade.current_file (fun acc global ->
562-
match global with
563-
| GVar (vi, _, _) when not (BaseUtil.is_static vi) ->
564-
mkAddrOf (Var vi, NoOffset) :: acc
565-
(* TODO: what about GVarDecl? *)
566-
| _ -> acc
567-
) deep_addrs
568-
)
569-
else
570-
deep_addrs
571-
in
572-
let st' = forget_reachable ctx st deep_addrs in
573-
let shallow_lvals = List.concat_map lvallist shallow_addrs in
574-
let st' = List.fold_left (invalidate_one ask ctx) st' shallow_lvals in
580+
let st' = special_unknown_invalidate ctx f args in
575581
(* invalidate lval if present *)
576582
match r with
577583
| Some lv -> invalidate_one ask ctx st' lv
@@ -673,21 +679,19 @@ struct
673679

674680
let threadenter ctx ~multiple lval f args =
675681
let st = ctx.local in
682+
(* TODO: HACK: Simulate enter_multithreaded for first entering thread to publish global inits before analyzing thread.
683+
Otherwise thread is analyzed with no global inits, reading globals gives bot, which turns into top, which might get published...
684+
sync `Thread doesn't help us here, it's not specific to entering multithreaded mode.
685+
EnterMultithreaded events only execute after threadenter and threadspawn. *)
686+
if not (ThreadFlag.has_ever_been_multi (Analyses.ask_of_ctx ctx)) then
687+
ignore (Priv.enter_multithreaded (Analyses.ask_of_ctx ctx) ctx.global ctx.sideg st);
676688
match Cilfacade.find_varinfo_fundec f with
677689
| fd ->
678-
(* TODO: HACK: Simulate enter_multithreaded for first entering thread to publish global inits before analyzing thread.
679-
Otherwise thread is analyzed with no global inits, reading globals gives bot, which turns into top, which might get published...
680-
sync `Thread doesn't help us here, it's not specific to entering multithreaded mode.
681-
EnterMultithreaded events only execute after threadenter and threadspawn. *)
682-
if not (ThreadFlag.has_ever_been_multi (Analyses.ask_of_ctx ctx)) then
683-
ignore (Priv.enter_multithreaded (Analyses.ask_of_ctx ctx) ctx.global ctx.sideg st);
684690
let st' = Priv.threadenter (Analyses.ask_of_ctx ctx) ctx.global st in
685691
let new_rel = make_callee_rel ~thread:true ctx fd args in
686692
[{st' with rel = new_rel}]
687693
| exception Not_found ->
688-
(* Unknown functions *)
689-
(* TODO: do something like base? *)
690-
failwith "relation.threadenter: unknown function"
694+
[special_unknown_invalidate ctx f args]
691695

692696
let threadspawn ctx ~multiple lval f args fctx =
693697
ctx.local

0 commit comments

Comments
 (0)