[pulse] rename "PulseArithmetic" to "PulseCItv"

Summary: In preparation for PulseArithmetic to be something else.

Reviewed By: ezgicicek

Differential Revision: D20393928

fbshipit-source-id: d93131e12
master
Jules Villard 5 years ago committed by Facebook GitHub Bot
parent 8a99f4b3bb
commit 7861752bf3

@ -215,9 +215,7 @@ module AddressAttributes = struct
BaseAddressAttributes.get_closure_proc_name addr (astate.post :> base_domain).attrs BaseAddressAttributes.get_closure_proc_name addr (astate.post :> base_domain).attrs
let get_arithmetic addr astate = let get_citv addr astate = BaseAddressAttributes.get_citv addr (astate.post :> base_domain).attrs
BaseAddressAttributes.get_arithmetic addr (astate.post :> base_domain).attrs
let get_bo_itv addr astate = let get_bo_itv addr astate =
BaseAddressAttributes.get_bo_itv addr (astate.post :> base_domain).attrs BaseAddressAttributes.get_bo_itv addr (astate.post :> base_domain).attrs
@ -451,11 +449,11 @@ module PrePost = struct
addresses [callee_addr] and [callee_addr'] that are distinct in the pre are aliased to a 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 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. *) calling [foo(z,z)] where the spec for [foo(x,y)] says that [x] and [y] are disjoint. *)
| Arithmetic of | CItv of
{ addr_caller: AbstractValue.t { addr_caller: AbstractValue.t
; addr_callee: AbstractValue.t ; addr_callee: AbstractValue.t
; arith_caller: Arithmetic.t option ; arith_caller: CItv.t option
; arith_callee: Arithmetic.t option ; arith_callee: CItv.t option
; call_state: call_state } ; call_state: call_state }
(** raised when the pre asserts arithmetic facts that are demonstrably false in the caller (** raised when the pre asserts arithmetic facts that are demonstrably false in the caller
state *) state *)
@ -475,11 +473,11 @@ module PrePost = struct
"address %a in caller already bound to %a, not %a@\nnote: current call state was %a" "address %a in caller already bound to %a, not %a@\nnote: current call state was %a"
AbstractValue.pp addr_caller AbstractValue.pp addr_callee' AbstractValue.pp addr_callee AbstractValue.pp addr_caller AbstractValue.pp addr_callee' AbstractValue.pp addr_callee
pp_call_state call_state pp_call_state call_state
| Arithmetic {addr_caller; addr_callee; arith_caller; arith_callee; call_state} -> | CItv {addr_caller; addr_callee; arith_caller; arith_callee; call_state} ->
F.fprintf fmt F.fprintf fmt
"caller addr %a%a but callee addr %a%a; %a=%a is unsatisfiable@\n\ "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) note: current call state was %a" AbstractValue.pp addr_caller (Pp.option CItv.pp)
arith_caller AbstractValue.pp addr_callee (Pp.option Arithmetic.pp) arith_callee arith_caller AbstractValue.pp addr_callee (Pp.option CItv.pp) arith_callee
AbstractValue.pp addr_caller pp_call_state call_state AbstractValue.pp addr_callee AbstractValue.pp addr_caller pp_call_state call_state AbstractValue.pp addr_callee
| ArithmeticBo {addr_caller; addr_callee; arith_callee; call_state} -> | ArithmeticBo {addr_caller; addr_callee; arith_callee; call_state} ->
F.fprintf fmt F.fprintf fmt
@ -633,24 +631,20 @@ module PrePost = struct
let subst_attribute call_state subst_ref 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) -> ( | CItv (arith_callee, hist) -> (
let arith_caller_opt = let arith_caller_opt = AddressAttributes.get_citv addr_caller astate |> Option.map ~f:fst in
AddressAttributes.get_arithmetic addr_caller astate |> Option.map ~f:fst match CItv.abduce_binop_is_true ~negated:false Eq arith_caller_opt (Some arith_callee) with
in
match
Arithmetic.abduce_binop_is_true ~negated:false Eq arith_caller_opt (Some arith_callee)
with
| Unsatisfiable -> | Unsatisfiable ->
raise raise
(Contradiction (Contradiction
(Arithmetic (CItv
{ 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 })) ; call_state }))
| Satisfiable (Some abduce_caller, _abduce_callee) -> | Satisfiable (Some abduce_caller, _abduce_callee) ->
Attribute.Arithmetic (abduce_caller, hist) Attribute.CItv (abduce_caller, hist)
| Satisfiable (None, _) -> | Satisfiable (None, _) ->
attr ) attr )
| BoItv itv -> ( | BoItv itv -> (
@ -683,9 +677,8 @@ module PrePost = struct
| Invalid (invalidation, trace) -> | Invalid (invalidation, trace) ->
Attribute.Invalid Attribute.Invalid
(invalidation, add_call_to_trace proc_name call_location caller_history trace) (invalidation, add_call_to_trace proc_name call_location caller_history trace)
| Arithmetic (arith, trace) -> | CItv (arith, trace) ->
Attribute.Arithmetic Attribute.CItv (arith, add_call_to_trace proc_name call_location caller_history trace)
(arith, add_call_to_trace proc_name call_location caller_history trace)
| Allocated trace -> | Allocated trace ->
Attribute.Allocated (add_call_to_trace proc_name call_location caller_history trace) Attribute.Allocated (add_call_to_trace proc_name call_location caller_history trace)
| AddressOfCppTemporary _ | AddressOfCppTemporary _

@ -84,7 +84,7 @@ module AddressAttributes : sig
val std_vector_reserve : AbstractValue.t -> t -> t val std_vector_reserve : AbstractValue.t -> t -> t
val get_arithmetic : AbstractValue.t -> t -> (Arithmetic.t * Trace.t) option val get_citv : AbstractValue.t -> t -> (CItv.t * Trace.t) option
val get_bo_itv : AbstractValue.t -> t -> Itv.ItvPure.t val get_bo_itv : AbstractValue.t -> t -> Itv.ItvPure.t

@ -6,7 +6,7 @@
*) *)
open! IStd open! IStd
module F = Format module F = Format
module Arithmetic = PulseArithmetic module CItv = PulseCItv
module Invalidation = PulseInvalidation module Invalidation = PulseInvalidation
module Trace = PulseTrace module Trace = PulseTrace
module ValueHistory = PulseValueHistory module ValueHistory = PulseValueHistory
@ -29,7 +29,7 @@ module Attribute = struct
| AddressOfCppTemporary of Var.t * ValueHistory.t | AddressOfCppTemporary of Var.t * ValueHistory.t
| AddressOfStackVariable of Var.t * Location.t * ValueHistory.t | AddressOfStackVariable of Var.t * Location.t * ValueHistory.t
| Allocated of Trace.t | Allocated of Trace.t
| Arithmetic of Arithmetic.t * Trace.t | CItv of CItv.t * Trace.t
| BoItv of Itv.ItvPure.t | BoItv of Itv.ItvPure.t
| Closure of Procname.t | Closure of Procname.t
| Invalid of Invalidation.t * Trace.t | Invalid of Invalidation.t * Trace.t
@ -63,7 +63,7 @@ module Attribute = struct
let std_vector_reserve_rank = Variants.to_rank StdVectorReserve let std_vector_reserve_rank = Variants.to_rank StdVectorReserve
let const_rank = Variants.to_rank (Arithmetic (Arithmetic.equal_to IntLit.zero, dummy_trace)) let const_rank = Variants.to_rank (CItv (CItv.equal_to IntLit.zero, dummy_trace))
let bo_itv_rank = Variants.to_rank (BoItv Itv.ItvPure.zero) let bo_itv_rank = Variants.to_rank (BoItv Itv.ItvPure.zero)
@ -82,8 +82,8 @@ module Attribute = struct
F.fprintf f "BoItv (%a)" Itv.ItvPure.pp bo_itv F.fprintf f "BoItv (%a)" Itv.ItvPure.pp bo_itv
| Closure pname -> | Closure pname ->
Procname.pp f pname Procname.pp f pname
| Arithmetic (phi, trace) -> | CItv (phi, trace) ->
F.fprintf f "Arith %a" (Trace.pp ~pp_immediate:(fun fmt -> Arithmetic.pp fmt phi)) trace F.fprintf f "Arith %a" (Trace.pp ~pp_immediate:(fun fmt -> CItv.pp fmt phi)) trace
| Invalid (invalidation, trace) -> | Invalid (invalidation, trace) ->
F.fprintf f "Invalid %a" F.fprintf f "Invalid %a"
(Trace.pp ~pp_immediate:(fun fmt -> Invalidation.pp fmt invalidation)) (Trace.pp ~pp_immediate:(fun fmt -> Invalidation.pp fmt invalidation))
@ -143,10 +143,10 @@ module Attributes = struct
|| Option.is_some (Set.find_rank attrs Attribute.invalid_rank) || Option.is_some (Set.find_rank attrs Attribute.invalid_rank)
let get_arithmetic attrs = let get_citv attrs =
Set.find_rank attrs Attribute.const_rank Set.find_rank attrs Attribute.const_rank
|> Option.map ~f:(fun attr -> |> Option.map ~f:(fun attr ->
let[@warning "-8"] (Attribute.Arithmetic (a, trace)) = attr in let[@warning "-8"] (Attribute.CItv (a, trace)) = attr in
(a, trace) ) (a, trace) )
@ -163,7 +163,7 @@ end
include Attribute include Attribute
let is_suitable_for_pre = function let is_suitable_for_pre = function
| Arithmetic _ | BoItv _ | MustBeValid _ -> | CItv _ | BoItv _ | MustBeValid _ ->
true true
| AddressOfCppTemporary _ | AddressOfCppTemporary _
| AddressOfStackVariable _ | AddressOfStackVariable _

