[ai] No need to create a domain for a bottom_lifted type

Summary: Makes `type 'astate bottom_lifted` accessible without invoking `BottomLifted`

Reviewed By: jvillard, sblackshear

Differential Revision: D5920660

fbshipit-source-id: 40fca97
master
Mehdi Bouaziz 7 years ago committed by Facebook Github Bot
parent 8012d61b0f
commit 39ff045569

@ -10,6 +10,14 @@
open! IStd open! IStd
module F = Format module F = Format
module Types = struct
type 'astate bottom_lifted = Bottom | NonBottom of 'astate
type 'astate top_lifted = Top | NonTop of 'astate
end
open! Types
module type S = sig module type S = sig
type astate type astate
@ -39,7 +47,7 @@ module type WithTop = sig
end end
module BottomLifted (Domain : S) = struct module BottomLifted (Domain : S) = struct
type astate = Bottom | NonBottom of Domain.astate type astate = Domain.astate bottom_lifted
let empty = Bottom let empty = Bottom
@ -82,7 +90,7 @@ module BottomLifted (Domain : S) = struct
end end
module TopLifted (Domain : S) = struct module TopLifted (Domain : S) = struct
type astate = Top | NonTop of Domain.astate type astate = Domain.astate top_lifted
let top = Top let top = Top

@ -10,6 +10,14 @@
open! IStd open! IStd
module F = Format module F = Format
module Types : sig
type 'astate bottom_lifted = Bottom | NonBottom of 'astate
type 'astate top_lifted = Top | NonTop of 'astate
end
open! Types
(** Abstract domains and domain combinators *) (** Abstract domains and domain combinators *)
module type S = sig module type S = sig
@ -47,14 +55,14 @@ end
(** Lift a pre-domain to a domain *) (** Lift a pre-domain to a domain *)
module BottomLifted (Domain : S) : sig module BottomLifted (Domain : S) : sig
type astate = Bottom | NonBottom of Domain.astate type astate = Domain.astate bottom_lifted
include WithBottom with type astate := astate include WithBottom with type astate := astate
end end
(** Create a domain with Top element from a pre-domain *) (** Create a domain with Top element from a pre-domain *)
module TopLifted (Domain : S) : sig module TopLifted (Domain : S) : sig
type astate = Top | NonTop of Domain.astate type astate = Domain.astate top_lifted
include WithTop with type astate := astate include WithTop with type astate := astate
end end

@ -12,6 +12,7 @@
open! IStd open! IStd
open AbsLoc open AbsLoc
open! AbstractDomain.Types
module F = Format module F = Format
module L = Logging module L = Logging
module Dom = BufferOverrunDomain module Dom = BufferOverrunDomain
@ -134,7 +135,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| "__inferbo_min" | "__inferbo_min"
-> model_min ret params loc mem -> model_min ret params loc mem
| "__exit" | "exit" | "__exit" | "exit"
-> Dom.Mem.Bottom -> Bottom
| "fgetc" | "fgetc"
-> model_by_value Dom.Val.Itv.m1_255 ret mem -> model_by_value Dom.Val.Itv.m1_255 ret mem
| "infer_print" | "infer_print"

@ -12,6 +12,7 @@
open! IStd open! IStd
open AbsLoc open AbsLoc
open! AbstractDomain.Types
module F = Format module F = Format
module L = Logging module L = Logging
module MF = MarkupFormatter module MF = MarkupFormatter

@ -11,6 +11,7 @@
*) *)
open! IStd open! IStd
open! AbstractDomain.Types
module F = Format module F = Format
module L = Logging module L = Logging

