[inferbo] Simplify condition trace

Reviewed By: skcho

Differential Revision: D9372262

fbshipit-source-id: 5338d5437
master
Mehdi Bouaziz 6 years ago committed by Facebook Github Bot
parent 5817ff6adc
commit 277fd06782

@ -393,38 +393,36 @@ module Report = struct
let check_binop_array_access let check_binop_array_access
: Typ.Procname.t -> is_plus:bool -> e1:Exp.t -> e2:Exp.t -> Location.t -> Dom.Mem.astate : is_plus:bool -> e1:Exp.t -> e2:Exp.t -> Location.t -> Dom.Mem.astate -> PO.ConditionSet.t
-> PO.ConditionSet.t -> PO.ConditionSet.t = -> PO.ConditionSet.t =
fun pname ~is_plus ~e1 ~e2 location mem cond_set -> fun ~is_plus ~e1 ~e2 location mem cond_set ->
let arr = Sem.eval e1 mem in let arr = Sem.eval e1 mem in
let idx = Sem.eval e2 mem in let idx = Sem.eval e2 mem in
let idx_sym_exp = Relation.SymExp.of_exp ~get_sym_f:(Sem.get_sym_f mem) e2 in let idx_sym_exp = Relation.SymExp.of_exp ~get_sym_f:(Sem.get_sym_f mem) e2 in
let relation = Dom.Mem.get_relation mem in let relation = Dom.Mem.get_relation mem in
BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus pname location cond_set BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus location cond_set
let check_binop let check_binop
: Typ.Procname.t -> bop:Binop.t -> e1:Exp.t -> e2:Exp.t -> Location.t -> Dom.Mem.astate : bop:Binop.t -> e1:Exp.t -> e2:Exp.t -> Location.t -> Dom.Mem.astate -> PO.ConditionSet.t
-> PO.ConditionSet.t -> PO.ConditionSet.t = -> PO.ConditionSet.t =
fun pname ~bop ~e1 ~e2 location mem cond_set -> fun ~bop ~e1 ~e2 location mem cond_set ->
match bop with match bop with
| Binop.PlusPI -> | Binop.PlusPI ->
check_binop_array_access pname ~is_plus:true ~e1 ~e2 location mem cond_set check_binop_array_access ~is_plus:true ~e1 ~e2 location mem cond_set
| Binop.MinusPI -> | Binop.MinusPI ->
check_binop_array_access pname ~is_plus:false ~e1 ~e2 location mem cond_set check_binop_array_access ~is_plus:false ~e1 ~e2 location mem cond_set
| _ -> | _ ->
cond_set cond_set
let check_expr let check_expr : Exp.t -> Location.t -> Dom.Mem.astate -> PO.ConditionSet.t -> PO.ConditionSet.t =
: Typ.Procname.t -> Exp.t -> Location.t -> Dom.Mem.astate -> PO.ConditionSet.t fun exp location mem cond_set ->
-> PO.ConditionSet.t =
fun pname exp location mem cond_set ->
let rec check_sub_expr exp cond_set = let rec check_sub_expr exp cond_set =
match exp with match exp with
| Exp.Lindex (array_exp, index_exp) -> | Exp.Lindex (array_exp, index_exp) ->
cond_set |> check_sub_expr array_exp |> check_sub_expr index_exp cond_set |> check_sub_expr array_exp |> check_sub_expr index_exp
|> BoUtils.Check.lindex ~array_exp ~index_exp mem pname location |> BoUtils.Check.lindex ~array_exp ~index_exp mem location
| Exp.BinOp (_, e1, e2) -> | Exp.BinOp (_, e1, e2) ->
cond_set |> check_sub_expr e1 |> check_sub_expr e2 cond_set |> check_sub_expr e1 |> check_sub_expr e2
| Exp.Lfield (e, _, _) | Exp.UnOp (_, e, _) | Exp.Exn e | Exp.Cast (_, e) -> | Exp.Lfield (e, _, _) | Exp.UnOp (_, e, _) | Exp.Exn e | Exp.Cast (_, e) ->
@ -441,18 +439,17 @@ module Report = struct
let arr = Sem.eval exp mem in let arr = Sem.eval exp mem in
let idx, idx_sym_exp = (Dom.Val.Itv.zero, Some Relation.SymExp.zero) in let idx, idx_sym_exp = (Dom.Val.Itv.zero, Some Relation.SymExp.zero) in
let relation = Dom.Mem.get_relation mem in let relation = Dom.Mem.get_relation mem in
BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus:true pname location BoUtils.Check.array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus:true location cond_set
cond_set
| Exp.BinOp (bop, e1, e2) -> | Exp.BinOp (bop, e1, e2) ->
check_binop pname ~bop ~e1 ~e2 location mem cond_set check_binop ~bop ~e1 ~e2 location mem cond_set
| _ -> | _ ->
cond_set cond_set
let instantiate_cond let instantiate_cond
: Tenv.t -> Typ.Procname.t -> Procdesc.t -> (Exp.t * Typ.t) list -> Dom.Mem.astate : Tenv.t -> Procdesc.t -> (Exp.t * Typ.t) list -> Dom.Mem.astate -> Payload.t -> Location.t
-> Payload.t -> Location.t -> PO.ConditionSet.t = -> PO.ConditionSet.t =
fun tenv caller_pname callee_pdesc params caller_mem summary location -> fun tenv callee_pdesc params caller_mem summary location ->
let callee_symbol_table = Dom.Summary.get_symbol_table summary in let callee_symbol_table = Dom.Summary.get_symbol_table summary in
let callee_exit_mem = Dom.Summary.get_output summary in let callee_exit_mem = Dom.Summary.get_output summary in
let callee_cond = Dom.Summary.get_cond_set summary in let callee_cond = Dom.Summary.get_cond_set summary in
@ -461,22 +458,21 @@ module Report = struct
in in
let pname = Procdesc.get_proc_name callee_pdesc in let pname = Procdesc.get_proc_name callee_pdesc in
let caller_rel = Dom.Mem.get_relation caller_mem in let caller_rel = Dom.Mem.get_relation caller_mem in
PO.ConditionSet.subst callee_cond bound_subst_map rel_subst_map caller_rel caller_pname pname PO.ConditionSet.subst callee_cond bound_subst_map rel_subst_map caller_rel pname location
location
let check_instr let check_instr
: Procdesc.t -> Tenv.t -> Itv.SymbolTable.t -> CFG.Node.t -> Sil.instr -> Dom.Mem.astate : Procdesc.t -> Tenv.t -> Itv.SymbolTable.t -> CFG.Node.t -> Sil.instr -> Dom.Mem.astate
-> PO.ConditionSet.t -> PO.ConditionSet.t = -> PO.ConditionSet.t -> PO.ConditionSet.t =
fun pdesc tenv symbol_table node instr mem cond_set -> fun pdesc tenv symbol_table node instr mem cond_set ->
let pname = Procdesc.get_proc_name pdesc in
match instr with match instr with
| Sil.Load (_, exp, _, location) | Sil.Store (exp, _, _, location) -> | Sil.Load (_, exp, _, location) | Sil.Store (exp, _, _, location) ->
check_expr pname exp location mem cond_set check_expr exp location mem cond_set
| Sil.Call (_, Const (Cfun callee_pname), params, location, _) -> ( | Sil.Call (_, Const (Cfun callee_pname), params, location, _) -> (
match Models.Call.dispatch tenv callee_pname params with match Models.Call.dispatch tenv callee_pname params with
| Some {Models.check} -> | Some {Models.check} ->
let node_hash = CFG.Node.hash node in let node_hash = CFG.Node.hash node in
let pname = Procdesc.get_proc_name pdesc in
check (Models.mk_model_env pname node_hash location tenv symbol_table) mem cond_set check (Models.mk_model_env pname node_hash location tenv symbol_table) mem cond_set
| None -> | None ->
match Ondemand.analyze_proc_name ~caller_pdesc:pdesc callee_pname with match Ondemand.analyze_proc_name ~caller_pdesc:pdesc callee_pname with
@ -484,7 +480,7 @@ module Report = struct
match Payload.of_summary callee_summary with match Payload.of_summary callee_summary with
| Some callee_payload -> | Some callee_payload ->
let callee_pdesc = Summary.get_proc_desc callee_summary in let callee_pdesc = Summary.get_proc_desc callee_summary in
instantiate_cond tenv pname callee_pdesc params mem callee_payload location instantiate_cond tenv callee_pdesc params mem callee_payload location
|> PO.ConditionSet.join cond_set |> PO.ConditionSet.join cond_set
| None -> | None ->
(* no inferbo payload *) cond_set ) (* no inferbo payload *) cond_set )
@ -582,29 +578,21 @@ module Report = struct
List.fold_right ~f ~init:([], 0) trace.trace |> fst |> List.rev List.fold_right ~f ~init:([], 0) trace.trace |> fst |> List.rev
let report_errors : Summary.t -> Procdesc.t -> PO.ConditionSet.t -> PO.ConditionSet.t = let report_errors : Summary.t -> PO.ConditionSet.t -> PO.ConditionSet.t =
fun summary pdesc cond_set -> fun summary cond_set ->
let pname = Procdesc.get_proc_name pdesc in
let report cond trace issue_type = let report cond trace issue_type =
let caller_pname, location = let location = PO.ConditionTrace.get_report_location trace in
match PO.ConditionTrace.get_cond_trace trace with let description = PO.description cond trace in
| PO.ConditionTrace.Inter (caller_pname, _, location) -> let error_desc = Localise.desc_buffer_overrun description in
(caller_pname, location) let exn = Exceptions.Checkers (issue_type, error_desc) in
| PO.ConditionTrace.Intra pname -> let trace =
(pname, PO.ConditionTrace.get_location trace) match TraceSet.choose_shortest trace.PO.ConditionTrace.val_traces with
| trace ->
make_err_trace trace description
| exception _ ->
[Errlog.make_trace_element 0 location description []]
in in
if Typ.Procname.equal pname caller_pname then Reporting.log_error summary ~loc:location ~ltr:trace exn
let description = PO.description cond trace in
let error_desc = Localise.desc_buffer_overrun description in
let exn = Exceptions.Checkers (issue_type, error_desc) in
let trace =
match TraceSet.choose_shortest trace.PO.ConditionTrace.val_traces with
| trace ->
make_err_trace trace description
| exception _ ->
[Errlog.make_trace_element 0 location description []]
in
Reporting.log_error summary ~loc:location ~ltr:trace exn
in in
PO.ConditionSet.check_all ~report cond_set PO.ConditionSet.check_all ~report cond_set
@ -647,7 +635,7 @@ let compute_invariant_map_and_check : Callbacks.proc_callback_args -> invariant_
in in
let cond_set = let cond_set =
Report.check_proc summary proc_desc tenv symbol_table cfg inv_map Report.check_proc summary proc_desc tenv symbol_table cfg inv_map
|> Report.report_errors summary proc_desc |> Report.forget_locs locals |> Report.report_errors summary |> Report.forget_locs locals
in in
let summary = let summary =
match exit_mem with match exit_mem with

