@ -12,9 +12,6 @@ open PulseDomainInterface
let debug fmt = L . ( debug Analysis Verbose fmt )
let debug fmt = L . ( debug Analysis Verbose fmt )
(* An impurity analysis that relies on pulse to determine how the state
changes * )
let get_matching_dest_addr_opt ~ edges_pre ~ edges_post : AbstractValue . t list option =
let get_matching_dest_addr_opt ~ edges_pre ~ edges_post : AbstractValue . t list option =
match
match
List . fold2 ~ init : ( Some [] )
List . fold2 ~ init : ( Some [] )
@ -37,23 +34,19 @@ let add_invalid_and_modified ~check_empty attrs acc =
Attributes . get_written_to attrs
Attributes . get_written_to attrs
| > Option . value_map ~ default : [] ~ f : ( fun modified -> [ ImpurityDomain . WrittenTo modified ] )
| > Option . value_map ~ default : [] ~ f : ( fun modified -> [ ImpurityDomain . WrittenTo modified ] )
in
in
let res =
let invalid_and_modified =
Attributes . get_invalid attrs
match Attributes . get_invalid attrs with
| > Option . value_map ~ default : modified ~ f : ( fun invalid ->
| None | Some ( PulseInvalidation . ConstantDereference _ , _ ) ->
ImpurityDomain . Invalid invalid :: modified )
modified
| Some invalid ->
ImpurityDomain . Invalid invalid :: modified
in
in
if check_empty && List . is_empty res then
if check_empty && List . is_empty invalid_and_modified then
L . ( die InternalError ) " Address is modified without being written to or invalidated. "
L . ( die InternalError ) " Address is modified without being written to or invalidated. "
else res @ acc
else invalid_and_modified @ acc
(* * Given Pulse summary, extract impurity info, i.e. parameters and global variables that are
let add_to_modified var addr pre_heap post acc =
modified by the function and skipped functions . * )
let extract_impurity tenv pdesc pre_post : ImpurityDomain . t =
let pre_heap = ( AbductiveDomain . extract_pre pre_post ) . BaseDomain . heap in
let post = AbductiveDomain . extract_post pre_post in
let post_stack = post . BaseDomain . stack in
let add_to_modified var addr acc =
let rec aux acc ~ addr_to_explore ~ visited : ImpurityDomain . trace list =
let rec aux acc ~ addr_to_explore ~ visited : ImpurityDomain . trace list =
match addr_to_explore with
match addr_to_explore with
| [] ->
| [] ->
@ -90,28 +83,39 @@ let extract_impurity tenv pdesc pre_post : ImpurityDomain.t =
acc
acc
| hd :: tl ->
| hd :: tl ->
ImpurityDomain . ModifiedVarSet . add { var ; trace_list = ( hd , tl ) } acc
ImpurityDomain . ModifiedVarSet . add { var ; trace_list = ( hd , tl ) } acc
in
let pname = Procdesc . get_proc_name pdesc in
let modified_params =
let get_modified_params pname post_stack pre_heap post formals =
Procdesc . get_formals pdesc
List . fold_left formals ~ init : ImpurityDomain . ModifiedVarSet . empty ~ f : ( fun acc ( name , typ ) ->
| > List . fold_left ~ init : ImpurityDomain . ModifiedVarSet . empty ~ f : ( fun acc ( name , typ ) ->
let var = Var . of_pvar ( Pvar . mk name pname ) in
let var = Var . of_pvar ( Pvar . mk name pname ) in
match BaseStack . find_opt var post_stack with
match BaseStack . find_opt var post_stack with
| Some ( addr , _ ) when Typ . is_pointer typ -> (
| Some ( addr , _ ) when Typ . is_pointer typ -> (
match BaseMemory . find_opt addr pre_heap with
match BaseMemory . find_opt addr pre_heap with
| Some edges_pre ->
| Some edges_pre ->
BaseMemory . Edges . fold
BaseMemory . Edges . fold
( fun _ ( addr , _ ) acc -> add_to_modified var addr acc )
( fun _ ( addr , _ ) acc -> add_to_modified var addr pre_heap post acc )
edges_pre acc
edges_pre acc
| None ->
| None ->
debug " The address is not materialized in pre-heap. " ;
debug " The address is not materialized in pre-heap. " ;
acc )
acc )
| _ ->
| _ ->
acc )
acc )
(* * Given Pulse summary, extract impurity info, i.e. parameters and global variables that are
modified by the function and skipped functions . * )
let extract_impurity tenv pdesc pre_post : ImpurityDomain . t =
let pre_heap = ( AbductiveDomain . extract_pre pre_post ) . BaseDomain . heap in
let post = AbductiveDomain . extract_post pre_post in
let post_stack = post . BaseDomain . stack in
let pname = Procdesc . get_proc_name pdesc in
let modified_params =
Procdesc . get_formals pdesc | > get_modified_params pname post_stack pre_heap post
in
in
let modified_globals =
let modified_globals =
BaseStack . fold
BaseStack . fold
( fun var ( addr , _ ) acc -> if Var . is_global var then add_to_modified var addr acc else acc )
( fun var ( addr , _ ) acc ->
if Var . is_global var then add_to_modified var addr pre_heap post acc else acc )
post_stack ImpurityDomain . ModifiedVarSet . empty
post_stack ImpurityDomain . ModifiedVarSet . empty
in
in
let is_modeled_pure pname =
let is_modeled_pure pname =