[inferbo] Simplify alias targets

Summary:
This diff simplifies two similar alias targets: AliasTarget.Simple and
AliasTarget.SimplePlusA.  Since the latter is simply extended version
of the former, they are better to have a common constructor.

Reviewed By: jvillard

Differential Revision: D17421416

fbshipit-source-id: e0946a73b
master
Sungkeun Cho 6 years ago committed by Facebook Github Bot
parent 21c890f23d
commit 0574372891

@ -713,7 +713,7 @@ module AliasTarget = struct
pruning values of program variables. For example, a C statement "if(x){...}" is translated to pruning values of program variables. For example, a C statement "if(x){...}" is translated to
"%r=load(x); if(%r){...}" in Sil. At the load statement, we record the alias between the "%r=load(x); if(%r){...}" in Sil. At the load statement, we record the alias between the
values of %r and x, then we can prune not only the value of %r, but also that of x inside the values of %r and x, then we can prune not only the value of %r, but also that of x inside the
if branch. if branch. The i field is to express "%r=load(x)+i".
"Empty relation": For pruning vector.length with vector::empty() results, we adopt a specific "Empty relation": For pruning vector.length with vector::empty() results, we adopt a specific
relation between %r and v->elements, where %r=v.empty(). So, if %r!=0, v's array length relation between %r and v->elements, where %r=v.empty(). So, if %r!=0, v's array length
@ -726,8 +726,7 @@ module AliasTarget = struct
field is to express "%r=x.size()+i", which is required to follow the semantics of `Array.add` field is to express "%r=x.size()+i", which is required to follow the semantics of `Array.add`
inside loops precisely. *) inside loops precisely. *)
type t = type t =
| Simple of Loc.t | Simple of {l: Loc.t; i: IntLit.t}
| SimplePlusA of Loc.t * IntLit.t
| Empty of Loc.t | Empty of Loc.t
| Size of {l: Loc.t; i: IntLit.t; java_tmp: Loc.t option} | Size of {l: Loc.t; i: IntLit.t; java_tmp: Loc.t option}
| Fgets of Loc.t | Fgets of Loc.t
@ -742,10 +741,9 @@ module AliasTarget = struct
else F.fprintf fmt "+%a" IntLit.pp i else F.fprintf fmt "+%a" IntLit.pp i
in in
fun fmt -> function fun fmt -> function
| Simple l -> | Simple {l; i} ->
Loc.pp fmt l Loc.pp fmt l ;
| SimplePlusA (l, i) -> if not (IntLit.iszero i) then intlit_pp fmt i
Loc.pp fmt l ; intlit_pp fmt i
| Empty l -> | Empty l ->
F.fprintf fmt "empty(%a)" Loc.pp l F.fprintf fmt "empty(%a)" Loc.pp l
| Size {l; i; java_tmp} -> | Size {l; i; java_tmp} ->
@ -763,7 +761,7 @@ module AliasTarget = struct
let get_locs = function let get_locs = function
| Size {l; java_tmp= Some tmp} -> | Size {l; java_tmp= Some tmp} ->
PowLoc.singleton l |> PowLoc.add tmp PowLoc.singleton l |> PowLoc.add tmp
| Simple l | SimplePlusA (l, _) | Size {l; java_tmp= None} | Empty l | Fgets l -> | Simple {l} | Size {l; java_tmp= None} | Empty l | Fgets l ->
PowLoc.singleton l PowLoc.singleton l
| Top -> | Top ->
PowLoc.empty PowLoc.empty
@ -773,10 +771,8 @@ module AliasTarget = struct
let loc_map x ~f = let loc_map x ~f =
match x with match x with
| Simple l -> | Simple {l; i} ->
Option.map (f l) ~f:(fun l -> Simple l) Option.map (f l) ~f:(fun l -> Simple {l; i})
| SimplePlusA (l, i) ->
Option.map (f l) ~f:(fun l -> SimplePlusA (l, i))
| Empty l -> | Empty l ->
Option.map (f l) ~f:(fun l -> Empty l) Option.map (f l) ~f:(fun l -> Empty l)
| Size {l; i; java_tmp} -> | Size {l; i; java_tmp} ->
@ -863,7 +859,7 @@ module AliasMap = struct
else else
let tgt = let tgt =
match tgt with match tgt with
| AliasTarget.Simple loc when Language.curr_language_is Java -> | AliasTarget.Simple {l= loc; i} when IntLit.iszero i && Language.curr_language_is Java ->
Option.value (find_loc loc x) ~default:tgt Option.value (find_loc loc x) ~default:tgt
| _ -> | _ ->
tgt tgt
@ -951,10 +947,10 @@ module Alias = struct
else a else a
| Exp.BinOp (Binop.PlusA _, Exp.Var id, Exp.Const (Const.Cint i)) | Exp.BinOp (Binop.PlusA _, Exp.Var id, Exp.Const (Const.Cint i))
| Exp.BinOp (Binop.PlusA _, Exp.Const (Const.Cint i), Exp.Var id) -> | Exp.BinOp (Binop.PlusA _, Exp.Const (Const.Cint i), Exp.Var id) ->
lift_map (AliasMap.load id (AliasTarget.SimplePlusA (loc, IntLit.neg i))) a lift_map (AliasMap.load id (AliasTarget.Simple {l= loc; i= IntLit.neg i})) a
|> lift_map (AliasMap.store_n ~prev:prev.map loc id i) |> lift_map (AliasMap.store_n ~prev:prev.map loc id i)
| Exp.BinOp (Binop.MinusA _, Exp.Var id, Exp.Const (Const.Cint i)) -> | Exp.BinOp (Binop.MinusA _, Exp.Var id, Exp.Const (Const.Cint i)) ->
lift_map (AliasMap.load id (AliasTarget.SimplePlusA (loc, i))) a lift_map (AliasMap.load id (AliasTarget.Simple {l= loc; i})) a
|> lift_map (AliasMap.store_n ~prev:prev.map loc id (IntLit.neg i)) |> lift_map (AliasMap.store_n ~prev:prev.map loc id (IntLit.neg i))
| _ -> | _ ->
a a
@ -1479,10 +1475,8 @@ module MemReach = struct
let find_simple_alias : Ident.t -> _ t0 -> (Loc.t * IntLit.t option) option = let find_simple_alias : Ident.t -> _ t0 -> (Loc.t * IntLit.t option) option =
fun k m -> fun k m ->
match Alias.find_id k m.alias with match Alias.find_id k m.alias with
| Some (AliasTarget.Simple l) -> | Some (AliasTarget.Simple {l; i}) ->
Some (l, None) Some (l, if IntLit.iszero i then None else Some i)
| Some (AliasTarget.SimplePlusA (l, i)) ->
Some (l, Some i)
| Some (AliasTarget.Empty _ | AliasTarget.Size _ | AliasTarget.Fgets _ | AliasTarget.Top) | Some (AliasTarget.Empty _ | AliasTarget.Size _ | AliasTarget.Fgets _ | AliasTarget.Top)
| None -> | None ->
None None
@ -1646,7 +1640,7 @@ module MemReach = struct
else {m with latest_prune= LatestPrune.forget updated_locs m.latest_prune} else {m with latest_prune= LatestPrune.forget updated_locs m.latest_prune}
| Lvar return, _, _ when Pvar.is_return return -> ( | Lvar return, _, _ when Pvar.is_return return -> (
match Alias.find_ret m.alias with match Alias.find_ret m.alias with
| Some (Simple (Var (ProgramVar pvar))) -> | Some (Simple {l= Var (ProgramVar pvar); i}) when IntLit.iszero i ->
{m with latest_prune= LatestPrune.replace ~from:pvar ~to_:return m.latest_prune} {m with latest_prune= LatestPrune.replace ~from:pvar ~to_:return m.latest_prune}
| _ -> | _ ->
m ) m )
@ -1828,7 +1822,7 @@ module Mem = struct
let load_simple_alias : Ident.t -> Loc.t -> t -> t = let load_simple_alias : Ident.t -> Loc.t -> t -> t =
fun id loc -> load_alias id (AliasTarget.Simple loc) fun id loc -> load_alias id (AliasTarget.Simple {l= loc; i= IntLit.zero})
let load_empty_alias : Ident.t -> Loc.t -> t -> t = let load_empty_alias : Ident.t -> Loc.t -> t -> t =