@ -8,6 +8,7 @@
*) *)
open! IStd open! IStd
open! AbstractDomain.Types
module F = Format module F = Format
module L = Logging module L = Logging
module GlobalsAccesses = SiofTrace.GlobalsAccesses module GlobalsAccesses = SiofTrace.GlobalsAccesses
@ -63,7 +64,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let is_compile_time_constructed pdesc pv = let is_compile_time_constructed pdesc pv =
let init_pname = Pvar.get_initializer_pname pv in let init_pname = Pvar.get_initializer_pname pv in
match Option.bind init_pname ~f:(Summary.read_summary pdesc) with match Option.bind init_pname ~f:(Summary.read_summary pdesc) with
| Some (Domain.BottomSiofTrace.Bottom, _) | Some (Bottom, _)
-> (* we analyzed the initializer for this global and found that it doesn't require any runtime -> (* we analyzed the initializer for this global and found that it doesn't require any runtime
initialization so cannot participate in SIOF *) initialization so cannot participate in SIOF *)
true true
@ -94,13 +95,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let add_globals astate outer_loc globals = let add_globals astate outer_loc globals =
if GlobalsAccesses.is_empty globals then astate if GlobalsAccesses.is_empty globals then astate
else else
let trace = let trace = match fst astate with Bottom -> SiofTrace.empty | NonBottom t -> t in
match fst astate with
| Domain.BottomSiofTrace.Bottom
-> SiofTrace.empty
| Domain.BottomSiofTrace.NonBottom t
-> t
in
(* filter out variables that are known to be already initialized *) (* filter out variables that are known to be already initialized *)
let non_init_globals = let non_init_globals =
let initialized = snd astate in let initialized = snd astate in
@ -109,15 +104,14 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let globals_trace = let globals_trace =
SiofTrace.add_sink (SiofTrace.make_access non_init_globals outer_loc) trace SiofTrace.add_sink (SiofTrace.make_access non_init_globals outer_loc) trace
in in
(Domain.BottomSiofTrace.NonBottom globals_trace, snd astate) (NonBottom globals_trace, snd astate)
let add_params_globals astate pdesc call_loc params = let add_params_globals astate pdesc call_loc params =
List.map ~f:(fun (e, _) -> get_globals pdesc call_loc e) params List.map ~f:(fun (e, _) -> get_globals pdesc call_loc e) params
|> List.fold ~f:GlobalsAccesses.union ~init:GlobalsAccesses.empty |> List.fold ~f:GlobalsAccesses.union ~init:GlobalsAccesses.empty
|> add_globals astate (Procdesc.get_loc pdesc) |> add_globals astate (Procdesc.get_loc pdesc)
let at_least_nonbottom = let at_least_nonbottom = Domain.join (NonBottom SiofTrace.empty, Domain.VarNames.empty)
Domain.join (Domain.BottomSiofTrace.NonBottom SiofTrace.empty, Domain.VarNames.empty)
let exec_instr astate {ProcData.pdesc} _ (instr: Sil.instr) = let exec_instr astate {ProcData.pdesc} _ (instr: Sil.instr) =
match instr with match instr with
@ -135,8 +129,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
then Some initialized_globals then Some initialized_globals
else None ) else None )
in in
Domain.join astate Domain.join astate (NonBottom SiofTrace.empty, Domain.VarNames.of_list init)
(Domain.BottomSiofTrace.NonBottom SiofTrace.empty, Domain.VarNames.of_list init)
| Call (_, Const Cfun callee_pname, _ :: params_without_self, loc, _) | Call (_, Const Cfun callee_pname, _ :: params_without_self, loc, _)
when Typ.Procname.is_c_method callee_pname && Typ.Procname.is_constructor callee_pname when Typ.Procname.is_c_method callee_pname && Typ.Procname.is_constructor callee_pname
&& Typ.Procname.is_constexpr callee_pname && Typ.Procname.is_constexpr callee_pname
@ -145,7 +138,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
-> let callsite = CallSite.make callee_pname loc in -> let callsite = CallSite.make callee_pname loc in
let callee_astate = let callee_astate =
match Summary.read_summary pdesc callee_pname with match Summary.read_summary pdesc callee_pname with
| Some (Domain.BottomSiofTrace.NonBottom trace, initialized_globals) | Some (NonBottom trace, initialized_globals)
-> let trace_without_initialized_globals = -> let trace_without_initialized_globals =
let sinks_with_non_init_globals = let sinks_with_non_init_globals =
SiofTrace.Sinks.filter SiofTrace.Sinks.filter
@ -156,13 +149,12 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
in in
SiofTrace.update_sinks trace sinks_with_non_init_globals SiofTrace.update_sinks trace sinks_with_non_init_globals
in in
( Domain.BottomSiofTrace.NonBottom ( NonBottom (SiofTrace.with_callsite trace_without_initialized_globals callsite)
(SiofTrace.with_callsite trace_without_initialized_globals callsite)
, initialized_globals ) , initialized_globals )
| Some (Domain.BottomSiofTrace.Bottom, _ as astate) | Some (Bottom, _ as astate)
-> astate -> astate
| None | None
-> (Domain.BottomSiofTrace.Bottom, Domain.VarNames.empty) -> (Bottom, Domain.VarNames.empty)
in in
add_params_globals astate pdesc loc params |> Domain.join callee_astate add_params_globals astate pdesc loc params |> Domain.join callee_astate
|> (* make sure it's not Bottom: we made a function call so this needs initialization *) |> (* make sure it's not Bottom: we made a function call so this needs initialization *)
@ -193,7 +185,7 @@ let report_siof summary trace pdesc gname loc =
in in
let trace_of_pname pname = let trace_of_pname pname =
match Summary.read_summary pdesc pname with match Summary.read_summary pdesc pname with
| Some (SiofDomain.BottomSiofTrace.NonBottom summary, _) | Some (NonBottom summary, _)
-> summary -> summary
| _ | _
-> SiofTrace.empty -> SiofTrace.empty
@ -233,7 +225,7 @@ let report_siof summary trace pdesc gname loc =
let siof_check pdesc gname (summary: Specs.summary) = let siof_check pdesc gname (summary: Specs.summary) =
match summary.payload.siof with match summary.payload.siof with
| Some (SiofDomain.BottomSiofTrace.NonBottom post, _) | Some (NonBottom post, _)
-> let attrs = Procdesc.get_attributes pdesc in -> let attrs = Procdesc.get_attributes pdesc in
let all_globals = let all_globals =
SiofTrace.Sinks.fold SiofTrace.Sinks.fold
@ -246,12 +238,12 @@ let siof_check pdesc gname (summary: Specs.summary) =
in in
if GlobalsAccesses.exists (is_foreign tu_opt) all_globals then if GlobalsAccesses.exists (is_foreign tu_opt) all_globals then
report_siof summary post pdesc gname attrs.ProcAttributes.loc report_siof summary post pdesc gname attrs.ProcAttributes.loc
| Some (SiofDomain.BottomSiofTrace.Bottom, _) | None | Some (Bottom, _) | None
-> () -> ()
let checker {Callbacks.proc_desc; tenv; summary} : Specs.summary = let checker {Callbacks.proc_desc; tenv; summary} : Specs.summary =
let proc_data = ProcData.make_default proc_desc tenv in let proc_data = ProcData.make_default proc_desc tenv in
let initial = (SiofDomain.BottomSiofTrace.Bottom, SiofDomain.VarNames.empty) in let initial = (Bottom, SiofDomain.VarNames.empty) in
let updated_summary = let updated_summary =
match Analyzer.compute_post proc_data ~initial with match Analyzer.compute_post proc_data ~initial with
| Some post | Some post

