@ -376,10 +376,12 @@ module Diagnostic = struct
 
			
		
	
		
			
				
					  let  get_issue_type  ( AccessToInvalidAddress  _ )  =  IssueType . use_after_lifetime 
 
			
		
	
		
			
				
					end  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					type  ' a  access_result  =  ( ' a ,  Diagnostic . t )  result  
			
		
	
		
			
				
					(* *  operations on the domain  *)  
			
		
	
		
			
				
					module  Operations  =  struct  
			
		
	
		
			
				
					  type  ' a  access_result  =  ( ' a ,  Diagnostic . t )  result 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					(* *  Check that the address is not known to be invalid  *)  
			
		
	
		
			
				
					let  check_addr_access  actor  address  astate  =  
			
		
	
		
			
				
					   (* *  Check that the address is not known to be invalid  *)  
			
		
	
		
			
				
					   let  check_addr_access  actor  address  astate  =  
			
		
	
		
			
				
					    match  InvalidAddressesDomain . get_invalidation  address  astate . invalids  with 
 
			
		
	
		
			
				
					    |  Some  invalidated_at  -> 
 
			
		
	
		
			
				
					        Error  ( Diagnostic . AccessToInvalidAddress  { invalidated_at ;  accessed_by =  actor ;  address } ) 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -387,11 +389,11 @@ let check_addr_access actor address astate =
 
			
		
	
		
			
				
					        Ok  astate 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					(* *  Walk the heap starting from [addr] and following [path]. Stop either at the element before last  
			
		
	
		
			
				
					   (* *  Walk the heap starting from [addr] and following [path]. Stop either at the element before last  
			
		
	
		
			
				
					   and  return  [ new_addr ]  if  [ overwrite_last ]  is  [ Some  new_addr ] ,  or  go  until  the  end  of  the  path  if  it 
 
			
		
	
		
			
				
					   is  [ None ] .  Create  more  addresses  into  the  heap  as  needed  to  follow  the  [ path ] .  Check  that  each 
 
			
		
	
		
			
				
					   address  reached  is  valid .  * ) 
 
			
		
	
		
			
				
					let  rec  walk  actor  ~ overwrite_last  addr  path  astate  =  
			
		
	
		
			
				
					   let  rec  walk  actor  ~ overwrite_last  addr  path  astate  =  
			
		
	
		
			
				
					    match  ( path ,  overwrite_last )  with 
 
			
		
	
		
			
				
					    |  [] ,  None  -> 
 
			
		
	
		
			
				
					        Ok  ( astate ,  addr ) 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -415,8 +417,8 @@ let rec walk actor ~overwrite_last addr path astate =
 
			
		
	
		
			
				
					            walk  actor  ~ overwrite_last  addr'  path  astate  ) 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					(* *  add addresses to the state to give a address to the destination of the given access path  *)  
			
		
	
		
			
				
					let  walk_access_expr  ? overwrite_last  astate  access_expr  location  =  
			
		
	
		
			
				
					   (* *  add addresses to the state to give a address to the destination of the given access path  *)  
			
		
	
		
			
				
					   let  walk_access_expr  ? overwrite_last  astate  access_expr  location  =  
			
		
	
		
			
				
					    let  ( access_var ,  _ ) ,  access_list  =  AccessExpression . to_access_path  access_expr  in 
 
			
		
	
		
			
				
					    match  ( overwrite_last ,  access_list )  with 
 
			
		
	
		
			
				
					    |  Some  new_addr ,  []  -> 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -436,50 +438,51 @@ let walk_access_expr ?overwrite_last astate access_expr location =
 
			
		
	
		
			
				
					        walk  actor  ~ overwrite_last  base_addr  access_list  astate 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					(* *  Use the stack and heap to walk the access path represented by the given expression down to an  
			
		
	
		
			
				
					   (* *  Use the stack and heap to walk the access path represented by the given expression down to an  
			
		
	
		
			
				
					    abstract  address  representing  what  the  expression  points  to . 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    Return  an  error  state  if  it  traverses  some  known  invalid  address  or  if  the  end  destination  is 
 
			
		
	
		
			
				
					    known  to  be  invalid .  * ) 
 
			
		
	
		
			
				
					let  materialize_address  astate  access_expr  =  walk_access_expr  astate  access_expr  
			
		
	
		
			
				
					   let  materialize_address  astate  access_expr  =  walk_access_expr  astate  access_expr  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					(* *  Use the stack and heap to walk the access path represented by the given expression down to an  
			
		
	
		
			
				
					   (* *  Use the stack and heap to walk the access path represented by the given expression down to an  
			
		
	
		
			
				
					    abstract  address  representing  what  the  expression  points  to ,  and  replace  that  with  the  given 
 
			
		
	
		
			
				
					    address . 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    Return  an  error  state  if  it  traverses  some  known  invalid  address .  * ) 
 
			
		
	
		
			
				
					let  overwrite_address  astate  access_expr  new_addr  =  
			
		
	
		
			
				
					   let  overwrite_address  astate  access_expr  new_addr  =  
			
		
	
		
			
				
					    walk_access_expr  ~ overwrite_last : new_addr  astate  access_expr 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					(* *  Add the given address to the set of know invalid addresses.  *)  
			
		
	
		
			
				
					let  mark_invalid  actor  address  astate  =  
			
		
	
		
			
				
					   (* *  Add the given address to the set of know invalid addresses.  *)  
			
		
	
		
			
				
					   let  mark_invalid  actor  address  astate  =  
			
		
	
		
			
				
					    { astate  with  invalids =  InvalidAddressesDomain . add  address  actor  astate . invalids } 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					let  read  location  access_expr  astate  =  
			
		
	
		
			
				
					   let  read  location  access_expr  astate  =  
			
		
	
		
			
				
					    materialize_address  astate  access_expr  location 
 
			
		
	
		
			
				
					    > > =  fun  ( astate ,  addr )  -> 
 
			
		
	
		
			
				
					    let  actor  =  { access_expr ;  location }  in 
 
			
		
	
		
			
				
					    check_addr_access  actor  addr  astate  > > |  fun  astate  ->  ( astate ,  addr ) 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					let  read_all  location  access_exprs  astate  =  
			
		
	
		
			
				
					   let  read_all  location  access_exprs  astate  =  
			
		
	
		
			
				
					    List . fold_result  access_exprs  ~ init : astate  ~ f : ( fun  astate  access_expr  -> 
 
			
		
	
		
			
				
					        read  location  access_expr  astate  > > |  fst  ) 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					let  write  location  access_expr  addr  astate  =  
			
		
	
		
			
				
					   let  write  location  access_expr  addr  astate  =  
			
		
	
		
			
				
					    overwrite_address  astate  access_expr  addr  location  > > |  fun  ( astate ,  _ )  ->  astate 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					let  havoc  var  astate  =  { astate  with  stack =  AliasingDomain . remove  var  astate . stack }  
			
		
	
		
			
				
					   let  havoc  var  astate  =  { astate  with  stack =  AliasingDomain . remove  var  astate . stack }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					let  invalidate  location  access_expr  astate  =  
			
		
	
		
			
				
					   let  invalidate  location  access_expr  astate  =  
			
		
	
		
			
				
					    materialize_address  astate  access_expr  location 
 
			
		
	
		
			
				
					    > > =  fun  ( astate ,  addr )  -> 
 
			
		
	
		
			
				
					    let  actor  =  { access_expr ;  location }  in 
 
			
		
	
		
			
				
					    check_addr_access  actor  addr  astate  > > |  mark_invalid  actor  addr 
 
			
		
	
		
			
				
					
  
			
		
	
		
			
				
					end  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					include  Domain  
			
		
	
		
			
				
					include  Operations