[Inferbo] Refactoring 7/8: remove dependency on CFG

Reviewed By: jvillard

Differential Revision: D7397133

fbshipit-source-id: e036c04
master
Mehdi Bouaziz 7 years ago committed by Facebook Github Bot
parent 722a66d452
commit a4eac6c2d6

@ -13,8 +13,11 @@
open! IStd open! IStd
open AbsLoc open AbsLoc
open! AbstractDomain.Types open! AbstractDomain.Types
module L = Logging module BoUtils = BufferOverrunUtils
module Dom = BufferOverrunDomain module Dom = BufferOverrunDomain
module L = Logging
module Models = BufferOverrunModels
module Sem = BufferOverrunSemantics
module Trace = BufferOverrunTrace module Trace = BufferOverrunTrace
module TraceSet = Trace.Set module TraceSet = Trace.Set
@ -31,9 +34,6 @@ end)
module TransferFunctions (CFG : ProcCfg.S) = struct module TransferFunctions (CFG : ProcCfg.S) = struct
module CFG = CFG module CFG = CFG
module Domain = Dom.Mem module Domain = Dom.Mem
module BoUtils = BufferOverrunUtils.Make (CFG)
module Sem = BoUtils.Sem
module Models = BufferOverrunModels.Make (BoUtils)
type extras = Typ.Procname.t -> Procdesc.t option type extras = Typ.Procname.t -> Procdesc.t option
@ -313,11 +313,6 @@ module CFG = Analyzer.TransferFunctions.CFG
type invariant_map = Analyzer.invariant_map type invariant_map = Analyzer.invariant_map
module Report = struct module Report = struct
(* I'd like to avoid rebuilding this :(
Everything depend on CFG only because of `get_allocsite` *)
module BoUtils = BufferOverrunUtils.Make (CFG)
module Sem = BoUtils.Sem
module Models = BufferOverrunModels.Make (BoUtils)
module PO = BufferOverrunProofObligations module PO = BufferOverrunProofObligations
type extras = Typ.Procname.t -> Procdesc.t option type extras = Typ.Procname.t -> Procdesc.t option