@ -8,6 +8,7 @@
*) *)
open! IStd open! IStd
open! AbstractDomain.Types
module VarNames = AbstractDomain.FiniteSet (String) module VarNames = AbstractDomain.FiniteSet (String)
module BottomSiofTrace = AbstractDomain.BottomLifted (SiofTrace) module BottomSiofTrace = AbstractDomain.BottomLifted (SiofTrace)
include AbstractDomain.Pair (BottomSiofTrace) (VarNames) include AbstractDomain.Pair (BottomSiofTrace) (VarNames)
@ -15,9 +16,9 @@ include AbstractDomain.Pair (BottomSiofTrace) (VarNames)
(** group together procedure-local accesses *) (** group together procedure-local accesses *)
let normalize (trace, initialized as astate) = let normalize (trace, initialized as astate) =
match trace with match trace with
| BottomSiofTrace.Bottom | Bottom
-> astate -> astate
| BottomSiofTrace.NonBottom trace | NonBottom trace
-> let elems = SiofTrace.Sinks.elements (SiofTrace.sinks trace) in -> let elems = SiofTrace.Sinks.elements (SiofTrace.sinks trace) in
let direct, indirect = List.partition_tf ~f:SiofTrace.is_intraprocedural_access elems in let direct, indirect = List.partition_tf ~f:SiofTrace.is_intraprocedural_access elems in
match direct with match direct with
@ -35,4 +36,4 @@ let normalize (trace, initialized as astate) =
SiofTrace.make_access kind loc :: indirect |> SiofTrace.Sinks.of_list SiofTrace.make_access kind loc :: indirect |> SiofTrace.Sinks.of_list
|> SiofTrace.update_sinks trace |> SiofTrace.update_sinks trace
in in
(BottomSiofTrace.NonBottom trace', initialized) (NonBottom trace', initialized)