@ -6,7 +6,7 @@
*) *)
open! IStd open! IStd
module F = Format module F = Format
module Arithmetic = PulseArithmetic module CItv = PulseCItv
module Invalidation = PulseInvalidation module Invalidation = PulseInvalidation
module Trace = PulseTrace module Trace = PulseTrace
module ValueHistory = PulseValueHistory module ValueHistory = PulseValueHistory
@ -15,7 +15,7 @@ type t =
| AddressOfCppTemporary of Var.t * ValueHistory.t | AddressOfCppTemporary of Var.t * ValueHistory.t
| AddressOfStackVariable of Var.t * Location.t * ValueHistory.t | AddressOfStackVariable of Var.t * Location.t * ValueHistory.t
| Allocated of Trace.t | Allocated of Trace.t
| Arithmetic of Arithmetic.t * Trace.t | CItv of CItv.t * Trace.t
| BoItv of Itv.ItvPure.t | BoItv of Itv.ItvPure.t
| Closure of Procname.t | Closure of Procname.t
| Invalid of Invalidation.t * Trace.t | Invalid of Invalidation.t * Trace.t
@ -35,7 +35,7 @@ module Attributes : sig
val get_closure_proc_name : t -> Procname.t option val get_closure_proc_name : t -> Procname.t option
val get_arithmetic : t -> (Arithmetic.t * Trace.t) option val get_citv : t -> (CItv.t * Trace.t) option
val get_bo_itv : t -> Itv.ItvPure.t option val get_bo_itv : t -> Itv.ItvPure.t option