@ -66,7 +66,7 @@ let get_malloc_info : Exp.t -> Typ.t * Int.t option * Exp.t * Exp.t option = fun
(Typ.mk (Typ.Tint Typ.IChar), Some 1, x, None) (Typ.mk (Typ.Tint Typ.IChar), Some 1, x, None)
let check_alloc_size size_exp {pname; location} mem cond_set = let check_alloc_size size_exp {location} mem cond_set =
let _, _, length0, _ = get_malloc_info size_exp in let _, _, length0, _ = get_malloc_info size_exp in
let v_length = Sem.eval length0 mem in let v_length = Sem.eval length0 mem in
match Dom.Val.get_itv v_length with match Dom.Val.get_itv v_length with
@ -77,7 +77,7 @@ let check_alloc_size size_exp {pname; location} mem cond_set =
let traces = let traces =
Dom.Val.get_traces v_length |> BufferOverrunTrace.Set.add_elem alloc_trace_elem Dom.Val.get_traces v_length |> BufferOverrunTrace.Set.add_elem alloc_trace_elem
in in
PO.ConditionSet.add_alloc_size pname location ~length traces cond_set PO.ConditionSet.add_alloc_size location ~length traces cond_set
let set_uninitialized location (typ: Typ.t) ploc mem = let set_uninitialized location (typ: Typ.t) ploc mem =
@ -275,8 +275,8 @@ module StdArray = struct
let exec _ ~ret:(id, _) mem = let exec _ ~ret:(id, _) mem =
L.(debug BufferOverrun Verbose) "Using model std::array<_, %Ld>::at" _size ; L.(debug BufferOverrun Verbose) "Using model std::array<_, %Ld>::at" _size ;
BoUtils.Exec.load_val id (Sem.eval_lindex array_exp index_exp mem) mem BoUtils.Exec.load_val id (Sem.eval_lindex array_exp index_exp mem) mem
and check {pname; location} mem cond_set = and check {location} mem cond_set =
BoUtils.Check.lindex ~array_exp ~index_exp mem pname location cond_set BoUtils.Check.lindex ~array_exp ~index_exp mem location cond_set
in in
{exec; check} {exec; check}
@ -384,18 +384,18 @@ module Collection = struct
let add_at_index (alist_id: Ident.t) index_exp = let add_at_index (alist_id: Ident.t) index_exp =
let check {pname; location} mem cond_set = let check {location} mem cond_set =
let array_exp = Exp.Var alist_id in let array_exp = Exp.Var alist_id in
BoUtils.Check.collection_access ~array_exp ~index_exp ~is_collection_add:true mem pname BoUtils.Check.collection_access ~array_exp ~index_exp ~is_collection_add:true mem location
location cond_set cond_set
in in
{exec= change_size_by ~size_f:incr_size alist_id; check} {exec= change_size_by ~size_f:incr_size alist_id; check}
let remove_at_index alist_id index_exp = let remove_at_index alist_id index_exp =
let check {pname; location} mem cond_set = let check {location} mem cond_set =
let array_exp = Exp.Var alist_id in let array_exp = Exp.Var alist_id in
BoUtils.Check.collection_access ~array_exp ~index_exp mem pname location cond_set BoUtils.Check.collection_access ~array_exp ~index_exp mem location cond_set
in in
{exec= change_size_by ~size_f:decr_size alist_id; check} {exec= change_size_by ~size_f:decr_size alist_id; check}
@ -405,19 +405,19 @@ module Collection = struct
let to_add_length = get_size alist_to_add mem in let to_add_length = get_size alist_to_add mem in
change_size_by ~size_f:(Dom.Val.plus_a to_add_length) alist_id _model_env ~ret mem change_size_by ~size_f:(Dom.Val.plus_a to_add_length) alist_id _model_env ~ret mem
in in
let check {pname; location} mem cond_set = let check {location} mem cond_set =
let array_exp = Exp.Var alist_id in let array_exp = Exp.Var alist_id in
BoUtils.Check.collection_access ~index_exp ~array_exp ~is_collection_add:true mem pname BoUtils.Check.collection_access ~index_exp ~array_exp ~is_collection_add:true mem location
location cond_set cond_set
in in
{exec; check} {exec; check}
let get_or_set_at_index alist_id index_exp = let get_or_set_at_index alist_id index_exp =
let exec _model_env ~ret:_ mem = mem in let exec _model_env ~ret:_ mem = mem in
let check {pname; location} mem cond_set = let check {location} mem cond_set =
let array_exp = Exp.Var alist_id in let array_exp = Exp.Var alist_id in
BoUtils.Check.collection_access ~index_exp ~array_exp mem pname location cond_set BoUtils.Check.collection_access ~index_exp ~array_exp mem location cond_set
in in
{exec; check} {exec; check}
end end