@ -11,15 +11,13 @@ open! IStd
open AbsLoc open AbsLoc
open! AbstractDomain.Types open! AbstractDomain.Types
module L = Logging module L = Logging
module BoUtils = BufferOverrunUtils
module Dom = BufferOverrunDomain module Dom = BufferOverrunDomain
module PO = BufferOverrunProofObligations module PO = BufferOverrunProofObligations
module Sem = BufferOverrunSemantics
module Trace = BufferOverrunTrace module Trace = BufferOverrunTrace
module TraceSet = Trace.Set module TraceSet = Trace.Set
module Make (BoUtils : BufferOverrunUtils.S) = struct
module CFG = BoUtils.CFG
module Sem = BoUtils.Sem
type model_env = type model_env =
{ pname: Typ.Procname.t { pname: Typ.Procname.t
; node_hash: int ; node_hash: int
@ -178,9 +176,9 @@ module Make (BoUtils : BufferOverrunUtils.S) = struct
mem mem
let by_value value = let by_value =
let exec {ret} mem = model_by_value value ret mem in let exec ~value {ret} mem = model_by_value value ret mem in
{exec; check= no_check} fun value -> {exec= exec ~value; check= no_check}
let bottom = let bottom =
@ -231,9 +229,7 @@ module Make (BoUtils : BufferOverrunUtils.S) = struct
module Boost = struct module Boost = struct
module Split = struct module Split = struct
let std_vector vector_arg = let std_vector vector_arg =
let exec {location} mem = let exec {location} mem = Split.std_vector ~adds_at_least_one:true vector_arg location mem in
Split.std_vector ~adds_at_least_one:true vector_arg location mem
in
{exec; check= no_check} {exec; check= no_check}
end end
end end
@ -261,15 +257,15 @@ module Make (BoUtils : BufferOverrunUtils.S) = struct
let declare_local ~decl_local {pname; node_hash; location} loc ~inst_num ~dimension mem = let declare_local ~decl_local {pname; node_hash; location} loc ~inst_num ~dimension mem =
(* should this be deferred to the constructor? *) (* should this be deferred to the constructor? *)
let length = Some (IntLit.of_int64 length) in let length = Some (IntLit.of_int64 length) in
BoUtils.Exec.decl_local_array ~decl_local pname ~node_hash location loc typ ~length BoUtils.Exec.decl_local_array ~decl_local pname ~node_hash location loc typ ~length ~inst_num
~inst_num ~dimension mem ~dimension mem
in in
let declare_symbolic ~decl_sym_val {pname; tenv; node_hash; location} ~depth loc ~inst_num let declare_symbolic ~decl_sym_val {pname; tenv; node_hash; location} ~depth loc ~inst_num
~new_sym_num ~new_alloc_num mem = ~new_sym_num ~new_alloc_num mem =
let offset = Itv.zero in let offset = Itv.zero in
let size = Itv.of_int64 length in let size = Itv.of_int64 length in
BoUtils.Exec.decl_sym_arr ~decl_sym_val pname tenv ~node_hash location ~depth loc typ BoUtils.Exec.decl_sym_arr ~decl_sym_val pname tenv ~node_hash location ~depth loc typ ~offset
~offset ~size ~inst_num ~new_sym_num ~new_alloc_num mem ~size ~inst_num ~new_sym_num ~new_alloc_num mem
in in
{declare_local; declare_symbolic} {declare_local; declare_symbolic}
@ -312,8 +308,8 @@ module Make (BoUtils : BufferOverrunUtils.S) = struct
let declare_local ~decl_local:_ {pname; location} _loc ~inst_num ~dimension:_ mem = let declare_local ~decl_local:_ {pname; location} _loc ~inst_num ~dimension:_ mem =
(no_model "local" pname location mem, inst_num) (no_model "local" pname location mem, inst_num)
in in
let declare_symbolic ~decl_sym_val:_ {pname; location} ~depth:_ _loc ~inst_num:_ let declare_symbolic ~decl_sym_val:_ {pname; location} ~depth:_ _loc ~inst_num:_ ~new_sym_num:_
~new_sym_num:_ ~new_alloc_num:_ mem = ~new_alloc_num:_ mem =
no_model "symbolic" pname location mem no_model "symbolic" pname location mem
in in
{declare_local; declare_symbolic} {declare_local; declare_symbolic}
@ -356,4 +352,3 @@ module Make (BoUtils : BufferOverrunUtils.S) = struct
[ -"std" &:: "array" < capt_typ `T &+ capt_int >--> StdArray.typ [ -"std" &:: "array" < capt_typ `T &+ capt_int >--> StdArray.typ
; -"std" &:: "array" &::.*--> StdArray.no_typ_model ] ; -"std" &:: "array" &::.*--> StdArray.no_typ_model ]
end end
end

@ -19,9 +19,6 @@ module Trace = BufferOverrunTrace
module TraceSet = Trace.Set module TraceSet = Trace.Set
open BufferOverrunDomain open BufferOverrunDomain
module Make (CFG : ProcCfg.S) = struct
exception Not_implemented
let eval_const : Const.t -> Val.t = function let eval_const : Const.t -> Val.t = function
| Const.Cint intlit -> ( | Const.Cint intlit -> (
try Val.of_int (IntLit.to_int intlit) with _ -> Val.Itv.top ) try Val.of_int (IntLit.to_int intlit) with _ -> Val.Itv.top )
@ -581,4 +578,3 @@ module Make (CFG : ProcCfg.S) = struct
list_fold2_def ~default:Val.Itv.top ~f:add_pair formals actuals ~init:([], None) list_fold2_def ~default:Val.Itv.top ~f:add_pair formals actuals ~init:([], None)
in in
(subst_map_of_pairs pairs, ret_alias) (subst_map_of_pairs pairs, ret_alias)
end

@ -13,54 +13,10 @@ open! AbstractDomain.Types
module L = Logging module L = Logging
module Dom = BufferOverrunDomain module Dom = BufferOverrunDomain
module PO = BufferOverrunProofObligations module PO = BufferOverrunProofObligations
module Sem = BufferOverrunSemantics
module Trace = BufferOverrunTrace module Trace = BufferOverrunTrace
module TraceSet = Trace.Set module TraceSet = Trace.Set
module type S = sig
module CFG : ProcCfg.S
module Sem : module type of BufferOverrunSemantics.Make (CFG)
module Exec : sig
val load_val : Ident.t -> Dom.Val.astate -> Dom.Mem.astate -> Dom.Mem.astate
type decl_local =
Typ.Procname.t -> node_hash:int -> Location.t -> Loc.t -> Typ.t -> inst_num:int
-> dimension:int -> Dom.Mem.astate -> Dom.Mem.astate * int
val decl_local_array :
decl_local:decl_local -> Typ.Procname.t -> node_hash:int -> Location.t -> Loc.t -> Typ.t
-> length:IntLit.t option -> ?stride:int -> inst_num:int -> dimension:int -> Dom.Mem.astate
-> Dom.Mem.astate * int
type decl_sym_val =
Typ.Procname.t -> Tenv.t -> node_hash:int -> Location.t -> depth:int -> Loc.t -> Typ.t
-> Dom.Mem.astate -> Dom.Mem.astate
val decl_sym_arr :
decl_sym_val:decl_sym_val -> Typ.Procname.t -> Tenv.t -> node_hash:int -> Location.t
-> depth:int -> Loc.t -> Typ.t -> ?offset:Itv.t -> ?size:Itv.t -> inst_num:int
-> new_sym_num:Itv.Counter.t -> new_alloc_num:Itv.Counter.t -> Dom.Mem.astate
-> Dom.Mem.astate
val init_array_fields :
Tenv.t -> Typ.Procname.t -> node_hash:int -> Typ.t -> PowLoc.t -> ?dyn_length:Exp.t
-> Dom.Mem.astate -> Dom.Mem.astate
val set_dyn_length : Tenv.t -> Typ.t -> PowLoc.t -> Itv.t -> Dom.Mem.astate -> Dom.Mem.astate
end
module Check : sig
val lindex :
array_exp:Exp.t -> index_exp:Exp.t -> Dom.Mem.astate -> Typ.Procname.t -> Location.t
-> PO.ConditionSet.t -> PO.ConditionSet.t
end
end
module Make (CFG : ProcCfg.S) = struct
module CFG = CFG
module Sem = BufferOverrunSemantics.Make (CFG)
module Exec = struct module Exec = struct
let load_val id val_ mem = let load_val id val_ mem =
let locs = val_ |> Dom.Val.get_all_locs in let locs = val_ |> Dom.Val.get_all_locs in
@ -76,18 +32,16 @@ module Make (CFG : ProcCfg.S) = struct
let decl_local_array let decl_local_array
: decl_local:decl_local -> Typ.Procname.t -> node_hash:int -> Location.t -> Loc.t -> Typ.t : decl_local:decl_local -> Typ.Procname.t -> node_hash:int -> Location.t -> Loc.t -> Typ.t
-> length:IntLit.t option -> ?stride:int -> inst_num:int -> dimension:int -> length:IntLit.t option -> ?stride:int -> inst_num:int -> dimension:int -> Dom.Mem.astate
-> Dom.Mem.astate -> Dom.Mem.astate * int = -> Dom.Mem.astate * int =
fun ~decl_local pname ~node_hash location loc typ ~length ?stride ~inst_num ~dimension mem -> fun ~decl_local pname ~node_hash location loc typ ~length ?stride ~inst_num ~dimension mem ->
let size = Option.value_map ~default:Itv.top ~f:Itv.of_int_lit length in let size = Option.value_map ~default:Itv.top ~f:Itv.of_int_lit length in
let arr = let arr =
Sem.eval_array_alloc pname ~node_hash typ ~stride ~offset:Itv.zero ~size ~inst_num Sem.eval_array_alloc pname ~node_hash typ ~stride ~offset:Itv.zero ~size ~inst_num ~dimension
~dimension
|> Dom.Val.add_trace_elem (Trace.ArrDecl location) |> Dom.Val.add_trace_elem (Trace.ArrDecl location)
in in
let mem = let mem =
if Int.equal dimension 1 then Dom.Mem.add_stack loc arr mem if Int.equal dimension 1 then Dom.Mem.add_stack loc arr mem else Dom.Mem.add_heap loc arr mem
else Dom.Mem.add_heap loc arr mem
in in
let loc = Loc.of_allocsite (Sem.get_allocsite pname ~node_hash ~inst_num ~dimension) in let loc = Loc.of_allocsite (Sem.get_allocsite pname ~node_hash ~inst_num ~dimension) in
let mem, _ = let mem, _ =
@ -153,8 +107,7 @@ module Make (CFG : ProcCfg.S) = struct
match Tenv.lookup tenv typename with match Tenv.lookup tenv typename with
| Some str -> | Some str ->
let f = init_field locs (dimension + 1) in let f = init_field locs (dimension + 1) in
IList.fold_last ~f ~f_last:(f ?dyn_length) ~init:(mem, 1) str.Typ.Struct.fields IList.fold_last ~f ~f_last:(f ?dyn_length) ~init:(mem, 1) str.Typ.Struct.fields |> fst
|> fst
| None -> | None ->
mem ) mem )
| _ -> | _ ->
@ -211,4 +164,3 @@ module Make (CFG : ProcCfg.S) = struct
let idx = Sem.eval index_exp mem in let idx = Sem.eval index_exp mem in
array_access ~arr ~idx ~is_plus:true pname location cond_set array_access ~arr ~idx ~is_plus:true pname location cond_set
end end
end