@ -71,7 +71,7 @@ let get_attribute getter address attrs =
let get_closure_proc_name = get_attribute Attributes.get_closure_proc_name let get_closure_proc_name = get_attribute Attributes.get_closure_proc_name
let get_arithmetic = get_attribute Attributes.get_arithmetic let get_citv = get_attribute Attributes.get_citv
let get_bo_itv v memory = let get_bo_itv v memory =
match get_attribute Attributes.get_bo_itv v memory with match get_attribute Attributes.get_bo_itv v memory with

@ -30,7 +30,7 @@ val invalidate : AbstractValue.t * ValueHistory.t -> Invalidation.t -> Location.
val get_closure_proc_name : AbstractValue.t -> t -> Procname.t option val get_closure_proc_name : AbstractValue.t -> t -> Procname.t option
val get_arithmetic : AbstractValue.t -> t -> (Arithmetic.t * Trace.t) option val get_citv : AbstractValue.t -> t -> (CItv.t * Trace.t) option
val get_bo_itv : AbstractValue.t -> t -> Itv.ItvPure.t val get_bo_itv : AbstractValue.t -> t -> Itv.ItvPure.t

@ -9,10 +9,10 @@ open! IStd
(** Basic Pulse modules that are safe to use in any module *) (** Basic Pulse modules that are safe to use in any module *)
module AbstractValue = PulseAbstractValue module AbstractValue = PulseAbstractValue
module Arithmetic = PulseArithmetic
module Attribute = PulseAttribute module Attribute = PulseAttribute
module Attributes = PulseAttribute.Attributes module Attributes = PulseAttribute.Attributes
module CallEvent = PulseCallEvent module CallEvent = PulseCallEvent
module CItv = PulseCItv
module Diagnostic = PulseDiagnostic module Diagnostic = PulseDiagnostic
module Invalidation = PulseInvalidation module Invalidation = PulseInvalidation
module Trace = PulseTrace module Trace = PulseTrace

