Summary: Adds an abstract domain to track global variable usages, as well as supporting changes to the frontend, IR and CLI. This analysis will support optimizations to the main symbolic-heap analysis, but for now can be invoked independently through the `-domain` flag on `analyze` targets of the Sledge executable. Reviewed By: jberdine Differential Revision: D17422212 fbshipit-source-id: 74bed0a76master
parent
633186c41e
commit
47f314c00e
@ -0,0 +1,68 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** Used-globals abstract domain *)
|
||||||
|
|
||||||
|
type t = Var.Set.t [@@deriving equal, sexp_of]
|
||||||
|
|
||||||
|
let pp = Set.pp Var.pp
|
||||||
|
let report_fmt_thunk = Fn.flip pp
|
||||||
|
let empty = Var.Set.empty
|
||||||
|
|
||||||
|
let init globals =
|
||||||
|
[%Trace.info
|
||||||
|
"pgm globals: {%a}" (Vector.pp ", " Llair_.Global.pp) globals] ;
|
||||||
|
empty
|
||||||
|
|
||||||
|
let join = Set.union
|
||||||
|
let is_false _ = false
|
||||||
|
let post _ _ state = state
|
||||||
|
let retn _ _ from_call post = Set.union from_call post
|
||||||
|
let dnf t = [t]
|
||||||
|
let add_if_global gs v = if Var.global v then Set.add gs v else gs
|
||||||
|
|
||||||
|
let used_globals ?(init = empty) exp =
|
||||||
|
Exp.fold_vars exp ~init ~f:add_if_global
|
||||||
|
|
||||||
|
let exec_assume st exp = Some (used_globals ~init:st exp)
|
||||||
|
let exec_kill st _ = st
|
||||||
|
let exec_move st _ rhs = used_globals ~init:st rhs
|
||||||
|
|
||||||
|
let exec_inst st inst =
|
||||||
|
[%Trace.call fun {pf} -> pf "{%a} %a { ? }" pp st Llair.Inst.pp inst]
|
||||||
|
;
|
||||||
|
Ok
|
||||||
|
(Llair.Inst.fold_exps inst ~init:st ~f:(fun acc e ->
|
||||||
|
used_globals ~init:acc e ))
|
||||||
|
|>
|
||||||
|
[%Trace.retn fun {pf} res ->
|
||||||
|
match res with
|
||||||
|
| Ok uses -> pf "new uses: %a" pp (Set.diff uses st)
|
||||||
|
| _ -> ()]
|
||||||
|
|
||||||
|
let exec_intrinsic ~skip_throw:_ st _ _ actuals =
|
||||||
|
List.fold actuals ~init:st ~f:(fun s a -> used_globals ~init:s a)
|
||||||
|
|> fun res -> Some (Ok res)
|
||||||
|
|
||||||
|
type from_call = t [@@deriving sexp_of]
|
||||||
|
|
||||||
|
(* Set abstract state to bottom (i.e. empty set) at function entry *)
|
||||||
|
let call ~summaries:_ actuals _ _ _ _ st =
|
||||||
|
(empty, List.fold actuals ~init:st ~f:(fun s a -> used_globals ~init:s a))
|
||||||
|
|
||||||
|
let resolve_callee lookup ptr _ =
|
||||||
|
match Var.of_exp ptr with
|
||||||
|
| Some callee_name -> lookup callee_name
|
||||||
|
| None -> []
|
||||||
|
|
||||||
|
(* A function summary is the set of global variables accessed by that
|
||||||
|
function and its transitive callees *)
|
||||||
|
type summary = t
|
||||||
|
|
||||||
|
let pp_summary = pp
|
||||||
|
let create_summary ~locals:_ ~formals:_ state = (state, state)
|
||||||
|
let apply_summary st summ = Some (Set.union st summ)
|
@ -0,0 +1,10 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** Used-globals abstract domain *)
|
||||||
|
|
||||||
|
include Domain_sig.Dom
|
Loading…
Reference in new issue