@ -354,42 +354,6 @@ module PrePost = struct
 
			
		
	
		
		
			
				
					
					  module  AddressSet  =  AbstractValue . Set 
  module  AddressSet  =  AbstractValue . Set 
 
			
		
	
		
		
			
				
					
					  module  AddressMap  =  AbstractValue . Map 
  module  AddressMap  =  AbstractValue . Map 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  type  contradiction  = 
 
			
		
	
		
		
			
				
					
					    |  Aliasing  of 
 
			
		
	
		
		
			
				
					
					        { addr_caller :  AbstractValue . t ;  addr_callee :  AbstractValue . t ;  addr_callee' :  AbstractValue . t } 
 
			
		
	
		
		
			
				
					
					        (* *  raised when the precondition and the current state disagree on the aliasing, i.e. some 
 
			
		
	
		
		
			
				
					
					            addresses  [ callee_addr ]  and  [ callee_addr' ]  that  are  distinct  in  the  pre  are  aliased  to  a 
 
			
		
	
		
		
			
				
					
					            single  address  [ caller_addr ]  in  the  caller's  current  state .  Typically  raised  when 
 
			
		
	
		
		
			
				
					
					            calling  [ foo ( z , z ) ]  where  the  spec  for  [ foo ( x , y ) ]  says  that  [ x ]  and  [ y ]  are  disjoint .  * ) 
 
			
		
	
		
		
			
				
					
					    |  Arithmetic  of 
 
			
		
	
		
		
			
				
					
					        {  addr_caller :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  addr_callee :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  arith_caller :  Arithmetic . t  option 
 
			
		
	
		
		
			
				
					
					        ;  arith_callee :  Arithmetic . t  option  } 
 
			
		
	
		
		
			
				
					
					        (* *  raised when the pre asserts arithmetic facts that are demonstrably false in the caller 
 
			
		
	
		
		
			
				
					
					            state  * ) 
 
			
		
	
		
		
			
				
					
					    |  ArithmeticBo  of 
 
			
		
	
		
		
			
				
					
					        { addr_caller :  AbstractValue . t ;  addr_callee :  AbstractValue . t ;  arith_callee :  Itv . ItvPure . t } 
 
			
		
	
		
		
			
				
					
					        (* *  raised when the pre asserts arithmetic facts that are demonstrably false in the caller 
 
			
		
	
		
		
			
				
					
					            state  * ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  pp_contradiction  fmt  =  function 
 
			
		
	
		
		
			
				
					
					    |  Aliasing  { addr_caller ;  addr_callee ;  addr_callee' }  -> 
 
			
		
	
		
		
			
				
					
					        F . fprintf  fmt  " address %a in caller already bound to %a, not %a "  AbstractValue . pp 
 
			
		
	
		
		
			
				
					
					          addr_caller  AbstractValue . pp  addr_callee'  AbstractValue . pp  addr_callee 
 
			
		
	
		
		
			
				
					
					    |  Arithmetic  { addr_caller ;  addr_callee ;  arith_caller ;  arith_callee }  -> 
 
			
		
	
		
		
			
				
					
					        F . fprintf  fmt  " caller addr %a%a but callee addr %a%a; %a=%a is unsatisfiable " 
 
			
		
	
		
		
			
				
					
					          AbstractValue . pp  addr_caller  ( Pp . option  Arithmetic . pp )  arith_caller  AbstractValue . pp 
 
			
		
	
		
		
			
				
					
					          addr_callee  ( Pp . option  Arithmetic . pp )  arith_callee  AbstractValue . pp  addr_caller 
 
			
		
	
		
		
			
				
					
					          AbstractValue . pp  addr_callee 
 
			
		
	
		
		
			
				
					
					    |  ArithmeticBo  { addr_caller ;  addr_callee ;  arith_callee }  -> 
 
			
		
	
		
		
			
				
					
					        F . fprintf  fmt 
 
			
		
	
		
		
			
				
					
					          " callee addr %a%a is incompatible with caller addr %a's arithmetic constraints " 
 
			
		
	
		
		
			
				
					
					          AbstractValue . pp  addr_callee  Itv . ItvPure . pp  arith_callee  AbstractValue . pp  addr_caller 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  exception  Contradiction  of  contradiction 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  (* *  stuff we carry around when computing the result of applying one pre/post pair  *) 
  (* *  stuff we carry around when computing the result of applying one pre/post pair  *) 
 
			
		
	
		
		
			
				
					
					  type  call_state  = 
  type  call_state  = 
 
			
		
	
		
		
			
				
					
					    {  astate :  t   (* *  caller's abstract state computed so far  *) 
    {  astate :  t   (* *  caller's abstract state computed so far  *) 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -417,6 +381,53 @@ module PrePost = struct
 
			
		
	
		
		
			
				
					
					      rev_subst  AddressSet . pp  visited 
      rev_subst  AddressSet . pp  visited 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  type  contradiction  = 
 
			
		
	
		
		
			
				
					
					    |  Aliasing  of 
 
			
		
	
		
		
			
				
					
					        {  addr_caller :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  addr_callee :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  addr_callee' :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  call_state :  call_state  } 
 
			
		
	
		
		
			
				
					
					        (* *  raised when the precondition and the current state disagree on the aliasing, i.e. some 
 
			
		
	
		
		
			
				
					
					            addresses  [ callee_addr ]  and  [ callee_addr' ]  that  are  distinct  in  the  pre  are  aliased  to  a 
 
			
		
	
		
		
			
				
					
					            single  address  [ caller_addr ]  in  the  caller's  current  state .  Typically  raised  when 
 
			
		
	
		
		
			
				
					
					            calling  [ foo ( z , z ) ]  where  the  spec  for  [ foo ( x , y ) ]  says  that  [ x ]  and  [ y ]  are  disjoint .  * ) 
 
			
		
	
		
		
			
				
					
					    |  Arithmetic  of 
 
			
		
	
		
		
			
				
					
					        {  addr_caller :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  addr_callee :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  arith_caller :  Arithmetic . t  option 
 
			
		
	
		
		
			
				
					
					        ;  arith_callee :  Arithmetic . t  option 
 
			
		
	
		
		
			
				
					
					        ;  call_state :  call_state  } 
 
			
		
	
		
		
			
				
					
					        (* *  raised when the pre asserts arithmetic facts that are demonstrably false in the caller 
 
			
		
	
		
		
			
				
					
					            state  * ) 
 
			
		
	
		
		
			
				
					
					    |  ArithmeticBo  of 
 
			
		
	
		
		
			
				
					
					        {  addr_caller :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  addr_callee :  AbstractValue . t 
 
			
		
	
		
		
			
				
					
					        ;  arith_callee :  Itv . ItvPure . t 
 
			
		
	
		
		
			
				
					
					        ;  call_state :  call_state  } 
 
			
		
	
		
		
			
				
					
					        (* *  raised when the pre asserts arithmetic facts that are demonstrably false in the caller 
 
			
		
	
		
		
			
				
					
					            state  * ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  pp_contradiction  fmt  =  function 
 
			
		
	
		
		
			
				
					
					    |  Aliasing  { addr_caller ;  addr_callee ;  addr_callee' ;  call_state }  -> 
 
			
		
	
		
		
			
				
					
					        F . fprintf  fmt 
 
			
		
	
		
		
			
				
					
					          " address %a in caller already bound to %a, not %a@ \n note: current call state was %a " 
 
			
		
	
		
		
			
				
					
					          AbstractValue . pp  addr_caller  AbstractValue . pp  addr_callee'  AbstractValue . pp  addr_callee 
 
			
		
	
		
		
			
				
					
					          pp_call_state  call_state 
 
			
		
	
		
		
			
				
					
					    |  Arithmetic  { addr_caller ;  addr_callee ;  arith_caller ;  arith_callee ;  call_state }  -> 
 
			
		
	
		
		
			
				
					
					        F . fprintf  fmt 
 
			
		
	
		
		
			
				
					
					          " caller addr %a%a but callee addr %a%a; %a=%a is unsatisfiable@ \n \ 
 
			
		
	
		
		
			
				
					
					           note :  current  call  state  was  % a "  AbstractValue.pp addr_caller (Pp.option Arithmetic.pp) 
 
			
		
	
		
		
			
				
					
					          arith_caller  AbstractValue . pp  addr_callee  ( Pp . option  Arithmetic . pp )  arith_callee 
 
			
		
	
		
		
			
				
					
					          AbstractValue . pp  addr_caller  pp_call_state  call_state  AbstractValue . pp  addr_callee 
 
			
		
	
		
		
			
				
					
					    |  ArithmeticBo  { addr_caller ;  addr_callee ;  arith_callee ;  call_state }  -> 
 
			
		
	
		
		
			
				
					
					        F . fprintf  fmt 
 
			
		
	
		
		
			
				
					
					          " callee addr %a%a is incompatible with caller addr %a's arithmetic constraints@ \n \ 
 
			
		
	
		
		
			
				
					
					           note :  current  call  state  was  % a "  AbstractValue.pp addr_callee Itv.ItvPure.pp arith_callee 
 
			
		
	
		
		
			
				
					
					          AbstractValue . pp  addr_caller  pp_call_state  call_state 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  exception  Contradiction  of  contradiction 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  fold_globals_of_stack  call_loc  stack  call_state  ~ f  = 
  let  fold_globals_of_stack  call_loc  stack  call_state  ~ f  = 
 
			
		
	
		
		
			
				
					
					    Container . fold_result  ~ fold : ( IContainer . fold_of_pervasives_map_fold  ~ fold : BaseStack . fold ) 
    Container . fold_result  ~ fold : ( IContainer . fold_of_pervasives_map_fold  ~ fold : BaseStack . fold ) 
 
			
		
	
		
		
			
				
					
					      stack  ~ init : call_state  ~ f : ( fun  call_state  ( var ,  stack_value )  -> 
      stack  ~ init : call_state  ~ f : ( fun  call_state  ( var ,  stack_value )  -> 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -438,7 +449,7 @@ module PrePost = struct
 
			
		
	
		
		
			
				
					
					    let  addr_caller  =  fst  addr_hist_caller  in 
    let  addr_caller  =  fst  addr_hist_caller  in 
 
			
		
	
		
		
			
				
					
					    (  match  AddressMap . find_opt  addr_caller  call_state . rev_subst  with 
    (  match  AddressMap . find_opt  addr_caller  call_state . rev_subst  with 
 
			
		
	
		
		
			
				
					
					    |  Some  addr_callee'  when  not  ( AbstractValue . equal  addr_callee  addr_callee' )  -> 
    |  Some  addr_callee'  when  not  ( AbstractValue . equal  addr_callee  addr_callee' )  -> 
 
			
		
	
		
		
			
				
					
					        raise  ( Contradiction  ( Aliasing  { addr_caller ;  addr_callee ;  addr_callee' ) ) 
        raise  ( Contradiction  ( Aliasing  { addr_caller ;  addr_callee ;  addr_callee' ; call_state  }) ) 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    |  _  -> 
    |  _  -> 
 
			
		
	
		
		
			
				
					
					        ()  )  ; 
        ()  )  ; 
 
			
		
	
		
		
			
				
					
					    if  AddressSet . mem  addr_callee  call_state . visited  then  ( ` AlreadyVisited ,  call_state ) 
    if  AddressSet . mem  addr_callee  call_state . visited  then  ( ` AlreadyVisited ,  call_state ) 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -559,7 +570,7 @@ module PrePost = struct
 
			
		
	
		
		
			
				
					
					        Bounds . Bound . of_pulse_value  v' 
        Bounds . Bound . of_pulse_value  v' 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  subst_attribute  astate  ~ addr_caller  attr  ~ addr_callee  = 
  let  subst_attribute  call_state  subst_ref astate  ~ addr_caller  attr  ~ addr_callee  = 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					    match  ( attr  :  Attribute . t )  with 
    match  ( attr  :  Attribute . t )  with 
 
			
		
	
		
		
			
				
					
					    |  Arithmetic  ( arith_callee ,  hist )  ->  ( 
    |  Arithmetic  ( arith_callee ,  hist )  ->  ( 
 
			
		
	
		
		
			
				
					
					        let  arith_caller_opt  =  Memory . get_arithmetic  addr_caller  astate  | >  Option . map  ~ f : fst  in 
        let  arith_caller_opt  =  Memory . get_arithmetic  addr_caller  astate  | >  Option . map  ~ f : fst  in 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -573,7 +584,8 @@ module PrePost = struct
 
			
		
	
		
		
			
				
					
					                    {  addr_caller 
                    {  addr_caller 
 
			
		
	
		
		
			
				
					
					                    ;  addr_callee 
                    ;  addr_callee 
 
			
		
	
		
		
			
				
					
					                    ;  arith_caller =  arith_caller_opt 
                    ;  arith_caller =  arith_caller_opt 
 
			
		
	
		
		
			
				
					
					                    ;  arith_callee =  Some  arith_callee  } ) ) 
                    ;  arith_callee =  Some  arith_callee 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					                    ;  call_state  } ) ) 
 
			
		
	
		
		
			
				
					
					        |  Satisfiable  ( Some  abduce_caller ,  _ abduce_callee )  -> 
        |  Satisfiable  ( Some  abduce_caller ,  _ abduce_callee )  -> 
 
			
		
	
		
		
			
				
					
					            Attribute . Arithmetic  ( abduce_caller ,  hist ) 
            Attribute . Arithmetic  ( abduce_caller ,  hist ) 
 
			
		
	
		
		
			
				
					
					        |  Satisfiable  ( None ,  _ )  -> 
        |  Satisfiable  ( None ,  _ )  -> 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -586,7 +598,9 @@ module PrePost = struct
 
			
		
	
		
		
			
				
					
					      |  NonBottom  itv'  -> 
      |  NonBottom  itv'  -> 
 
			
		
	
		
		
			
				
					
					          Attribute . BoItv  itv' 
          Attribute . BoItv  itv' 
 
			
		
	
		
		
			
				
					
					      |  Bottom  -> 
      |  Bottom  -> 
 
			
		
	
		
		
			
				
					
					          raise  ( Contradiction  ( ArithmeticBo  { addr_callee ;  addr_caller ;  arith_callee =  itv } ) )  ) 
          raise 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					            ( Contradiction  ( ArithmeticBo  { addr_callee ;  addr_caller ;  arith_callee =  itv ;  call_state } ) ) 
 
			
		
	
		
		
			
				
					
					      ) 
 
			
		
	
		
		
			
				
					
					    |  AddressOfCppTemporary  _ 
    |  AddressOfCppTemporary  _ 
 
			
		
	
		
		
			
				
					
					    |  AddressOfStackVariable  _ 
    |  AddressOfStackVariable  _ 
 
			
		
	
		
		
			
				
					
					    |  Closure  _ 
    |  Closure  _ 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -620,7 +634,9 @@ module PrePost = struct
 
			
		
	
		
		
			
				
					
					    let  subst_ref  =  ref  call_state . subst  in 
    let  subst_ref  =  ref  call_state . subst  in 
 
			
		
	
		
		
			
				
					
					    let  attrs  = 
    let  attrs  = 
 
			
		
	
		
		
			
				
					
					      Attributes . map  attrs  ~ f : ( fun  attr  -> 
      Attributes . map  attrs  ~ f : ( fun  attr  -> 
 
			
		
	
		
		
			
				
					
					          let  attr  =  subst_attribute  subst_ref  call_state . astate  ~ addr_callee  ~ addr_caller  attr  in 
          let  attr  = 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					            subst_attribute  call_state  subst_ref  call_state . astate  ~ addr_callee  ~ addr_caller  attr 
 
			
		
	
		
		
			
				
					
					          in 
 
			
		
	
		
		
			
				
					
					          add_call_to_attribute  attr  ) 
          add_call_to_attribute  attr  ) 
 
			
		
	
		
		
			
				
					
					    in 
    in 
 
			
		
	
		
		
			
				
					
					    ( ! subst_ref ,  attrs ) 
    ( ! subst_ref ,  attrs )