@ -5,8 +5,6 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*) *)
[@@@ocamlformat "parse-docstrings = false"]
open! IStd open! IStd
module F = Format module F = Format
module L = Logging module L = Logging
@ -112,8 +110,8 @@ end
module Unsafe : sig module Unsafe : sig
type t = private type t = private
| Between of Bound.t * Bound.t (** we write [b1,b2] for these *) | Between of Bound.t * Bound.t (** we write \[b1,b2\] for these *)
| Outside of IntLit.t * IntLit.t (** we write i1][i2 for these *) | Outside of IntLit.t * IntLit.t (** we write i1\]\[i2 for these *)
[@@deriving compare] [@@deriving compare]
val between : Bound.t -> Bound.t -> t val between : Bound.t -> Bound.t -> t
@ -177,7 +175,7 @@ let has_empty_intersection a1 a2 =
| Between (lower1, upper1), Between (lower2, upper2) -> | Between (lower1, upper1), Between (lower2, upper2) ->
Bound.lt upper1 lower2 || Bound.lt upper2 lower1 Bound.lt upper1 lower2 || Bound.lt upper2 lower1
| Between (lower1, upper1), Outside (l2, u2) | Outside (l2, u2), Between (lower1, upper1) -> | Between (lower1, upper1), Outside (l2, u2) | Outside (l2, u2), Between (lower1, upper1) ->
(* is [l1, u1] inside [l2, u2]? *) (* is \[l1, u1\] inside \[l2, u2\]? *)
Bound.le (Int l2) lower1 && Bound.ge (Int u2) upper1 Bound.le (Int l2) lower1 && Bound.ge (Int u2) upper1
@ -235,22 +233,22 @@ let rec abduce_eq (a1 : t) (a2 : t) =
| Outside (l1, u1), Outside (l2, u2) -> | Outside (l1, u1), Outside (l2, u2) ->
(* ∃x. (x<l1 x>u1)(x<l2 x>u2) ∧ li<=ui*) (* ∃x. (x<l1 x>u1)(x<l2 x>u2) ∧ li<=ui*)
(* all the possible cases: (* all the possible cases:
x: --------[ ]--------- x: --------\[ \]---------
y: -----[ ]-------- y: -----\[ \]--------
x: ---[ ]------ x: ---\[ \]------
y: -----[ ]-------- y: -----\[ \]--------
x: ---[ ]---------- x: ---\[ \]----------
y: -----[ ]-------- y: -----\[ \]--------
x: ---------[ ]---- x: ---------\[ \]----
y: -----[ ]-------- y: -----\[ \]--------
-> SAT, can tighten both to min(l1,l2)][max(u1,u2) -> SAT, can tighten both to min(l1,l2)\]\[max(u1,u2)
x: ---------------[ ]-- x: ---------------\[ \]--
y: -----[ ]-------- y: -----\[ \]--------
or symmetrically x<->y => cannot express the 3 intervals that would be needed so return SAT or symmetrically x<->y => cannot express the 3 intervals that would be needed so return SAT
(TODO: we might want to keep only one of these, which would be a kind of recency model of (TODO: we might want to keep only one of these, which would be a kind of recency model of
disequalities: remember the last known disequality) disequalities: remember the last known disequality)
@ -267,24 +265,24 @@ let rec abduce_eq (a1 : t) (a2 : t) =
(* ∃x. l1≤x≤u1 ∧ (x<l2 x>u2) *) (* ∃x. l1≤x≤u1 ∧ (x<l2 x>u2) *)
(* all the possible cases: (* all the possible cases:
x: [-------] x: \[-------\]
y: --[ ]--- y: --\[ \]---
case 1 above: SAT, cannot say more unless a1 is [-,+] (then we can abduce that a1 is case 1 above: SAT, cannot say more unless a1 is \[-,+\] (then we can abduce that a1 is
the same as a2) the same as a2)
x: [--] x: \[--\]
y: ------[ ]-- y: ------\[ \]--
case 2 above: UNSAT case 2 above: UNSAT
x: [---] x: \[---\]
y: ------[ ]-- y: ------\[ \]--
case 3 above: SAT: x = x\cap y for both case 3 above: SAT: x = x\cap y for both
x: [----] x: \[----\]
y: ------[ ]-- y: ------\[ \]--
case 4 above: SAT: x\cap y for both case 4 above: SAT: x\cap y for both
*) *)
@ -360,11 +358,11 @@ let abduce_le (a1 : t) (a2 : t) =
(* two cases: (* two cases:
1. l1<l2: we don't know if xy for sure and cannot express a good fact to abduce to make 1. l1<l2: we don't know if xy for sure and cannot express a good fact to abduce to make
it true it true
x: [----doesn't matter where u1 is x: \[----doesn't matter where u1 is
y: -----[ ]--------------------- y: -----\[ \]---------------------
2. l1l2: we can abduce that ymax(u2+1, l1) and that makes it SAT 2. l1l2: we can abduce that ymax(u2+1, l1) and that makes it SAT
x: [----doesn't matter either x: \[----doesn't matter either
y: -----[ ]--------------------- y: -----\[ \]---------------------
*) *)
if Bound.lt lower1 (Int l2) then (* case 1: l1<l2 *) Satisfiable (None, None) if Bound.lt lower1 (Int l2) then (* case 1: l1<l2 *) Satisfiable (None, None)
else else
@ -374,12 +372,12 @@ let abduce_le (a1 : t) (a2 : t) =
| Outside (l1, u1), Between (_lower2, upper2) -> | Outside (l1, u1), Between (_lower2, upper2) ->
(* similarly, two cases: (* similarly, two cases:
1. u1u2: can refine to xmin(l1+1, u2) 1. u1u2: can refine to xmin(l1+1, u2)
x: -----[ ]--------------------- x: -----\[ \]---------------------
y: ..-] y: ..-\]
or y: ...-----] or y: ...-----\]
2. u1<u2: cannot deduce anything 2. u1<u2: cannot deduce anything
x: -----[ ]--------------------- x: -----\[ \]---------------------
y: ...---] y: ...---\]
*) *)
if Bound.ge (Int u1) upper2 then if Bound.ge (Int u1) upper2 then
(* case 1: l1>l2 *) (* case 1: l1>l2 *)