@ -0,0 +1,51 @@
(*
* Copyright (c) 2017 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! IStd
open AbsLoc
module Dom = BufferOverrunDomain
module PO = BufferOverrunProofObligations
module Exec : sig
val load_val : Ident.t -> Dom.Val.astate -> Dom.Mem.astate -> Dom.Mem.astate
type decl_local =
Typ.Procname.t -> node_hash:int -> Location.t -> Loc.t -> Typ.t -> inst_num:int
-> dimension:int -> Dom.Mem.astate -> Dom.Mem.astate * int
val decl_local_array :
decl_local:decl_local -> Typ.Procname.t -> node_hash:int -> Location.t -> Loc.t -> Typ.t
-> length:IntLit.t option -> ?stride:int -> inst_num:int -> dimension:int -> Dom.Mem.astate
-> Dom.Mem.astate * int
type decl_sym_val =
Typ.Procname.t -> Tenv.t -> node_hash:int -> Location.t -> depth:int -> Loc.t -> Typ.t
-> Dom.Mem.astate -> Dom.Mem.astate
val decl_sym_arr :
decl_sym_val:decl_sym_val -> Typ.Procname.t -> Tenv.t -> node_hash:int -> Location.t
-> depth:int -> Loc.t -> Typ.t -> ?offset:Itv.t -> ?size:Itv.t -> inst_num:int
-> new_sym_num:Itv.Counter.t -> new_alloc_num:Itv.Counter.t -> Dom.Mem.astate -> Dom.Mem.astate
val init_array_fields :
Tenv.t -> Typ.Procname.t -> node_hash:int -> Typ.t -> PowLoc.t -> ?dyn_length:Exp.t
-> Dom.Mem.astate -> Dom.Mem.astate
val set_dyn_length : Tenv.t -> Typ.t -> PowLoc.t -> Itv.t -> Dom.Mem.astate -> Dom.Mem.astate
end
module Check : sig
val array_access :
arr:Dom.Val.t -> idx:Dom.Val.t -> is_plus:bool -> Typ.Procname.t -> Location.t
-> PO.ConditionSet.t -> PO.ConditionSet.t
val lindex :
array_exp:Exp.t -> index_exp:Exp.t -> Dom.Mem.astate -> Typ.Procname.t -> Location.t
-> PO.ConditionSet.t -> PO.ConditionSet.t
end
Loading…
Cancel
Save