@ -357,57 +357,52 @@ module Condition = struct
end end
module ConditionTrace = struct module ConditionTrace = struct
type cond_trace = type cond_trace = Intra | Inter of {call_site: Location.t; callee_pname: Typ.Procname.t}
| Intra of Typ.Procname.t
| Inter of Typ.Procname.t * Typ.Procname.t * Location.t
[@@deriving compare] [@@deriving compare]
type t = type t = {cond_trace: cond_trace; issue_location: Location.t; val_traces: ValTraceSet.t}
{ proc_name: Typ.Procname.t
; cond_trace: cond_trace
; location: Location.t
; val_traces: ValTraceSet.t }
[@@deriving compare] [@@deriving compare]
let pp_location : F.formatter -> t -> unit = fun fmt ct -> Location.pp_file_pos fmt ct.location let pp_location : F.formatter -> t -> unit =
fun fmt ct -> Location.pp_file_pos fmt ct.issue_location
let pp : F.formatter -> t -> unit = let pp : F.formatter -> t -> unit =
fun fmt ct -> fun fmt ct ->
if Config.bo_debug <= 1 then F.fprintf fmt "at %a" pp_location ct if Config.bo_debug <= 1 then F.fprintf fmt "at %a" pp_location ct
else else
match ct.cond_trace with match ct.cond_trace with
| Inter (_, pname, location) -> | Inter {callee_pname; call_site} ->
let pname = Typ.Procname.to_string pname in let pname = Typ.Procname.to_string callee_pname in
F.fprintf fmt "at %a by call to %s at %a (%a)" pp_location ct pname Location.pp_file_pos F.fprintf fmt "at %a by call to %s at %a (%a)" pp_location ct pname Location.pp_file_pos
location ValTraceSet.pp ct.val_traces call_site ValTraceSet.pp ct.val_traces
| Intra _ -> | Intra ->
F.fprintf fmt "%a (%a)" pp_location ct ValTraceSet.pp ct.val_traces F.fprintf fmt "%a (%a)" pp_location ct ValTraceSet.pp ct.val_traces
let pp_description : F.formatter -> t -> unit = let pp_description : F.formatter -> t -> unit =
fun fmt ct -> fun fmt ct ->
match ct.cond_trace with match ct.cond_trace with
| Inter (_, pname, _) | Inter {callee_pname}
when Config.bo_debug >= 1 || not (SourceFile.is_cpp_model ct.location.Location.file) -> when Config.bo_debug >= 1 || not (SourceFile.is_cpp_model ct.issue_location.Location.file) ->
F.fprintf fmt " by call to %a " MF.pp_monospaced (Typ.Procname.to_string pname) F.fprintf fmt " by call to %a " MF.pp_monospaced (Typ.Procname.to_string callee_pname)
| _ -> | _ ->
() ()
let get_location : t -> Location.t = fun ct -> ct.location let get_report_location : t -> Location.t =
fun ct -> match ct.cond_trace with Intra -> ct.issue_location | Inter {call_site} -> call_site
let get_cond_trace : t -> cond_trace = fun ct -> ct.cond_trace
let make : Typ.Procname.t -> Location.t -> ValTraceSet.t -> t = let make : Location.t -> ValTraceSet.t -> t =
fun proc_name location val_traces -> fun issue_location val_traces -> {issue_location; cond_trace= Intra; val_traces}
{proc_name; location; cond_trace= Intra proc_name; val_traces}
let make_call_and_subst ~traces_caller ~caller_pname ~callee_pname location ct = let make_call_and_subst ~traces_caller ~callee_pname call_site ct =
let val_traces = let val_traces =
ValTraceSet.instantiate ~traces_caller ~traces_callee:ct.val_traces location ValTraceSet.instantiate ~traces_caller ~traces_callee:ct.val_traces call_site
in in
{ct with cond_trace= Inter (caller_pname, callee_pname, location); val_traces} {ct with cond_trace= Inter {callee_pname; call_site}; val_traces}
let has_unknown ct = ValTraceSet.has_unknown ct.val_traces let has_unknown ct = ValTraceSet.has_unknown ct.val_traces
@ -442,13 +437,13 @@ module ConditionWithTrace = struct
cmp cmp
let subst (bound_map, trace_map) rel_map caller_relation caller_pname callee_pname location cwt = let subst (bound_map, trace_map) rel_map caller_relation callee_pname call_site cwt =
let symbols = Condition.get_symbols cwt.cond in let symbols = Condition.get_symbols cwt.cond in
if List.is_empty symbols then if List.is_empty symbols then
L.(die InternalError) L.(die InternalError)
"Trying to substitute a non-symbolic condition %a from %a at %a. Why was it propagated in \ "Trying to substitute a non-symbolic condition %a from %a at %a. Why was it propagated in \
the first place?" the first place?"
pp cwt Typ.Procname.pp callee_pname Location.pp location ; pp cwt Typ.Procname.pp callee_pname Location.pp call_site ;
match Condition.subst bound_map rel_map caller_relation cwt.cond with match Condition.subst bound_map rel_map caller_relation cwt.cond with
| None -> | None ->
None None
@ -462,8 +457,7 @@ module ConditionWithTrace = struct
val_traces ) val_traces )
in in
let trace = let trace =
ConditionTrace.make_call_and_subst ~traces_caller ~caller_pname ~callee_pname location ConditionTrace.make_call_and_subst ~traces_caller ~callee_pname call_site cwt.trace
cwt.trace
in in
Some {cond; trace; reported= cwt.reported} Some {cond; trace; reported= cwt.reported}
@ -561,32 +555,31 @@ module ConditionSet = struct
let join condset1 condset2 = List.fold_left ~f:join_one condset1 ~init:condset2 let join condset1 condset2 = List.fold_left ~f:join_one condset1 ~init:condset2
let add_opt pname location val_traces condset = function let add_opt location val_traces condset = function
| None -> | None ->
condset condset
| Some cond -> | Some cond ->
let trace = ConditionTrace.make pname location val_traces in let trace = ConditionTrace.make location val_traces in
let cwt = ConditionWithTrace.make cond trace in let cwt = ConditionWithTrace.make cond trace in
join [cwt] condset join [cwt] condset
let add_array_access pname location ~idx ~size ~is_collection_add ~idx_sym_exp ~size_sym_exp let add_array_access location ~idx ~size ~is_collection_add ~idx_sym_exp ~size_sym_exp ~relation
~relation val_traces condset = val_traces condset =
ArrayAccessCondition.make ~idx ~size ~idx_sym_exp ~size_sym_exp ~relation ArrayAccessCondition.make ~idx ~size ~idx_sym_exp ~size_sym_exp ~relation
|> Condition.make_array_access ~is_collection_add |> add_opt pname location val_traces condset |> Condition.make_array_access ~is_collection_add |> add_opt location val_traces condset
let add_alloc_size pname location ~length val_traces condset = let add_alloc_size location ~length val_traces condset =
AllocSizeCondition.make ~length |> Condition.make_alloc_size AllocSizeCondition.make ~length |> Condition.make_alloc_size
|> add_opt pname location val_traces condset |> add_opt location val_traces condset
let subst condset bound_map_trace_map rel_subst_map caller_relation caller_pname callee_pname let subst condset bound_map_trace_map rel_subst_map caller_relation callee_pname call_site =
location =
let subst_add_cwt condset cwt = let subst_add_cwt condset cwt =
match match
ConditionWithTrace.subst bound_map_trace_map rel_subst_map caller_relation caller_pname ConditionWithTrace.subst bound_map_trace_map rel_subst_map caller_relation callee_pname
callee_pname location cwt call_site cwt
with with
| None -> | None ->
condset condset

