|  |  |  | @ -91,7 +91,7 @@ let add_abstraction_instructions pdesc = | 
			
		
	
		
			
				
					|  |  |  |  |     if node_requires_abstraction node then Node.append_instrs node [Sil.Abstract loc] in | 
			
		
	
		
			
				
					|  |  |  |  |   Cfg.Procdesc.iter_nodes do_node pdesc | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | module BackwardCfg = ProcCfg.Backward(ProcCfg.Exceptional) | 
			
		
	
		
			
				
					|  |  |  |  | module BackwardCfg = ProcCfg.OneInstrPerNode(ProcCfg.Backward(ProcCfg.Exceptional)) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | module LivenessAnalysis = | 
			
		
	
		
			
				
					|  |  |  |  |   AbstractInterpreter.Make | 
			
		
	
	
		
			
				
					|  |  |  | @ -115,9 +115,10 @@ module NullifyTransferFunctions = struct | 
			
		
	
		
			
				
					|  |  |  |  |   module CFG = ProcCfg.Exceptional | 
			
		
	
		
			
				
					|  |  |  |  |   type extras = LivenessAnalysis.inv_map | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |   let postprocess ((reaching_defs, _) as astate) node_id { ProcData.extras; } = | 
			
		
	
		
			
				
					|  |  |  |  |   let postprocess ((reaching_defs, _) as astate) node { ProcData.extras; } = | 
			
		
	
		
			
				
					|  |  |  |  |     let node_id =  (CFG.underlying_id node), ProcCfg.Node_index in | 
			
		
	
		
			
				
					|  |  |  |  |     match LivenessAnalysis.extract_state node_id extras with | 
			
		
	
		
			
				
					|  |  |  |  |     (* note: because the analysis backward, post and pre are reversed *) | 
			
		
	
		
			
				
					|  |  |  |  |     (* note: because the analysis is backward, post and pre are reversed *) | 
			
		
	
		
			
				
					|  |  |  |  |     | Some { AbstractInterpreter.post = live_before; pre = live_after; } -> | 
			
		
	
		
			
				
					|  |  |  |  |         let to_nullify = VarDomain.diff (VarDomain.union live_before reaching_defs) live_after in | 
			
		
	
		
			
				
					|  |  |  |  |         let reaching_defs' = VarDomain.diff reaching_defs to_nullify in | 
			
		
	
	
		
			
				
					|  |  |  | @ -150,7 +151,7 @@ module NullifyTransferFunctions = struct | 
			
		
	
		
			
				
					|  |  |  |  |       | Sil.Nullify _ -> | 
			
		
	
		
			
				
					|  |  |  |  |           failwith "Should not add nullify instructions before running nullify analysis!" in | 
			
		
	
		
			
				
					|  |  |  |  |     if is_last_instr_in_node instr node | 
			
		
	
		
			
				
					|  |  |  |  |     then postprocess astate' (CFG.id node) extras | 
			
		
	
		
			
				
					|  |  |  |  |     then postprocess astate' node extras | 
			
		
	
		
			
				
					|  |  |  |  |     else astate' | 
			
		
	
		
			
				
					|  |  |  |  | end | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -159,16 +160,32 @@ module NullifyAnalysis = | 
			
		
	
		
			
				
					|  |  |  |  |     (Scheduler.ReversePostorder (ProcCfg.Exceptional)) | 
			
		
	
		
			
				
					|  |  |  |  |     (NullifyTransferFunctions) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let add_nullify_instrs pdesc tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   let liveness_proc_cfg = BackwardCfg.from_pdesc pdesc in | 
			
		
	
		
			
				
					|  |  |  |  |   let proc_data_no_extras = ProcData.make_default pdesc tenv in | 
			
		
	
		
			
				
					|  |  |  |  |   let liveness_inv_map = LivenessAnalysis.exec_cfg liveness_proc_cfg proc_data_no_extras in | 
			
		
	
		
			
				
					|  |  |  |  | (** remove dead stores whose lhs is a frontend-created temporary variable. these dead stores are | 
			
		
	
		
			
				
					|  |  |  |  |     created by copy-propagation *) | 
			
		
	
		
			
				
					|  |  |  |  | let remove_dead_frontend_stores pdesc liveness_inv_map = | 
			
		
	
		
			
				
					|  |  |  |  |   let is_live var instr_id liveness_inv_map = | 
			
		
	
		
			
				
					|  |  |  |  |     match LivenessAnalysis.extract_pre instr_id liveness_inv_map with | 
			
		
	
		
			
				
					|  |  |  |  |     | Some pre -> VarDomain.mem var pre | 
			
		
	
		
			
				
					|  |  |  |  |     | None -> true in | 
			
		
	
		
			
				
					|  |  |  |  |   let is_used_store (instr, instr_id_opt) = | 
			
		
	
		
			
				
					|  |  |  |  |     match instr, instr_id_opt with | 
			
		
	
		
			
				
					|  |  |  |  |     | Sil.Letderef (id, _, _, _), Some instr_id when not (Ident.is_none id) -> | 
			
		
	
		
			
				
					|  |  |  |  |         is_live (Var.of_id id) instr_id liveness_inv_map | 
			
		
	
		
			
				
					|  |  |  |  |     | _ -> true in | 
			
		
	
		
			
				
					|  |  |  |  |   let node_remove_dead_stores node = | 
			
		
	
		
			
				
					|  |  |  |  |     let instr_nodes = BackwardCfg.instr_ids node in | 
			
		
	
		
			
				
					|  |  |  |  |     let instr_nodes' = IList.filter_changed is_used_store instr_nodes in | 
			
		
	
		
			
				
					|  |  |  |  |     if instr_nodes' != instr_nodes | 
			
		
	
		
			
				
					|  |  |  |  |     then | 
			
		
	
		
			
				
					|  |  |  |  |       Cfg.Node.replace_instrs node (IList.rev_map fst instr_nodes') in | 
			
		
	
		
			
				
					|  |  |  |  |   Cfg.Procdesc.iter_nodes node_remove_dead_stores pdesc | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let add_nullify_instrs pdesc tenv liveness_inv_map = | 
			
		
	
		
			
				
					|  |  |  |  |   let address_taken_vars = | 
			
		
	
		
			
				
					|  |  |  |  |     if Procname.is_java (Cfg.Procdesc.get_proc_name pdesc) | 
			
		
	
		
			
				
					|  |  |  |  |     then AddressTaken.Domain.empty (* can't take the address of a variable in Java *) | 
			
		
	
		
			
				
					|  |  |  |  |     else | 
			
		
	
		
			
				
					|  |  |  |  |       match AddressTaken.Analyzer.compute_post proc_data_no_extras with | 
			
		
	
		
			
				
					|  |  |  |  |       match AddressTaken.Analyzer.compute_post (ProcData.make_default pdesc tenv) with | 
			
		
	
		
			
				
					|  |  |  |  |       | Some post -> post | 
			
		
	
		
			
				
					|  |  |  |  |       | None -> AddressTaken.Domain.empty in | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -270,8 +287,16 @@ let do_copy_propagation pdesc tenv = | 
			
		
	
		
			
				
					|  |  |  |  |        then Cfg.Node.replace_instrs node (IList.rev instrs)) | 
			
		
	
		
			
				
					|  |  |  |  |     (Cfg.Procdesc.get_nodes pdesc) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let do_liveness pdesc tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   let liveness_proc_cfg = BackwardCfg.from_pdesc pdesc in | 
			
		
	
		
			
				
					|  |  |  |  |   LivenessAnalysis.exec_cfg liveness_proc_cfg (ProcData.make_default pdesc tenv) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let doit pdesc cg tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   if Config.copy_propagation then do_copy_propagation pdesc tenv; | 
			
		
	
		
			
				
					|  |  |  |  |   add_nullify_instrs pdesc tenv; | 
			
		
	
		
			
				
					|  |  |  |  |   if not Config.lazy_dynamic_dispatch then add_dispatch_calls pdesc cg tenv; | 
			
		
	
		
			
				
					|  |  |  |  |   let liveness_inv_map = do_liveness pdesc tenv in | 
			
		
	
		
			
				
					|  |  |  |  |   if not (Config.lazy_dynamic_dispatch) && Config.copy_propagation | 
			
		
	
		
			
				
					|  |  |  |  |   then remove_dead_frontend_stores pdesc liveness_inv_map; | 
			
		
	
		
			
				
					|  |  |  |  |   add_nullify_instrs pdesc tenv liveness_inv_map; | 
			
		
	
		
			
				
					|  |  |  |  |   if not Config.lazy_dynamic_dispatch | 
			
		
	
		
			
				
					|  |  |  |  |   then add_dispatch_calls pdesc cg tenv; | 
			
		
	
		
			
				
					|  |  |  |  |   add_abstraction_instructions pdesc; | 
			
		
	
	
		
			
				
					|  |  |  | 
 |