@ -20,6 +20,11 @@ module Import = struct
 
			
		
	
		
		
			
				
					
					    |  ExitProgram  of  AbductiveDomain . summary 
    |  ExitProgram  of  AbductiveDomain . summary 
 
			
		
	
		
		
			
				
					
					    |  AbortProgram  of  AbductiveDomain . summary 
    |  AbortProgram  of  AbductiveDomain . summary 
 
			
		
	
		
		
			
				
					
					    |  LatentAbortProgram  of  { astate :  AbductiveDomain . summary ;  latent_issue :  LatentIssue . t } 
    |  LatentAbortProgram  of  { astate :  AbductiveDomain . summary ;  latent_issue :  LatentIssue . t } 
 
			
		
	
		
		
			
				
					
					    |  LatentInvalidAccess  of 
 
			
		
	
		
		
			
				
					
					        {  astate :  AbductiveDomain . summary 
 
			
		
	
		
		
			
				
					
					        ;  address :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  must_be_valid :  Trace . t 
 
			
		
	
		
		
			
				
					
					        ;  calling_context :  ( CallEvent . t  *  Location . t )  list  } 
 
			
		
	
		
		
			
				
					
					    |  ISLLatentMemoryError  of  AbductiveDomain . summary 
    |  ISLLatentMemoryError  of  AbductiveDomain . summary 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  type  ' astate  base_error  =  ' astate  AccessResult . error  = 
  type  ' astate  base_error  =  ' astate  AccessResult . error  = 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -622,7 +627,7 @@ let apply_callee tenv ~caller_proc_desc callee_pname call_loc callee_exec_state
 
			
		
	
		
		
			
				
					
					    with 
    with 
 
			
		
	
		
		
			
				
					
					    |  ( Sat  ( Error  _ )  |  Unsat )  as  path_result  -> 
    |  ( Sat  ( Error  _ )  |  Unsat )  as  path_result  -> 
 
			
		
	
		
		
			
				
					
					        path_result 
        path_result 
 
			
		
	
		
		
			
				
					
					    |  Sat  ( Ok  ( post ,  return_val_opt )  -> 
    |  Sat  ( Ok  ( post ,  return_val_opt , subst  ))  -> 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					        let  event  =  ValueHistory . Call  { f =  Call  callee_pname ;  location =  call_loc ;  in_call =  [] }  in 
        let  event  =  ValueHistory . Call  { f =  Call  callee_pname ;  location =  call_loc ;  in_call =  [] }  in 
 
			
		
	
		
		
			
				
					
					        let  post  = 
        let  post  = 
 
			
		
	
		
		
			
				
					
					          match  return_val_opt  with 
          match  return_val_opt  with 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -631,28 +636,31 @@ let apply_callee tenv ~caller_proc_desc callee_pname call_loc callee_exec_state
 
			
		
	
		
		
			
				
					
					          |  None  -> 
          |  None  -> 
 
			
		
	
		
		
			
				
					
					              havoc_id  ( fst  ret )  [ event ]  post 
              havoc_id  ( fst  ret )  [ event ]  post 
 
			
		
	
		
		
			
				
					
					        in 
        in 
 
			
		
	
		
		
			
				
					
					        f  
        f  subst  post
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  in 
  in 
 
			
		
	
		
		
			
				
					
					  let  open  ExecutionDomain  in 
  let  open  ExecutionDomain  in 
 
			
		
	
		
		
			
				
					
					  let  open  SatUnsat . Import  in 
  let  open  SatUnsat . Import  in 
 
			
		
	
		
		
			
				
					
					  match  callee_exec_state  with 
  match  callee_exec_state  with 
 
			
		
	
		
		
			
				
					
					  |  ContinueProgram  astate  -> 
  |  ContinueProgram  astate  -> 
 
			
		
	
		
		
			
				
					
					      map_call_result  ~ is_isl_error_prepost : false  astate  ~ f : ( fun  astate  -> 
      map_call_result  ~ is_isl_error_prepost : false  astate  ~ f : ( fun  _ subst  astate  -> 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					          Sat  ( Ok  ( ContinueProgram  astate ) )  ) 
          Sat  ( Ok  ( ContinueProgram  astate ) )  ) 
 
			
		
	
		
		
			
				
					
					  |  AbortProgram  astate  |  ExitProgram  astate  |  LatentAbortProgram  { astate }  -> 
  |  AbortProgram  astate 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  |  ExitProgram  astate 
 
			
		
	
		
		
			
				
					
					  |  LatentAbortProgram  { astate } 
 
			
		
	
		
		
			
				
					
					  |  LatentInvalidAccess  { astate }  -> 
 
			
		
	
		
		
			
				
					
					      map_call_result  ~ is_isl_error_prepost : false 
      map_call_result  ~ is_isl_error_prepost : false 
 
			
		
	
		
		
			
				
					
					        ( astate  :>  AbductiveDomain . t ) 
        ( astate  :>  AbductiveDomain . t ) 
 
			
		
	
		
		
			
				
					
					        ~ f : ( fun  astate  -> 
        ~ f : ( fun  subst  astate -> 
 
			
				
				
			
		
	
		
		
			
				
					
					          let +  ( astate_summary  :  AbductiveDomain . summary )  = 
          let *  ( astate_summary  :  AbductiveDomain . summary )  = 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					            AbductiveDomain . summary_of_post  tenv  caller_proc_desc  astate 
            AbductiveDomain . summary_of_post  tenv  caller_proc_desc  astate 
 
			
		
	
		
		
			
				
					
					          in 
          in 
 
			
		
	
		
		
			
				
					
					          match  callee_exec_state  with 
          match  callee_exec_state  with 
 
			
		
	
		
		
			
				
					
					          |  ContinueProgram  _  |  ISLLatentMemoryError  _  -> 
          |  ContinueProgram  _  |  ISLLatentMemoryError  _  -> 
 
			
		
	
		
		
			
				
					
					              assert  false 
              assert  false 
 
			
		
	
		
		
			
				
					
					          |  AbortProgram  _  -> 
          |  AbortProgram  _  -> 
 
			
		
	
		
		
			
				
					
					              ( AbortProgram  astate_summary ) 
              Sat (  Ok ( AbortProgram  astate_summary ) ) 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					          |  ExitProgram  _  -> 
          |  ExitProgram  _  -> 
 
			
		
	
		
		
			
				
					
					              ( ExitProgram  astate_summary ) 
              Sat (  Ok ( ExitProgram  astate_summary ) ) 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					          |  LatentAbortProgram  { latent_issue }  ->  ( 
          |  LatentAbortProgram  { latent_issue }  ->  ( 
 
			
		
	
		
		
			
				
					
					              let  latent_issue  = 
              let  latent_issue  = 
 
			
		
	
		
		
			
				
					
					                LatentIssue . add_call  ( CallEvent . Call  callee_pname ,  call_loc )  latent_issue 
                LatentIssue . add_call  ( CallEvent . Call  callee_pname ,  call_loc )  latent_issue 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -660,15 +668,43 @@ let apply_callee tenv ~caller_proc_desc callee_pname call_loc callee_exec_state
 
			
		
	
		
		
			
				
					
					              let  diagnostic  =  LatentIssue . to_diagnostic  latent_issue  in 
              let  diagnostic  =  LatentIssue . to_diagnostic  latent_issue  in 
 
			
		
	
		
		
			
				
					
					              match  LatentIssue . should_report  astate_summary  diagnostic  with 
              match  LatentIssue . should_report  astate_summary  diagnostic  with 
 
			
		
	
		
		
			
				
					
					              |  ` DelayReport  latent_issue  -> 
              |  ` DelayReport  latent_issue  -> 
 
			
		
	
		
		
			
				
					
					                  ( LatentAbortProgram  { astate =  astate_summary ;  latent_issue } ) 
                  Sat (  Ok ( LatentAbortProgram  { astate =  astate_summary ;  latent_issue } ) ) 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					              |  ` ReportNow  -> 
              |  ` ReportNow  -> 
 
			
		
	
		
		
			
				
					
					                  Error 
                  Sat 
 
			
				
				
			
		
	
		
		
			
				
					
					                    ( ReportableError  { diagnostic ;  astate =  ( astate_summary  :>  AbductiveDomain . t ) } )  ) 
                    ( Error 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                       ( ReportableError  { diagnostic ;  astate =  ( astate_summary  :>  AbductiveDomain . t ) } ) ) 
 
			
		
	
		
		
			
				
					
					              ) 
              ) 
 
			
		
	
		
		
			
				
					
					          |  LatentInvalidAccess  { address =  address_callee ;  must_be_valid ;  calling_context }  ->  ( 
 
			
		
	
		
		
			
				
					
					            match  AbstractValue . Map . find_opt  address_callee  subst  with 
 
			
		
	
		
		
			
				
					
					            |  None  -> 
 
			
		
	
		
		
			
				
					
					                (*  the address became unreachable so the bug can never be reached; drop it  *)  Unsat 
 
			
		
	
		
		
			
				
					
					            |  Some  ( address ,  _ history )  ->  ( 
 
			
		
	
		
		
			
				
					
					                let  calling_context  =  ( CallEvent . Call  callee_pname ,  call_loc )  ::  calling_context  in 
 
			
		
	
		
		
			
				
					
					                match 
 
			
		
	
		
		
			
				
					
					                  AbductiveDomain . find_post_cell_opt  address  ( astate_summary  :>  AbductiveDomain . t ) 
 
			
		
	
		
		
			
				
					
					                  | >  Option . bind  ~ f : ( fun  ( _ ,  attrs )  ->  Attributes . get_invalid  attrs ) 
 
			
		
	
		
		
			
				
					
					                with 
 
			
		
	
		
		
			
				
					
					                |  None  -> 
 
			
		
	
		
		
			
				
					
					                    (*  still no proof that the address is invalid  *) 
 
			
		
	
		
		
			
				
					
					                    Sat 
 
			
		
	
		
		
			
				
					
					                      ( Ok 
 
			
		
	
		
		
			
				
					
					                         ( LatentInvalidAccess 
 
			
		
	
		
		
			
				
					
					                            { astate =  astate_summary ;  address ;  must_be_valid ;  calling_context } ) ) 
 
			
		
	
		
		
			
				
					
					                |  Some  ( invalidation ,  invalidation_trace )  -> 
 
			
		
	
		
		
			
				
					
					                    Sat 
 
			
		
	
		
		
			
				
					
					                      ( Error 
 
			
		
	
		
		
			
				
					
					                         ( ReportableError 
 
			
		
	
		
		
			
				
					
					                            {  diagnostic = 
 
			
		
	
		
		
			
				
					
					                                AccessToInvalidAddress 
 
			
		
	
		
		
			
				
					
					                                  {  calling_context 
 
			
		
	
		
		
			
				
					
					                                  ;  invalidation 
 
			
		
	
		
		
			
				
					
					                                  ;  invalidation_trace 
 
			
		
	
		
		
			
				
					
					                                  ;  access_trace =  must_be_valid  } 
 
			
		
	
		
		
			
				
					
					                            ;  astate =  ( astate_summary  :>  AbductiveDomain . t )  } ) )  )  )  ) 
 
			
		
	
		
		
			
				
					
					  |  ISLLatentMemoryError  astate  -> 
  |  ISLLatentMemoryError  astate  -> 
 
			
		
	
		
		
			
				
					
					      map_call_result  ~ is_isl_error_prepost : true 
      map_call_result  ~ is_isl_error_prepost : true 
 
			
		
	
		
		
			
				
					
					        ( astate  :>  AbductiveDomain . t ) 
        ( astate  :>  AbductiveDomain . t ) 
 
			
		
	
		
		
			
				
					
					        ~ f : ( fun  astate  -> 
        ~ f : ( fun  _ subst  astate  -> 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					          let +  astate_summary  =  AbductiveDomain . summary_of_post  tenv  caller_proc_desc  astate  in 
          let +  astate_summary  =  AbductiveDomain . summary_of_post  tenv  caller_proc_desc  astate  in 
 
			
		
	
		
		
			
				
					
					          Ok  ( ISLLatentMemoryError  astate_summary )  ) 
          Ok  ( ISLLatentMemoryError  astate_summary )  )