@ -199,18 +199,18 @@ end
module Check = struct module Check = struct
let check_access ~size ~idx ~size_sym_exp ~idx_sym_exp ~relation ~arr ~idx_traces let check_access ~size ~idx ~size_sym_exp ~idx_sym_exp ~relation ~arr ~idx_traces
?(is_collection_add= false) pname location cond_set = ?(is_collection_add= false) location cond_set =
let arr_traces = Dom.Val.get_traces arr in let arr_traces = Dom.Val.get_traces arr in
match (size, idx) with match (size, idx) with
| NonBottom length, NonBottom idx -> | NonBottom length, NonBottom idx ->
let traces = TraceSet.merge ~arr_traces ~idx_traces location in let traces = TraceSet.merge ~arr_traces ~idx_traces location in
PO.ConditionSet.add_array_access pname location ~size:length ~idx ~size_sym_exp PO.ConditionSet.add_array_access location ~size:length ~idx ~size_sym_exp ~idx_sym_exp
~idx_sym_exp ~relation ~is_collection_add traces cond_set ~relation ~is_collection_add traces cond_set
| _ -> | _ ->
cond_set cond_set
let array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus pname location cond_set = let array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus location cond_set =
let arr_blk = Dom.Val.get_array_blk arr in let arr_blk = Dom.Val.get_array_blk arr in
let size = ArrayBlk.sizeof arr_blk in let size = ArrayBlk.sizeof arr_blk in
let size_sym_exp = Relation.SymExp.of_sym (Dom.Val.get_size_sym arr) in let size_sym_exp = Relation.SymExp.of_sym (Dom.Val.get_size_sym arr) in
@ -226,12 +226,11 @@ module Check = struct
in in
L.(debug BufferOverrun Verbose) L.(debug BufferOverrun Verbose)
"@[<v 2>Add condition :@,array: %a@, idx: %a@,@]@." ArrayBlk.pp arr_blk Itv.pp idx_in_blk ; "@[<v 2>Add condition :@,array: %a@, idx: %a@,@]@." ArrayBlk.pp arr_blk Itv.pp idx_in_blk ;
check_access ~size ~idx:idx_in_blk ~size_sym_exp ~idx_sym_exp ~relation ~arr ~idx_traces pname check_access ~size ~idx:idx_in_blk ~size_sym_exp ~idx_sym_exp ~relation ~arr ~idx_traces
location cond_set location cond_set
let collection_access ~array_exp ~index_exp ?(is_collection_add= false) mem pname location let collection_access ~array_exp ~index_exp ?(is_collection_add= false) mem location cond_set =
cond_set =
let idx = Sem.eval index_exp mem in let idx = Sem.eval index_exp mem in
let arr = Sem.eval array_exp mem in let arr = Sem.eval array_exp mem in
let idx_traces = Dom.Val.get_traces idx in let idx_traces = Dom.Val.get_traces idx in
@ -239,13 +238,13 @@ module Check = struct
let idx = Dom.Val.get_itv idx in let idx = Dom.Val.get_itv idx in
let relation = Dom.Mem.get_relation mem in let relation = Dom.Mem.get_relation mem in
check_access ~size ~idx ~size_sym_exp:None ~idx_sym_exp:None ~relation ~arr ~idx_traces check_access ~size ~idx ~size_sym_exp:None ~idx_sym_exp:None ~relation ~arr ~idx_traces
~is_collection_add pname location cond_set ~is_collection_add location cond_set
let lindex ~array_exp ~index_exp mem pname location cond_set = let lindex ~array_exp ~index_exp mem location cond_set =
let idx = Sem.eval index_exp mem in let idx = Sem.eval index_exp mem in
let arr = Sem.eval_arr array_exp mem in let arr = Sem.eval_arr array_exp mem in
let idx_sym_exp = Relation.SymExp.of_exp ~get_sym_f:(Sem.get_sym_f mem) index_exp in let idx_sym_exp = Relation.SymExp.of_exp ~get_sym_f:(Sem.get_sym_f mem) index_exp in
let relation = Dom.Mem.get_relation mem in let relation = Dom.Mem.get_relation mem in
array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus:true pname location cond_set array_access ~arr ~idx ~idx_sym_exp ~relation ~is_plus:true location cond_set
end end