@ -307,10 +307,10 @@ let rec eval_arr : Typ.IntegerWidths.t -> Exp.t -> Mem.t -> Val.t =
match exp with match exp with
| Exp.Var id -> ( | Exp.Var id -> (
match Mem.find_alias id mem with match Mem.find_alias id mem with
| Some (AliasTarget.Simple loc) -> | Some (AliasTarget.Simple {l= loc; i}) when IntLit.iszero i ->
Mem.find loc mem Mem.find loc mem
| Some | Some
( AliasTarget.SimplePlusA _ ( AliasTarget.Simple _
| AliasTarget.Size _ | AliasTarget.Size _
| AliasTarget.Empty _ | AliasTarget.Empty _
| AliasTarget.Fgets _ | AliasTarget.Fgets _
@ -498,7 +498,7 @@ module Prune = struct
match e with match e with
| Exp.Var x -> ( | Exp.Var x -> (
match Mem.find_alias x mem with match Mem.find_alias x mem with
| Some (AliasTarget.Simple lv) -> | Some (AliasTarget.Simple {l= lv; i}) when IntLit.iszero i ->
let v = Mem.find lv mem in let v = Mem.find lv mem in
let v' = Val.prune_ne_zero v in let v' = Val.prune_ne_zero v in
update_mem_in_prune lv v' astate update_mem_in_prune lv v' astate
@ -510,11 +510,11 @@ module Prune = struct
let strlen_loc = Loc.of_c_strlen lv in let strlen_loc = Loc.of_c_strlen lv in
let v' = Val.prune_ge_one (Mem.find strlen_loc mem) in let v' = Val.prune_ge_one (Mem.find strlen_loc mem) in
update_mem_in_prune strlen_loc v' astate update_mem_in_prune strlen_loc v' astate
| Some (AliasTarget.SimplePlusA _ | AliasTarget.Size _ | Top) | None -> | Some (AliasTarget.Simple _ | AliasTarget.Size _ | Top) | None ->
astate ) astate )
| Exp.UnOp (Unop.LNot, Exp.Var x, _) -> ( | Exp.UnOp (Unop.LNot, Exp.Var x, _) -> (
match Mem.find_alias x mem with match Mem.find_alias x mem with
| Some (AliasTarget.Simple lv) -> | Some (AliasTarget.Simple {l= lv; i}) when IntLit.iszero i ->
let v = Mem.find lv mem in let v = Mem.find lv mem in
let v' = Val.prune_eq_zero v in let v' = Val.prune_eq_zero v in
update_mem_in_prune lv v' astate update_mem_in_prune lv v' astate
@ -522,7 +522,7 @@ module Prune = struct
let v = Mem.find lv mem in let v = Mem.find lv mem in
let v' = Val.prune_length_ge_one v in let v' = Val.prune_length_ge_one v in
update_mem_in_prune lv v' astate update_mem_in_prune lv v' astate
| Some (AliasTarget.SimplePlusA _ | AliasTarget.Size _ | AliasTarget.Fgets _ | Top) | None -> | Some (AliasTarget.Simple _ | AliasTarget.Size _ | AliasTarget.Fgets _ | Top) | None ->
astate ) astate )
| _ -> | _ ->
astate astate

Loading…
Cancel
Save