@ -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  =