@ -7,6 +7,8 @@
open! IStd open! IStd
module F = Format module F = Format
(** Concrete interval domain (CItv) *)
type t [@@deriving compare] type t [@@deriving compare]
val equal_to : IntLit.t -> t val equal_to : IntLit.t -> t

@ -43,7 +43,7 @@ module Misc = struct
let i = IntLit.of_int64 i64 in let i = IntLit.of_int64 i64 in
AddressAttributes.add_one ret_addr (BoItv (Itv.ItvPure.of_int_lit i)) astate AddressAttributes.add_one ret_addr (BoItv (Itv.ItvPure.of_int_lit i)) astate
|> AddressAttributes.add_one ret_addr |> AddressAttributes.add_one ret_addr
(Arithmetic (Arithmetic.equal_to i, Immediate {location; history= []})) (CItv (CItv.equal_to i, Immediate {location; history= []}))
in in
Ok [PulseOperations.write_id ret_id (ret_addr, []) astate] Ok [PulseOperations.write_id ret_id (ret_addr, []) astate]
@ -54,7 +54,7 @@ module Misc = struct
let astate = let astate =
AddressAttributes.add_one ret_addr (BoItv Itv.ItvPure.nat) astate AddressAttributes.add_one ret_addr (BoItv Itv.ItvPure.nat) astate
|> AddressAttributes.add_one ret_addr |> AddressAttributes.add_one ret_addr
(Arithmetic (Arithmetic.zero_inf, Immediate {location; history= []})) (CItv (CItv.zero_inf, Immediate {location; history= []}))
in in
Ok [PulseOperations.write_id ret_id (ret_addr, []) astate] Ok [PulseOperations.write_id ret_id (ret_addr, []) astate]
@ -78,8 +78,8 @@ module C = struct
(* NOTE: we could introduce a case-split explicitly on =0 vs ≠0 but instead only act on what we (* NOTE: we could introduce a case-split explicitly on =0 vs ≠0 but instead only act on what we
currently know about the value. This is purely to avoid contributing to path explosion. *) currently know about the value. This is purely to avoid contributing to path explosion. *)
let is_known_zero = let is_known_zero =
( AddressAttributes.get_arithmetic (fst deleted_access) astate ( AddressAttributes.get_citv (fst deleted_access) astate
|> function Some (arith, _) -> Arithmetic.is_equal_to_zero arith | None -> false ) |> function Some (arith, _) -> CItv.is_equal_to_zero arith | None -> false )
|| Itv.ItvPure.is_zero (AddressAttributes.get_bo_itv (fst deleted_access) astate) || Itv.ItvPure.is_zero (AddressAttributes.get_bo_itv (fst deleted_access) astate)
in in
if is_known_zero then (* freeing 0 is a no-op *) if is_known_zero then (* freeing 0 is a no-op *)

