@ -20,10 +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 }
| ISLLatentMemoryError of ' abductive_domain_t
| ISLLatentMemoryError of AbductiveDomain . summary
type ' astate base_error = ' astate AccessResult . error =
type ' astate base_error = ' astate AccessResult . error =
| ReportableError of { astate : ' astate ; diagnostic : Diagnostic . t }
| ReportableError of { astate : ' astate ; diagnostic : Diagnostic . t }
| ISLError of ' astate
include IResult . Let_syntax
include IResult . Let_syntax
@ -63,33 +64,31 @@ let check_addr_access access_mode location (address, history) astate =
let check_and_abduce_addr_access_isl access_mode location ( address , history ) ? ( null_noop = false )
let check_and_abduce_addr_access_isl access_mode location ( address , history ) ? ( null_noop = false )
astate =
astate =
let access_trace = Trace . Immediate { location ; history } in
let access_trace = Trace . Immediate { location ; history } in
match AddressAttributes . check_valid_isl access_trace address ~ null_noop astate with
AddressAttributes . check_valid_isl access_trace address ~ null_noop astate
| Error ( invalidation , invalidation_trace , astate ) ->
| > List . map ~ f : ( function
[ Error
| Error ( ` InvalidAccess ( invalidation , invalidation_trace , astate ) ) ->
( ReportableError
Error
{ diagnostic =
( ReportableError
Diagnostic . AccessToInvalidAddress
{ diagnostic =
{ calling_context = [] ; invalidation ; invalidation_trace ; access_trace }
Diagnostic . AccessToInvalidAddress
; astate } ) ]
{ calling_context = [] ; invalidation ; invalidation_trace ; access_trace }
| Ok astates -> (
; astate } )
match access_mode with
| Error ( ` ISLError astate ) ->
| Read ->
Error ( ISLError astate )
List . map astates ~ f : ( fun astate ->
| Ok astate -> (
AddressAttributes . check_initialized access_trace address astate
match access_mode with
| > Result . map_error ~ f : ( fun () ->
| Read ->
ReportableError
AddressAttributes . check_initialized access_trace address astate
{ diagnostic =
| > Result . map_error ~ f : ( fun () ->
Diagnostic . ReadUninitializedValue { calling_context = [] ; trace = access_trace }
ReportableError
; astate = AbductiveDomain . set_isl_status ISLError astate } ) )
{ diagnostic =
| Write ->
Diagnostic . ReadUninitializedValue
List . map astates ~ f : ( fun astate ->
{ calling_context = [] ; trace = access_trace }
match astate . AbductiveDomain . isl_status with
; astate } )
| ISLOk ->
| Write ->
Ok ( AbductiveDomain . initialize address astate )
Ok ( AbductiveDomain . initialize address astate )
| ISLError ->
| NoAccess ->
Ok astate )
Ok astate ) )
| NoAccess ->
List . map ~ f : ( fun astate -> Ok astate ) astates )
module Closures = struct
module Closures = struct
@ -175,11 +174,7 @@ let eval_access_biad_isl mode location addr_hist access astate =
let map_ok addr_hist access results =
let map_ok addr_hist access results =
List . map results ~ f : ( fun result ->
List . map results ~ f : ( fun result ->
let + astate = result in
let + astate = result in
match astate . AbductiveDomain . isl_status with
Memory . eval_edge addr_hist access astate )
| ISLOk ->
Memory . eval_edge addr_hist access astate
| ISLError ->
( astate , addr_hist ) )
in
in
let results = check_and_abduce_addr_access_isl mode location addr_hist astate in
let results = check_and_abduce_addr_access_isl mode location addr_hist astate in
map_ok addr_hist access results
map_ok addr_hist access results
@ -290,14 +285,10 @@ let eval_structure_isl mode loc exp astate =
let eval_deref_biad_isl location access addr_hist astate =
let eval_deref_biad_isl location access addr_hist astate =
let astates = check_and_abduce_addr_access_isl Read location addr_hist astate in
check_and_abduce_addr_access_isl Read location addr_hist astate
List . map astates ~ f : ( fun astate ->
| > List . map ~ f : ( fun result ->
let + astate = astate in
let + astate = result in
match astate . AbductiveDomain . isl_status with
Memory . eval_edge addr_hist access astate )
| ISLOk ->
Memory . eval_edge addr_hist access astate
| ISLError ->
( astate , addr_hist ) )
let eval_deref_isl location exp astate =
let eval_deref_isl location exp astate =
@ -307,12 +298,8 @@ let eval_deref_isl location exp astate =
else [ eval_deref location exp astate ]
else [ eval_deref location exp astate ]
in
in
List . concat_map ls_astate_addr_hist ~ f : ( fun result ->
List . concat_map ls_astate_addr_hist ~ f : ( fun result ->
let < * > ( ( astate , _ ) as astate_addr ) = result in
let < * > astate_addr = result in
match astate . AbductiveDomain . isl_status with
eval_deref_function astate_addr )
| ISLOk ->
eval_deref_function astate_addr
| ISLError ->
[ Ok astate_addr ] )
let realloc_pvar tenv pvar typ location astate =
let realloc_pvar tenv pvar typ location astate =
@ -338,14 +325,10 @@ let write_access location addr_trace_ref access addr_trace_obj astate =
let write_access_biad_isl location addr_trace_ref access addr_trace_obj astate =
let write_access_biad_isl location addr_trace_ref access addr_trace_obj astate =
check_and_abduce_addr_access_isl Write location addr_trace_ref astate
let astates = check_and_abduce_addr_access_isl Write location addr_trace_ref astate in
| > List . map ~ f : ( fun result ->
List . map astates ~ f : ( fun result ->
let + astate = result in
let + astate = result in
match astate . AbductiveDomain . isl_status with
Memory . add_edge addr_trace_ref access addr_trace_obj location astate )
| ISLOk ->
Memory . add_edge addr_trace_ref access addr_trace_obj location astate
| ISLError ->
astate )
let write_deref location ~ ref : addr_trace_ref ~ obj : addr_trace_obj astate =
let write_deref location ~ ref : addr_trace_ref ~ obj : addr_trace_obj astate =
@ -386,11 +369,7 @@ let invalidate_biad_isl location cause (address, history) astate =
check_and_abduce_addr_access_isl NoAccess location ( address , history ) ~ null_noop : true astate
check_and_abduce_addr_access_isl NoAccess location ( address , history ) ~ null_noop : true astate
| > List . map ~ f : ( fun result ->
| > List . map ~ f : ( fun result ->
let + astate = result in
let + astate = result in
match astate . AbductiveDomain . isl_status with
AddressAttributes . invalidate ( address , history ) cause location astate )
| ISLOk ->
AddressAttributes . invalidate ( address , history ) cause location astate
| ISLError ->
astate )
let invalidate_access location cause ref_addr_hist access astate =
let invalidate_access location cause ref_addr_hist access astate =
@ -636,10 +615,10 @@ let unknown_call tenv call_loc reason ~ret ~actuals ~formals_opt astate =
let apply_callee tenv ~ caller_proc_desc callee_pname call_loc callee_exec_state ~ ret
let apply_callee tenv ~ caller_proc_desc callee_pname call_loc callee_exec_state ~ ret
~ captured_vars_with_actuals ~ formals ~ actuals astate =
~ captured_vars_with_actuals ~ formals ~ actuals astate =
let map_call_result callee_prepost ~ f =
let map_call_result ~ is_isl_error_prepost callee_prepost ~ f =
match
match
PulseInterproc . apply_prepost callee_pname call_loc ~ callee_prepost ~ captured_vars_with_actuals
PulseInterproc . apply_prepost ~ is_isl_error_prepost callee_pname call_loc ~ callee_prepost
~ formals ~ actuals astate
~ captured_vars_with_actuals ~ formals ~ actuals astate
with
with
| ( Sat ( Error _ ) | Unsat ) as path_result ->
| ( Sat ( Error _ ) | Unsat ) as path_result ->
path_result
path_result
@ -658,11 +637,10 @@ let apply_callee tenv ~caller_proc_desc callee_pname call_loc callee_exec_state
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 astate ~ f : ( fun astate -> Sat ( Ok ( ContinueProgram astate ) ) )
map_call_result ~ is_isl_error_prepost : false astate ~ f : ( fun astate ->
| ISLLatentMemoryError astate ->
Sat ( Ok ( ContinueProgram astate ) ) )
map_call_result astate ~ f : ( fun astate -> Sat ( Ok ( ISLLatentMemoryError astate ) ) )
| AbortProgram astate | ExitProgram astate | LatentAbortProgram { astate } ->
| AbortProgram astate | ExitProgram astate | LatentAbortProgram { astate } ->
map_call_result
map_call_result ~ is_isl_error_prepost : false
( astate :> AbductiveDomain . t )
( astate :> AbductiveDomain . t )
~ f : ( fun astate ->
~ f : ( fun 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
@ -685,7 +663,15 @@ let apply_callee tenv ~caller_proc_desc callee_pname call_loc callee_exec_state
| ` DelayReport ( astate , latent_issue ) ->
| ` DelayReport ( astate , latent_issue ) ->
Ok ( LatentAbortProgram { astate ; latent_issue } )
Ok ( LatentAbortProgram { astate ; latent_issue } )
| ` ReportNow ( astate , diagnostic ) ->
| ` ReportNow ( astate , diagnostic ) ->
Error ( ReportableError { diagnostic ; astate = ( astate :> AbductiveDomain . t ) } ) ) )
Error ( ReportableError { diagnostic ; astate = ( astate :> AbductiveDomain . t ) } )
| ` ISLDelay astate ->
Error ( ISLError ( astate :> AbductiveDomain . t ) ) ) )
| ISLLatentMemoryError astate ->
map_call_result ~ is_isl_error_prepost : true
( astate :> AbductiveDomain . t )
~ f : ( fun astate ->
let + astate_summary = AbductiveDomain . summary_of_post tenv caller_proc_desc astate in
Ok ( ISLLatentMemoryError astate_summary ) )
let get_captured_actuals location ~ captured_vars ~ actual_closure astate =
let get_captured_actuals location ~ captured_vars ~ actual_closure astate =