@ -8,6 +8,7 @@
*) *)
open! IStd open! IStd
open! AbstractDomain.Types
module F = Format module F = Format
module L = Logging module L = Logging
module MF = MarkupFormatter module MF = MarkupFormatter
@ -21,9 +22,9 @@ module Domain = struct
let add_call_site annot sink call_site (annot_map, previous_vstate as astate) = let add_call_site annot sink call_site (annot_map, previous_vstate as astate) =
match previous_vstate with match previous_vstate with
| TrackingDomain.Bottom | Bottom
-> astate -> astate
| TrackingDomain.NonBottom _ | NonBottom _
-> let sink_map = -> let sink_map =
try AnnotReachabilityDomain.find annot annot_map try AnnotReachabilityDomain.find annot annot_map
with Not_found -> AnnotReachabilityDomain.SinkMap.empty with Not_found -> AnnotReachabilityDomain.SinkMap.empty
@ -37,28 +38,24 @@ module Domain = struct
if phys_equal sink_map' sink_map then astate if phys_equal sink_map' sink_map then astate
else (AnnotReachabilityDomain.add annot sink_map' annot_map, previous_vstate) else (AnnotReachabilityDomain.add annot sink_map' annot_map, previous_vstate)
let stop_tracking ((annot_map, _): astate) = (annot_map, TrackingDomain.Bottom) let stop_tracking ((annot_map, _): astate) = (annot_map, Bottom)
let add_tracking_var var (annot_map, previous_vstate as astate) = let add_tracking_var var (annot_map, previous_vstate as astate) =
match previous_vstate with match previous_vstate with
| TrackingDomain.Bottom | Bottom
-> astate -> astate
| TrackingDomain.NonBottom vars | NonBottom vars
-> (annot_map, TrackingDomain.NonBottom (TrackingVar.add var vars)) -> (annot_map, NonBottom (TrackingVar.add var vars))
let remove_tracking_var var (annot_map, previous_vstate as astate) = let remove_tracking_var var (annot_map, previous_vstate as astate) =
match previous_vstate with match previous_vstate with
| TrackingDomain.Bottom | Bottom
-> astate -> astate
| TrackingDomain.NonBottom vars | NonBottom vars
-> (annot_map, TrackingDomain.NonBottom (TrackingVar.remove var vars)) -> (annot_map, NonBottom (TrackingVar.remove var vars))
let is_tracked_var var (_, vstate) = let is_tracked_var var (_, vstate) =
match vstate with match vstate with Bottom -> false | NonBottom vars -> TrackingVar.mem var vars
| TrackingDomain.Bottom
-> false
| TrackingDomain.NonBottom vars
-> TrackingVar.mem var vars
end end
module Summary = Summary.Make (struct module Summary = Summary.Make (struct
@ -434,9 +431,7 @@ end
module Analyzer = AbstractInterpreter.Make (ProcCfg.Exceptional) (TransferFunctions) module Analyzer = AbstractInterpreter.Make (ProcCfg.Exceptional) (TransferFunctions)
let checker ({Callbacks.proc_desc; tenv; summary} as callback) : Specs.summary = let checker ({Callbacks.proc_desc; tenv; summary} as callback) : Specs.summary =
let initial = let initial = (AnnotReachabilityDomain.empty, NonBottom Domain.TrackingVar.empty) in
(AnnotReachabilityDomain.empty, Domain.TrackingDomain.NonBottom Domain.TrackingVar.empty)
in
let proc_data = ProcData.make_default proc_desc tenv in let proc_data = ProcData.make_default proc_desc tenv in
match Analyzer.compute_post proc_data ~initial with match Analyzer.compute_post proc_data ~initial with
| Some (annot_map, _) | Some (annot_map, _)

Loading…
Cancel
Save