@ -105,21 +105,19 @@ let eval_arith_operand location binop_addr binop_hist bop op_lhs op_rhs astate =
let arith_of_op op astate = let arith_of_op op astate =
match op with match op with
| LiteralOperand i -> | LiteralOperand i ->
Some (Arithmetic.equal_to i) Some (CItv.equal_to i)
| AbstractValueOperand v -> | AbstractValueOperand v ->
AddressAttributes.get_arithmetic v astate |> Option.map ~f:fst AddressAttributes.get_citv v astate |> Option.map ~f:fst
in in
match match
Option.both (arith_of_op op_lhs astate) (arith_of_op op_rhs astate) Option.both (arith_of_op op_lhs astate) (arith_of_op op_rhs astate)
|> Option.bind ~f:(fun (addr_lhs, addr_rhs) -> Arithmetic.binop bop addr_lhs addr_rhs) |> Option.bind ~f:(fun (addr_lhs, addr_rhs) -> CItv.binop bop addr_lhs addr_rhs)
with with
| None -> | None ->
astate astate
| Some binop_a -> | Some binop_a ->
let binop_trace = Trace.Immediate {location; history= binop_hist} in let binop_trace = Trace.Immediate {location; history= binop_hist} in
let astate = let astate = AddressAttributes.add_one binop_addr (CItv (binop_a, binop_trace)) astate in
AddressAttributes.add_one binop_addr (Arithmetic (binop_a, binop_trace)) astate
in
astate astate
@ -148,14 +146,14 @@ let eval_binop location binop op_lhs op_rhs binop_hist astate =
let eval_unop_arith location unop_addr unop operand_addr unop_hist astate = let eval_unop_arith location unop_addr unop operand_addr unop_hist astate =
match match
AddressAttributes.get_arithmetic operand_addr astate AddressAttributes.get_citv operand_addr astate
|> Option.bind ~f:(function a, _ -> Arithmetic.unop unop a) |> Option.bind ~f:(function a, _ -> CItv.unop unop a)
with with
| None -> | None ->
astate astate
| Some unop_a -> | Some unop_a ->
let unop_trace = Trace.Immediate {location; history= unop_hist} in let unop_trace = Trace.Immediate {location; history= unop_hist} in
AddressAttributes.add_one unop_addr (Arithmetic (unop_a, unop_trace)) astate AddressAttributes.add_one unop_addr (CItv (unop_a, unop_trace)) astate
let eval_unop_bo_itv unop_addr unop operand_addr astate = let eval_unop_bo_itv unop_addr unop operand_addr astate =
@ -210,7 +208,7 @@ let eval location exp0 astate =
let addr = AbstractValue.mk_fresh () in let addr = AbstractValue.mk_fresh () in
let astate = let astate =
AddressAttributes.add_one addr AddressAttributes.add_one addr
(Arithmetic (Arithmetic.equal_to i, Immediate {location; history= []})) (CItv (CItv.equal_to i, Immediate {location; history= []}))
astate astate
|> AddressAttributes.add_one addr (BoItv (Itv.ItvPure.of_int_lit i)) |> AddressAttributes.add_one addr (BoItv (Itv.ItvPure.of_int_lit i))
|> AddressAttributes.invalidate |> AddressAttributes.invalidate
@ -244,14 +242,14 @@ let eval_arith location exp astate =
( astate ( astate
, None , None
, Some , Some
( Arithmetic.equal_to i ( CItv.equal_to i
, Trace.Immediate {location; history= [ValueHistory.Assignment location]} ) , Trace.Immediate {location; history= [ValueHistory.Assignment location]} )
, Itv.ItvPure.of_int_lit i ) , Itv.ItvPure.of_int_lit i )
| exp -> | exp ->
let+ astate, (value, _) = eval location exp astate in let+ astate, (value, _) = eval location exp astate in
( astate ( astate
, Some value , Some value
, AddressAttributes.get_arithmetic value astate , AddressAttributes.get_citv value astate
, AddressAttributes.get_bo_itv value astate ) , AddressAttributes.get_bo_itv value astate )
@ -267,7 +265,7 @@ let record_abduced event location addr_opt orig_arith_hist_opt arith_opt astate
| Some (_, trace) -> | Some (_, trace) ->
Trace.add_event event trace Trace.add_event event trace
in in
let attribute = Attribute.Arithmetic (arith, trace) in let attribute = Attribute.CItv (arith, trace) in
AddressAttributes.abduce_attribute addr attribute astate AddressAttributes.abduce_attribute addr attribute astate
|> AddressAttributes.add_one addr attribute |> AddressAttributes.add_one addr attribute
@ -302,7 +300,7 @@ let prune ~is_then_branch if_kind location ~condition astate =
eval_arith location exp_rhs astate eval_arith location exp_rhs astate
in in
match match
Arithmetic.abduce_binop_is_true ~negated bop (Option.map ~f:fst arith_lhs_opt) CItv.abduce_binop_is_true ~negated bop (Option.map ~f:fst arith_lhs_opt)
(Option.map ~f:fst arith_rhs_opt) (Option.map ~f:fst arith_rhs_opt)
with with
| Unsatisfiable -> | Unsatisfiable ->

Loading…
Cancel
Save