@ -58,14 +58,14 @@ end
module Check : sig module Check : sig
val array_access : val array_access :
arr:Dom.Val.t -> idx:Dom.Val.t -> idx_sym_exp:Relation.SymExp.t option arr:Dom.Val.t -> idx:Dom.Val.t -> idx_sym_exp:Relation.SymExp.t option
-> relation:Relation.astate -> is_plus:bool -> Typ.Procname.t -> Location.t -> relation:Relation.astate -> is_plus:bool -> Location.t -> PO.ConditionSet.t
-> PO.ConditionSet.t -> PO.ConditionSet.t -> PO.ConditionSet.t
val lindex : val lindex :
array_exp:Exp.t -> index_exp:Exp.t -> Dom.Mem.astate -> Typ.Procname.t -> Location.t array_exp:Exp.t -> index_exp:Exp.t -> Dom.Mem.astate -> Location.t -> PO.ConditionSet.t
-> PO.ConditionSet.t -> PO.ConditionSet.t -> PO.ConditionSet.t
val collection_access : val collection_access :
array_exp:Exp.t -> index_exp:Exp.t -> ?is_collection_add:bool -> Dom.Mem.astate array_exp:Exp.t -> index_exp:Exp.t -> ?is_collection_add:bool -> Dom.Mem.astate -> Location.t
-> Typ.Procname.t -> Location.t -> PO.ConditionSet.t -> PO.ConditionSet.t -> PO.ConditionSet.t -> PO.ConditionSet.t
end end

Loading…
Cancel
Save