[HIL][3/4] remove compatibility AccessExpression.ml

Summary:
`AccessExpression.t` and `HilExp.t` are about to become mutually
recursive, this will help distinguish the actual changes from the moving
of code around.

This deletes the file left around in the previous commit to preserve
callers of `AccessExpression`.

Reviewed By: mbouaziz

Differential Revision: D13377645

fbshipit-source-id: 71338d1f3
master
Jules Villard 6 years ago committed by Facebook Github Bot
parent d59e6ac1bf
commit 1ee5877aa2

@ -1,9 +0,0 @@
(*
* Copyright (c) 2018-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
include HilExp.AccessExpression

@ -9,17 +9,17 @@ open! IStd
module F = Format module F = Format
module L = Logging module L = Logging
type call = Direct of Typ.Procname.t | Indirect of AccessExpression.t [@@deriving compare] type call = Direct of Typ.Procname.t | Indirect of HilExp.AccessExpression.t [@@deriving compare]
let pp_call fmt = function let pp_call fmt = function
| Direct pname -> | Direct pname ->
Typ.Procname.pp fmt pname Typ.Procname.pp fmt pname
| Indirect access_expr -> | Indirect access_expr ->
F.fprintf fmt "*%a" AccessExpression.pp access_expr F.fprintf fmt "*%a" HilExp.AccessExpression.pp access_expr
type t = type t =
| Assign of AccessExpression.t * HilExp.t * Location.t | Assign of HilExp.AccessExpression.t * HilExp.t * Location.t
| Assume of HilExp.t * [`Then | `Else] * Sil.if_kind * Location.t | Assume of HilExp.t * [`Then | `Else] * Sil.if_kind * Location.t
| Call of AccessPath.base * call * HilExp.t list * CallFlags.t * Location.t | Call of AccessPath.base * call * HilExp.t list * CallFlags.t * Location.t
| ExitScope of Var.t list | ExitScope of Var.t list
@ -27,7 +27,8 @@ type t =
let pp fmt = function let pp fmt = function
| Assign (access_expr, exp, loc) -> | Assign (access_expr, exp, loc) ->
F.fprintf fmt "%a := %a [%a]" AccessExpression.pp access_expr HilExp.pp exp Location.pp loc F.fprintf fmt "%a := %a [%a]" HilExp.AccessExpression.pp access_expr HilExp.pp exp
Location.pp loc
| Assume (exp, _, _, loc) -> | Assume (exp, _, _, loc) ->
F.fprintf fmt "assume %a [%a]" HilExp.pp exp Location.pp loc F.fprintf fmt "assume %a [%a]" HilExp.pp exp Location.pp loc
| Call (ret, call, actuals, _, loc) -> | Call (ret, call, actuals, _, loc) ->
@ -38,7 +39,7 @@ let pp fmt = function
F.fprintf fmt "exit scope [%a]" (Pp.seq ~sep:"; " Var.pp) vars F.fprintf fmt "exit scope [%a]" (Pp.seq ~sep:"; " Var.pp) vars
type translation = Instr of t | Bind of Var.t * AccessExpression.t | Ignore type translation = Instr of t | Bind of Var.t * HilExp.AccessExpression.t | Ignore
(** convert an SIL instruction into an HIL instruction. The [f_resolve_id] function should map an (** convert an SIL instruction into an HIL instruction. The [f_resolve_id] function should map an
SSA temporary variable to the access path it represents. Evaluating the HIL instruction should SSA temporary variable to the access path it represents. Evaluating the HIL instruction should
@ -51,10 +52,10 @@ let of_sil ~include_array_indexes ~f_resolve_id (instr : Sil.instr) =
let analyze_id_assignment ?(add_deref = false) lhs_id rhs_exp rhs_typ loc = let analyze_id_assignment ?(add_deref = false) lhs_id rhs_exp rhs_typ loc =
let rhs_hil_exp = exp_of_sil ~add_deref rhs_exp rhs_typ in let rhs_hil_exp = exp_of_sil ~add_deref rhs_exp rhs_typ in
match rhs_hil_exp with match rhs_hil_exp with
| AccessExpression rhs_access_expr -> | HilExp.AccessExpression rhs_access_expr ->
Bind (lhs_id, rhs_access_expr) Bind (lhs_id, rhs_access_expr)
| _ -> | _ ->
Instr (Assign (AccessExpression.base (lhs_id, rhs_typ), rhs_hil_exp, loc)) Instr (Assign (HilExp.AccessExpression.base (lhs_id, rhs_typ), rhs_hil_exp, loc))
in in
match instr with match instr with
| Load (lhs_id, rhs_exp, rhs_typ, loc) -> | Load (lhs_id, rhs_exp, rhs_typ, loc) ->
@ -73,7 +74,7 @@ let of_sil ~include_array_indexes ~f_resolve_id (instr : Sil.instr) =
| Store (lhs_exp, typ, rhs_exp, loc) -> | Store (lhs_exp, typ, rhs_exp, loc) ->
let lhs_access_expr = let lhs_access_expr =
match HilExp.ignore_cast (exp_of_sil ~add_deref:true lhs_exp typ) with match HilExp.ignore_cast (exp_of_sil ~add_deref:true lhs_exp typ) with
| AccessExpression access_expr -> | HilExp.AccessExpression access_expr ->
access_expr access_expr
| BinaryOperator (_, exp0, exp1) -> ( | BinaryOperator (_, exp0, exp1) -> (
(* pointer arithmetic. somewhere in one of the expressions, there should be at least (* pointer arithmetic. somewhere in one of the expressions, there should be at least
@ -97,7 +98,7 @@ let of_sil ~include_array_indexes ~f_resolve_id (instr : Sil.instr) =
let dummy_base_var = let dummy_base_var =
Var.of_id (Ident.create_normal (Ident.string_to_name (IntLit.to_string i)) 0) Var.of_id (Ident.create_normal (Ident.string_to_name (IntLit.to_string i)) 0)
in in
AccessExpression.base (dummy_base_var, Typ.void_star) HilExp.AccessExpression.base (dummy_base_var, Typ.void_star)
| _ -> | _ ->
L.(die InternalError) L.(die InternalError)
"Non-assignable LHS expression %a at %a" Exp.pp lhs_exp Location.pp_file_pos loc "Non-assignable LHS expression %a at %a" Exp.pp lhs_exp Location.pp_file_pos loc
@ -109,7 +110,7 @@ let of_sil ~include_array_indexes ~f_resolve_id (instr : Sil.instr) =
match exp_of_sil call_exp (Typ.mk Tvoid) with match exp_of_sil call_exp (Typ.mk Tvoid) with
| Constant (Cfun procname) | Closure (procname, _) -> | Constant (Cfun procname) | Closure (procname, _) ->
Direct procname Direct procname
| AccessExpression access_expr -> | HilExp.AccessExpression access_expr ->
Indirect access_expr Indirect access_expr
| call_exp -> | call_exp ->
L.(die InternalError) "Unexpected call expression %a" HilExp.pp call_exp L.(die InternalError) "Unexpected call expression %a" HilExp.pp call_exp

@ -9,10 +9,10 @@ open! IStd
module F = Format module F = Format
(** type of a procedure call; either direct or via function pointer *) (** type of a procedure call; either direct or via function pointer *)
type call = Direct of Typ.Procname.t | Indirect of AccessExpression.t [@@deriving compare] type call = Direct of Typ.Procname.t | Indirect of HilExp.AccessExpression.t [@@deriving compare]
type t = type t =
| Assign of AccessExpression.t * HilExp.t * Location.t | Assign of HilExp.AccessExpression.t * HilExp.t * Location.t
(** LHS access expression, RHS expression *) (** LHS access expression, RHS expression *)
| Assume of HilExp.t * [`Then | `Else] * Sil.if_kind * Location.t | Assume of HilExp.t * [`Then | `Else] * Sil.if_kind * Location.t
(** Assumed expression, true_branch boolean, source of the assume (conditional, ternary, etc.) *) (** Assumed expression, true_branch boolean, source of the assume (conditional, ternary, etc.) *)
@ -26,12 +26,12 @@ val pp : F.formatter -> t -> unit
(** Result of translating an SIL instruction *) (** Result of translating an SIL instruction *)
type translation = type translation =
| Instr of t (** HIL instruction to execute *) | Instr of t (** HIL instruction to execute *)
| Bind of Var.t * AccessExpression.t (** add binding to identifier map *) | Bind of Var.t * HilExp.AccessExpression.t (** add binding to identifier map *)
| Ignore (** no-op *) | Ignore (** no-op *)
val of_sil : val of_sil :
include_array_indexes:bool include_array_indexes:bool
-> f_resolve_id:(Var.t -> AccessExpression.t option) -> f_resolve_id:(Var.t -> HilExp.AccessExpression.t option)
-> Sil.instr -> Sil.instr
-> translation -> translation
(** convert an SIL instruction into an HIL instruction. The [f_resolve_id] function should map an (** convert an SIL instruction into an HIL instruction. The [f_resolve_id] function should map an

@ -62,7 +62,7 @@ struct
let actual_state' = let actual_state' =
IdAccessPathMapDomain.fold IdAccessPathMapDomain.fold
(fun id access_expr astate_acc -> (fun id access_expr astate_acc ->
let lhs_access_path = AccessExpression.base (id, Typ.mk Typ.Tvoid) in let lhs_access_path = HilExp.AccessExpression.base (id, Typ.mk Typ.Tvoid) in
let dummy_assign = let dummy_assign =
HilInstr.Assign (lhs_access_path, HilExp.AccessExpression access_expr, loc) HilInstr.Assign (lhs_access_path, HilExp.AccessExpression access_expr, loc)
in in

@ -11,20 +11,21 @@ module L = Logging
include (IdMap : module type of IdMap with type 'a t := 'a IdMap.t) include (IdMap : module type of IdMap with type 'a t := 'a IdMap.t)
type t = AccessExpression.t IdMap.t type t = HilExp.AccessExpression.t IdMap.t
type value = AccessExpression.t type value = HilExp.AccessExpression.t
let pp fmt astate = IdMap.pp ~pp_value:AccessExpression.pp fmt astate let pp fmt astate = IdMap.pp ~pp_value:HilExp.AccessExpression.pp fmt astate
let check_invariant ap1 ap2 = function let check_invariant ap1 ap2 = function
| Var.ProgramVar pvar when Pvar.is_ssa_frontend_tmp pvar -> | Var.ProgramVar pvar when Pvar.is_ssa_frontend_tmp pvar ->
(* Sawja reuses temporary variables which sometimes breaks this invariant *) (* Sawja reuses temporary variables which sometimes breaks this invariant *)
() ()
| id -> | id ->
if not (AccessExpression.equal ap1 ap2) then if not (HilExp.AccessExpression.equal ap1 ap2) then
L.(die InternalError) L.(die InternalError)
"Id %a maps to both %a and %a" Var.pp id AccessExpression.pp ap1 AccessExpression.pp ap2 "Id %a maps to both %a and %a" Var.pp id HilExp.AccessExpression.pp ap1
HilExp.AccessExpression.pp ap2
let ( <= ) ~lhs ~rhs = let ( <= ) ~lhs ~rhs =

@ -9,4 +9,4 @@ open! IStd
(** mapping of ids to raw access paths. useful for id-normalizing access paths *) (** mapping of ids to raw access paths. useful for id-normalizing access paths *)
include AbstractDomain.MapS with type key = Var.t and type value = AccessExpression.t include AbstractDomain.MapS with type key = Var.t and type value = HilExp.AccessExpression.t

@ -194,7 +194,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Some (HilExp.AccessExpression actual_access_expr) -> | Some (HilExp.AccessExpression actual_access_expr) ->
Some Some
(Domain.LocalAccessPath.make (Domain.LocalAccessPath.make
(AccessExpression.to_access_path actual_access_expr) (HilExp.AccessExpression.to_access_path actual_access_expr)
caller_pname) caller_pname)
| _ -> | _ ->
None ) None )
@ -219,7 +219,9 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
, _ ) -> , _ ) ->
let summary = Payload.read proc_data.pdesc callee_procname in let summary = Payload.read proc_data.pdesc callee_procname in
let receiver = let receiver =
Domain.LocalAccessPath.make (AccessExpression.to_access_path receiver_ae) caller_pname Domain.LocalAccessPath.make
(HilExp.AccessExpression.to_access_path receiver_ae)
caller_pname
in in
if if
( LithoFramework.is_component_builder callee_procname proc_data.tenv ( LithoFramework.is_component_builder callee_procname proc_data.tenv
@ -252,10 +254,10 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
alias. this helps us keep track of chains in cases like tmp = getFoo(); x = tmp; alias. this helps us keep track of chains in cases like tmp = getFoo(); x = tmp;
tmp.getBar() *) tmp.getBar() *)
let lhs_access_path = let lhs_access_path =
Domain.LocalAccessPath.make (AccessExpression.to_access_path lhs_ae) caller_pname Domain.LocalAccessPath.make (HilExp.AccessExpression.to_access_path lhs_ae) caller_pname
in in
let rhs_access_path = let rhs_access_path =
Domain.LocalAccessPath.make (AccessExpression.to_access_path rhs_ae) caller_pname Domain.LocalAccessPath.make (HilExp.AccessExpression.to_access_path rhs_ae) caller_pname
in in
try try
let call_set = Domain.find rhs_access_path astate in let call_set = Domain.find rhs_access_path astate in

@ -159,7 +159,8 @@ module Domain = struct
let exp_add_reads exp loc summary astate = let exp_add_reads exp loc summary astate =
List.fold List.fold
~f:(fun acc access_expr -> ~f:(fun acc access_expr ->
access_path_add_read (AccessExpression.to_access_path access_expr) loc summary acc ) access_path_add_read (HilExp.AccessExpression.to_access_path access_expr) loc summary acc
)
(HilExp.get_access_exprs exp) ~init:astate (HilExp.get_access_exprs exp) ~init:astate
@ -235,12 +236,12 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
false false
let get_assigned_base (access_expression : AccessExpression.t) = let get_assigned_base (access_expression : HilExp.AccessExpression.t) =
match access_expression with match access_expression with
| Base base -> | Base base ->
Some base Some base
| _ -> | _ ->
let base = AccessExpression.get_base access_expression in let base = HilExp.AccessExpression.get_base access_expression in
(* assume assigning to any field of an aggregate struct re-initalizes the struct *) (* assume assigning to any field of an aggregate struct re-initalizes the struct *)
Option.some_if (is_aggregate base) base Option.some_if (is_aggregate base) base
@ -254,7 +255,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let acquire_ownership call_exp return_base actuals loc summary astate = let acquire_ownership call_exp return_base actuals loc summary astate =
let aquire_ownership_of_first_param actuals = let aquire_ownership_of_first_param actuals =
match actuals with match actuals with
| HilExp.AccessExpression (AccessExpression.AddressOf access_expression) :: other_actuals -> ( | HilExp.AccessExpression (AddressOf access_expression) :: other_actuals -> (
match get_assigned_base access_expression with match get_assigned_base access_expression with
| Some constructed_base -> | Some constructed_base ->
let astate' = Domain.actuals_add_reads other_actuals loc summary astate in let astate' = Domain.actuals_add_reads other_actuals loc summary astate in
@ -326,7 +327,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(* assign to field, array, indirectly with &/*, or a combination *) (* assign to field, array, indirectly with &/*, or a combination *)
Domain.exp_add_reads rhs_exp loc summary astate Domain.exp_add_reads rhs_exp loc summary astate
|> Domain.access_path_add_read |> Domain.access_path_add_read
(AccessExpression.to_access_path lhs_access_exp) (HilExp.AccessExpression.to_access_path lhs_access_exp)
loc summary ) loc summary )
| Call (_, Direct callee_pname, _, _, _) | Call (_, Direct callee_pname, _, _, _)
when Typ.Procname.equal callee_pname BuiltinDecl.__variable_initialization -> when Typ.Procname.equal callee_pname BuiltinDecl.__variable_initialization ->

@ -62,7 +62,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Direct callee_pname when is_destructor callee_pname -> ( | Direct callee_pname when is_destructor callee_pname -> (
match actuals with match actuals with
| [AccessExpression destroyed_access] -> | [AccessExpression destroyed_access] ->
let destroyed_object = AccessExpression.dereference destroyed_access in let destroyed_object = HilExp.AccessExpression.dereference destroyed_access in
PulseDomain.invalidate PulseDomain.invalidate
(CppDestructor (callee_pname, destroyed_object, call_loc)) (CppDestructor (callee_pname, destroyed_object, call_loc))
call_loc destroyed_object astate call_loc destroyed_object astate
@ -71,7 +71,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Direct callee_pname when Typ.Procname.is_constructor callee_pname -> ( | Direct callee_pname when Typ.Procname.is_constructor callee_pname -> (
match actuals with match actuals with
| AccessExpression constructor_access :: rest -> | AccessExpression constructor_access :: rest ->
let constructed_object = AccessExpression.dereference constructor_access in let constructed_object = HilExp.AccessExpression.dereference constructor_access in
PulseDomain.havoc call_loc constructed_object astate >>= read_all rest PulseDomain.havoc call_loc constructed_object astate >>= read_all rest
| _ -> | _ ->
Ok astate ) Ok astate )
@ -81,12 +81,12 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(* We want to assign *lhs to *rhs when rhs is materialized temporary created in constructor *) (* We want to assign *lhs to *rhs when rhs is materialized temporary created in constructor *)
| [AccessExpression lhs; (HilExp.AccessExpression (AddressOf (Base rhs_base)) as rhs_exp)] | [AccessExpression lhs; (HilExp.AccessExpression (AddressOf (Base rhs_base)) as rhs_exp)]
when Var.is_cpp_temporary (fst rhs_base) -> when Var.is_cpp_temporary (fst rhs_base) ->
let lhs_deref = AccessExpression.dereference lhs in let lhs_deref = HilExp.AccessExpression.dereference lhs in
exec_assign lhs_deref rhs_exp call_loc astate exec_assign lhs_deref rhs_exp call_loc astate
(* copy assignment *) (* copy assignment *)
| [AccessExpression lhs; HilExp.AccessExpression rhs] -> | [AccessExpression lhs; HilExp.AccessExpression rhs] ->
let lhs_deref = AccessExpression.dereference lhs in let lhs_deref = HilExp.AccessExpression.dereference lhs in
let rhs_deref = AccessExpression.dereference rhs in let rhs_deref = HilExp.AccessExpression.dereference rhs in
PulseDomain.havoc call_loc lhs_deref astate PulseDomain.havoc call_loc lhs_deref astate
>>= fun astate -> PulseDomain.read call_loc rhs_deref astate >>| fst >>= fun astate -> PulseDomain.read call_loc rhs_deref astate >>| fst
| _ -> | _ ->

@ -476,7 +476,7 @@ end
(* {2 Access operations on the domain} *) (* {2 Access operations on the domain} *)
type actor = {access_expr: AccessExpression.t; location: Location.t} [@@deriving compare] type actor = {access_expr: HilExp.AccessExpression.t; location: Location.t} [@@deriving compare]
module Diagnostic = struct module Diagnostic = struct
type t = type t =
@ -491,7 +491,7 @@ module Diagnostic = struct
let pp_debug_address f = let pp_debug_address f =
if Config.debug_mode then F.fprintf f " (debug: %a)" AbstractAddress.pp address if Config.debug_mode then F.fprintf f " (debug: %a)" AbstractAddress.pp address
in in
F.asprintf "`%a` accesses address %a past its lifetime%t" AccessExpression.pp F.asprintf "`%a` accesses address %a past its lifetime%t" HilExp.AccessExpression.pp
accessed_by.access_expr Invalidation.pp invalidated_by pp_debug_address accessed_by.access_expr Invalidation.pp invalidated_by pp_debug_address
@ -506,7 +506,7 @@ module Diagnostic = struct
in in
invalidated_by_trace invalidated_by_trace
@ [ Errlog.make_trace_element 0 accessed_by.location @ [ Errlog.make_trace_element 0 accessed_by.location
(F.asprintf "accessed `%a` here" AccessExpression.pp accessed_by.access_expr) (F.asprintf "accessed `%a` here" HilExp.AccessExpression.pp accessed_by.access_expr)
[] ] [] ]
@ -582,7 +582,7 @@ module Operations = struct
(** add addresses to the state to give a address to the destination of the given access path *) (** add addresses to the state to give a address to the destination of the given access path *)
let walk_access_expr ~on_last astate access_expr location = let walk_access_expr ~on_last astate access_expr location =
let (access_var, _), access_list = let (access_var, _), access_list =
AccessExpression.to_accesses ~f_array_offset:(fun _ -> ()) access_expr HilExp.AccessExpression.to_accesses ~f_array_offset:(fun _ -> ()) access_expr
in in
if Config.write_html then if Config.write_html then
L.d_printfln "Accessing %a -> [%a]" Var.pp access_var L.d_printfln "Accessing %a -> [%a]" Var.pp access_var
@ -632,7 +632,7 @@ module Operations = struct
{astate with stack= Stack.add var (AbstractAddressSet.mk_fresh ()) astate.stack} {astate with stack= Stack.add var (AbstractAddressSet.mk_fresh ()) astate.stack}
let havoc location (access_expr : AccessExpression.t) astate = let havoc location (access_expr : HilExp.AccessExpression.t) astate =
match access_expr with match access_expr with
| Base (access_var, _) -> | Base (access_var, _) ->
havoc_var access_var astate |> Result.return havoc_var access_var astate |> Result.return

@ -36,23 +36,24 @@ end
type 'a access_result = ('a, Diagnostic.t) result type 'a access_result = ('a, Diagnostic.t) result
module StdVector : sig module StdVector : sig
val is_reserved : Location.t -> AccessExpression.t -> t -> (t * bool) access_result val is_reserved : Location.t -> HilExp.AccessExpression.t -> t -> (t * bool) access_result
val mark_reserved : Location.t -> AccessExpression.t -> t -> t access_result val mark_reserved : Location.t -> HilExp.AccessExpression.t -> t -> t access_result
end end
val read : Location.t -> AccessExpression.t -> t -> (t * AbstractAddressSet.t) access_result val read : Location.t -> HilExp.AccessExpression.t -> t -> (t * AbstractAddressSet.t) access_result
val read_all : Location.t -> AccessExpression.t list -> t -> t access_result val read_all : Location.t -> HilExp.AccessExpression.t list -> t -> t access_result
val havoc_var : Var.t -> t -> t val havoc_var : Var.t -> t -> t
val havoc : Location.t -> AccessExpression.t -> t -> t access_result val havoc : Location.t -> HilExp.AccessExpression.t -> t -> t access_result
val write_var : Var.t -> AbstractAddressSet.t -> t -> t val write_var : Var.t -> AbstractAddressSet.t -> t -> t
val write : Location.t -> AccessExpression.t -> AbstractAddressSet.t -> t -> t access_result val write : Location.t -> HilExp.AccessExpression.t -> AbstractAddressSet.t -> t -> t access_result
val invalidate : PulseInvalidation.t -> Location.t -> AccessExpression.t -> t -> t access_result val invalidate :
PulseInvalidation.t -> Location.t -> HilExp.AccessExpression.t -> t -> t access_result
val remove_vars : Var.t list -> t -> t val remove_vars : Var.t list -> t -> t

@ -17,11 +17,11 @@ let std_vector_function_pp f = function
type t = type t =
| CFree of AccessExpression.t * Location.t | CFree of HilExp.AccessExpression.t * Location.t
| CppDelete of AccessExpression.t * Location.t | CppDelete of HilExp.AccessExpression.t * Location.t
| CppDestructor of Typ.Procname.t * AccessExpression.t * Location.t | CppDestructor of Typ.Procname.t * HilExp.AccessExpression.t * Location.t
| Nullptr | Nullptr
| StdVector of std_vector_function * AccessExpression.t * Location.t | StdVector of std_vector_function * HilExp.AccessExpression.t * Location.t
[@@deriving compare] [@@deriving compare]
let issue_type_of_cause = function let issue_type_of_cause = function
@ -49,16 +49,16 @@ let get_location = function
let pp f = function let pp f = function
| CFree (access_expr, location) -> | CFree (access_expr, location) ->
F.fprintf f "invalidated by call to `free(%a)` at %a" AccessExpression.pp access_expr F.fprintf f "invalidated by call to `free(%a)` at %a" HilExp.AccessExpression.pp access_expr
Location.pp location Location.pp location
| CppDelete (access_expr, location) -> | CppDelete (access_expr, location) ->
F.fprintf f "invalidated by call to `delete %a` at %a" AccessExpression.pp access_expr F.fprintf f "invalidated by call to `delete %a` at %a" HilExp.AccessExpression.pp access_expr
Location.pp location Location.pp location
| CppDestructor (proc_name, access_expr, location) -> | CppDestructor (proc_name, access_expr, location) ->
F.fprintf f "invalidated by destructor call `%a(%a)` at %a" Typ.Procname.pp proc_name F.fprintf f "invalidated by destructor call `%a(%a)` at %a" Typ.Procname.pp proc_name
AccessExpression.pp access_expr Location.pp location HilExp.AccessExpression.pp access_expr Location.pp location
| Nullptr -> | Nullptr ->
F.fprintf f "null pointer" F.fprintf f "null pointer"
| StdVector (std_vector_f, access_expr, location) -> | StdVector (std_vector_f, access_expr, location) ->
F.fprintf f "potentially invalidated by call to `%a(%a, ..)` at %a" std_vector_function_pp F.fprintf f "potentially invalidated by call to `%a(%a, ..)` at %a" std_vector_function_pp
std_vector_f AccessExpression.pp access_expr Location.pp location std_vector_f HilExp.AccessExpression.pp access_expr Location.pp location

@ -9,11 +9,11 @@ open! IStd
type std_vector_function = PushBack | Reserve [@@deriving compare] type std_vector_function = PushBack | Reserve [@@deriving compare]
type t = type t =
| CFree of AccessExpression.t * Location.t | CFree of HilExp.AccessExpression.t * Location.t
| CppDelete of AccessExpression.t * Location.t | CppDelete of HilExp.AccessExpression.t * Location.t
| CppDestructor of Typ.Procname.t * AccessExpression.t * Location.t | CppDestructor of Typ.Procname.t * HilExp.AccessExpression.t * Location.t
| Nullptr | Nullptr
| StdVector of std_vector_function * AccessExpression.t * Location.t | StdVector of std_vector_function * HilExp.AccessExpression.t * Location.t
[@@deriving compare] [@@deriving compare]
val issue_type_of_cause : t -> IssueType.t val issue_type_of_cause : t -> IssueType.t

@ -80,10 +80,10 @@ module StdVector = struct
"__internal_array" "__internal_array"
let to_internal_array vector = AccessExpression.field_offset vector internal_array let to_internal_array vector = HilExp.AccessExpression.field_offset vector internal_array
let deref_internal_array vector = let deref_internal_array vector =
AccessExpression.(array_offset (dereference (to_internal_array vector)) Typ.void []) HilExp.AccessExpression.(array_offset (dereference (to_internal_array vector)) Typ.void [])
let reallocate_internal_array vector vector_f location astate = let reallocate_internal_array vector vector_f location astate =
@ -100,7 +100,8 @@ module StdVector = struct
match actuals with match actuals with
| [AccessExpression vector; _index] -> | [AccessExpression vector; _index] ->
PulseDomain.read location (deref_internal_array vector) astate PulseDomain.read location (deref_internal_array vector) astate
>>= fun (astate, loc) -> PulseDomain.write location (AccessExpression.base ret) loc astate >>= fun (astate, loc) ->
PulseDomain.write location (HilExp.AccessExpression.base ret) loc astate
| _ -> | _ ->
Ok (PulseDomain.havoc_var (fst ret) astate) Ok (PulseDomain.havoc_var (fst ret) astate)

@ -37,13 +37,13 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(* given a heap access to ae, find which parameter indices of pdesc (* given a heap access to ae, find which parameter indices of pdesc
it modifies *) it modifies *)
let track_modified_params formals ae = let track_modified_params formals ae =
let base_var, _ = AccessExpression.get_base ae in let base_var, _ = HilExp.AccessExpression.get_base ae in
let modified_params = get_modified_params formals ~f:(Var.equal base_var) in let modified_params = get_modified_params formals ~f:(Var.equal base_var) in
Domain.impure modified_params Domain.impure modified_params
let rec is_heap_access ae = let rec is_heap_access ae =
match (ae : AccessExpression.t) with match (ae : HilExp.AccessExpression.t) with
| FieldOffset _ | ArrayOffset _ -> | FieldOffset _ | ArrayOffset _ ->
true true
| Dereference ae | AddressOf ae -> | Dereference ae | AddressOf ae ->
@ -74,7 +74,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
debug "Argument %a is modified.\n" HilExp.pp arg_exp ; debug "Argument %a is modified.\n" HilExp.pp arg_exp ;
HilExp.get_access_exprs arg_exp HilExp.get_access_exprs arg_exp
|> List.fold ~init:modified_acc ~f:(fun modified_acc ae -> |> List.fold ~init:modified_acc ~f:(fun modified_acc ae ->
ModifiedVarSet.add (AccessExpression.get_base ae |> fst) modified_acc ) ) ModifiedVarSet.add (HilExp.AccessExpression.get_base ae |> fst) modified_acc ) )
else modified_acc ) else modified_acc )
callee_args callee_args
in in

@ -51,7 +51,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let report_intra access_expr loc summary = let report_intra access_expr loc summary =
let message = let message =
F.asprintf "The value read from %a was never initialized" AccessExpression.pp access_expr F.asprintf "The value read from %a was never initialized" HilExp.AccessExpression.pp
access_expr
in in
let ltr = [Errlog.make_trace_element 0 loc "" []] in let ltr = [Errlog.make_trace_element 0 loc "" []] in
Reporting.log_error summary ~loc ~ltr IssueType.uninitialized_value message Reporting.log_error summary ~loc ~ltr IssueType.uninitialized_value message
@ -64,8 +65,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let get_formals pname = Ondemand.get_proc_desc pname |> Option.map ~f:Procdesc.get_formals let get_formals pname = Ondemand.get_proc_desc pname |> Option.map ~f:Procdesc.get_formals
let should_report_var pdesc tenv maybe_uninit_vars access_expr = let should_report_var pdesc tenv maybe_uninit_vars access_expr =
let base = AccessExpression.get_base access_expr in let base = HilExp.AccessExpression.get_base access_expr in
match (AccessExpression.get_typ access_expr tenv, base) with match (HilExp.AccessExpression.get_typ access_expr tenv, base) with
| Some typ, (Var.ProgramVar pv, _) -> | Some typ, (Var.ProgramVar pv, _) ->
(not (Pvar.is_frontend_tmp pv)) (not (Pvar.is_frontend_tmp pv))
&& (not (Procdesc.is_captured_var pdesc pv)) && (not (Procdesc.is_captured_var pdesc pv))
@ -85,13 +86,13 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let is_struct_field_passed_by_ref callee_formals t access_expr idx = let is_struct_field_passed_by_ref callee_formals t access_expr idx =
is_struct t is_struct t
&& (not (AccessExpression.is_base access_expr)) && (not (HilExp.AccessExpression.is_base access_expr))
&& function_expects_a_pointer_as_nth_param callee_formals idx && function_expects_a_pointer_as_nth_param callee_formals idx
let is_array_element_passed_by_ref callee_formals t access_expr idx = let is_array_element_passed_by_ref callee_formals t access_expr idx =
is_array t is_array t
&& (not (AccessExpression.is_base access_expr)) && (not (HilExp.AccessExpression.is_base access_expr))
&& function_expects_a_pointer_as_nth_param callee_formals idx && function_expects_a_pointer_as_nth_param callee_formals idx
@ -105,7 +106,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
List.iteri actuals ~f:(fun idx e -> List.iteri actuals ~f:(fun idx e ->
match HilExp.ignore_cast e with match HilExp.ignore_cast e with
| HilExp.AccessExpression access_expr -> | HilExp.AccessExpression access_expr ->
let _, t = AccessExpression.get_base access_expr in let _, t = HilExp.AccessExpression.get_base access_expr in
if if
should_report_var pdesc tenv maybe_uninit_vars access_expr should_report_var pdesc tenv maybe_uninit_vars access_expr
&& (not (Typ.is_pointer t)) && (not (Typ.is_pointer t))
@ -129,10 +130,10 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let is_pointer_assignment tenv lhs rhs = let is_pointer_assignment tenv lhs rhs =
let _, base_typ = AccessExpression.get_base lhs in let _, base_typ = HilExp.AccessExpression.get_base lhs in
HilExp.is_null_literal rhs HilExp.is_null_literal rhs
(* the rhs has type int when assigning the lhs to null *) (* the rhs has type int when assigning the lhs to null *)
|| Option.equal Typ.equal (AccessExpression.get_typ lhs tenv) (HilExp.get_typ tenv rhs) || Option.equal Typ.equal (HilExp.AccessExpression.get_typ lhs tenv) (HilExp.get_typ tenv rhs)
&& Typ.is_pointer base_typ && Typ.is_pointer base_typ
@ -147,7 +148,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
if if
D.exists D.exists
(fun access_expr -> (fun access_expr ->
let base = AccessExpression.get_base access_expr in let base = HilExp.AccessExpression.get_base access_expr in
AccessPath.equal_base base (var_fparam, t) ) AccessPath.equal_base base (var_fparam, t) )
init_formal_params init_formal_params
then Some var_fparam then Some var_fparam
@ -161,7 +162,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Some var_formal -> | Some var_formal ->
let maybe_uninit_vars = MaybeUninitVars.remove access_expr maybe_uninit_vars in let maybe_uninit_vars = MaybeUninitVars.remove access_expr maybe_uninit_vars in
if remove_fields then if remove_fields then
let base = AccessExpression.get_base access_expr in let base = HilExp.AccessExpression.get_base access_expr in
let init_formals' = MaybeUninitVars.of_list (D.elements init_formals) in let init_formals' = MaybeUninitVars.of_list (D.elements init_formals) in
MaybeUninitVars.remove_init_fields base var_formal maybe_uninit_vars init_formals' MaybeUninitVars.remove_init_fields base var_formal maybe_uninit_vars init_formals'
else maybe_uninit_vars else maybe_uninit_vars
@ -195,12 +196,12 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
() ()
in in
let update_prepost access_expr rhs = let update_prepost access_expr rhs =
let lhs_base = AccessExpression.get_base access_expr in let lhs_base = HilExp.AccessExpression.get_base access_expr in
if if
FormalMap.is_formal lhs_base formals FormalMap.is_formal lhs_base formals
&& Typ.is_pointer (snd lhs_base) && Typ.is_pointer (snd lhs_base)
&& ( (not (is_pointer_assignment tenv access_expr rhs)) && ( (not (is_pointer_assignment tenv access_expr rhs))
|| not (AccessExpression.is_base access_expr) ) || not (HilExp.AccessExpression.is_base access_expr) )
then then
let pre = D.add access_expr astate.prepost.UninitDomain.pre in let pre = D.add access_expr astate.prepost.UninitDomain.pre in
{astate.prepost with pre} {astate.prepost with pre}
@ -209,16 +210,16 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
match instr with match instr with
| Assign (lhs_access_expr, rhs_expr, loc) -> | Assign (lhs_access_expr, rhs_expr, loc) ->
(* check on lhs_typ to avoid false positive when assigning a pointer to another *) (* check on lhs_typ to avoid false positive when assigning a pointer to another *)
( match AccessExpression.get_typ lhs_access_expr tenv with ( match HilExp.AccessExpression.get_typ lhs_access_expr tenv with
| Some lhs_typ when not (Typ.is_reference lhs_typ) -> | Some lhs_typ when not (Typ.is_reference lhs_typ) ->
check_hil_expr ~loc rhs_expr check_hil_expr ~loc rhs_expr
| _ -> | _ ->
() ) ; () ) ;
let maybe_uninit_vars = MaybeUninitVars.remove lhs_access_expr astate.maybe_uninit_vars in let maybe_uninit_vars = MaybeUninitVars.remove lhs_access_expr astate.maybe_uninit_vars in
let maybe_uninit_vars = let maybe_uninit_vars =
if AccessExpression.is_base lhs_access_expr then if HilExp.AccessExpression.is_base lhs_access_expr then
(* if we assign to the root of a struct then we need to remove all the fields *) (* if we assign to the root of a struct then we need to remove all the fields *)
let lhs_base = AccessExpression.get_base lhs_access_expr in let lhs_base = HilExp.AccessExpression.get_base lhs_access_expr in
MaybeUninitVars.remove_all_fields tenv lhs_base maybe_uninit_vars MaybeUninitVars.remove_all_fields tenv lhs_base maybe_uninit_vars
|> MaybeUninitVars.remove_dereference_access lhs_base |> MaybeUninitVars.remove_dereference_access lhs_base
else maybe_uninit_vars else maybe_uninit_vars
@ -259,7 +260,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let access_expr_to_remove = let access_expr_to_remove =
match access_expr with AddressOf ae -> ae | _ -> access_expr match access_expr with AddressOf ae -> ae | _ -> access_expr
in in
match AccessExpression.get_base access_expr with match HilExp.AccessExpression.get_base access_expr with
| _, {Typ.desc= Tarray _} when is_initializing_all_args -> | _, {Typ.desc= Tarray _} when is_initializing_all_args ->
MaybeUninitVars.remove access_expr acc MaybeUninitVars.remove access_expr acc
| _, t | _, t
@ -285,7 +286,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| HilExp.Closure (_, apl) -> | HilExp.Closure (_, apl) ->
(* remove the captured variables of a block/lambda *) (* remove the captured variables of a block/lambda *)
List.fold apl ~init:acc ~f:(fun acc (base, _) -> List.fold apl ~init:acc ~f:(fun acc (base, _) ->
MaybeUninitVars.remove (AccessExpression.base base) acc ) MaybeUninitVars.remove (HilExp.AccessExpression.base base) acc )
| _ -> | _ ->
acc ) acc )
in in
@ -301,6 +302,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| ExitScope _ -> | ExitScope _ ->
astate astate
let pp_session_name node fmt = F.fprintf fmt "uninit %a" CFG.Node.pp_id (CFG.Node.id node) let pp_session_name node fmt = F.fprintf fmt "uninit %a" CFG.Node.pp_id (CFG.Node.id node)
end end
@ -312,7 +314,7 @@ module Initial = struct
List.fold (Procdesc.get_locals pdesc) ~init:[] List.fold (Procdesc.get_locals pdesc) ~init:[]
~f:(fun acc (var_data : ProcAttributes.var_data) -> ~f:(fun acc (var_data : ProcAttributes.var_data) ->
let pvar = Pvar.mk var_data.name (Procdesc.get_proc_name pdesc) in let pvar = Pvar.mk var_data.name (Procdesc.get_proc_name pdesc) in
let base_access_expr = AccessExpression.base (Var.of_pvar pvar, var_data.typ) in let base_access_expr = HilExp.AccessExpression.base (Var.of_pvar pvar, var_data.typ) in
match var_data.typ.Typ.desc with match var_data.typ.Typ.desc with
| Typ.Tstruct qual_name | Typ.Tstruct qual_name
(* T30105165 remove filtering after we improve union translation *) (* T30105165 remove filtering after we improve union translation *)
@ -322,7 +324,7 @@ module Initial = struct
let flist = let flist =
List.fold List.fold
~f:(fun acc' (fn, _, _) -> ~f:(fun acc' (fn, _, _) ->
AccessExpression.field_offset base_access_expr fn :: acc' ) HilExp.AccessExpression.field_offset base_access_expr fn :: acc' )
~init:acc fields ~init:acc fields
in in
base_access_expr :: flist base_access_expr :: flist
@ -331,9 +333,9 @@ module Initial = struct
| _ -> | _ ->
acc ) acc )
| Typ.Tarray {elt} -> | Typ.Tarray {elt} ->
AccessExpression.array_offset base_access_expr elt [] :: acc HilExp.AccessExpression.array_offset base_access_expr elt [] :: acc
| Typ.Tptr _ -> | Typ.Tptr _ ->
base_access_expr :: AccessExpression.dereference base_access_expr :: acc base_access_expr :: HilExp.AccessExpression.dereference base_access_expr :: acc
| _ -> | _ ->
base_access_expr :: acc ) base_access_expr :: acc )
end end

@ -7,15 +7,15 @@
open! IStd open! IStd
module F = Format module F = Format
module Domain = AbstractDomain.InvertedSet (AccessExpression) module Domain = AbstractDomain.InvertedSet (HilExp.AccessExpression)
module MaybeUninitVars = struct module MaybeUninitVars = struct
include AbstractDomain.FiniteSet (AccessExpression) include AbstractDomain.FiniteSet (HilExp.AccessExpression)
let subst_formal_actual_fields formal_var actual_base_var init_formals = let subst_formal_actual_fields formal_var actual_base_var init_formals =
map map
(fun access_expr -> (fun access_expr ->
let v, t = AccessExpression.get_base access_expr in let v, t = HilExp.AccessExpression.get_base access_expr in
let v' = if Var.equal v formal_var then actual_base_var else v in let v' = if Var.equal v formal_var then actual_base_var else v in
let t' = let t' =
match t.desc with match t.desc with
@ -28,7 +28,7 @@ module MaybeUninitVars = struct
| _ -> | _ ->
t t
in in
AccessExpression.replace_base ~remove_deref_after_base:true (v', t') access_expr ) HilExp.AccessExpression.replace_base ~remove_deref_after_base:true (v', t') access_expr )
init_formals init_formals
@ -50,7 +50,9 @@ module MaybeUninitVars = struct
match Tenv.lookup tenv name_struct with match Tenv.lookup tenv name_struct with
| Some {fields} -> | Some {fields} ->
List.fold fields ~init:maybe_uninit_vars ~f:(fun acc (fn, _, _) -> List.fold fields ~init:maybe_uninit_vars ~f:(fun acc (fn, _, _) ->
remove (AccessExpression.field_offset (AccessExpression.base base) fn) acc ) remove
(HilExp.AccessExpression.field_offset (HilExp.AccessExpression.base base) fn)
acc )
| _ -> | _ ->
maybe_uninit_vars ) maybe_uninit_vars )
| _ -> | _ ->
@ -60,7 +62,9 @@ module MaybeUninitVars = struct
let remove_dereference_access base maybe_uninit_vars = let remove_dereference_access base maybe_uninit_vars =
match base with match base with
| _, {Typ.desc= Tptr _} -> | _, {Typ.desc= Tptr _} ->
remove (AccessExpression.dereference (AccessExpression.base base)) maybe_uninit_vars remove
(HilExp.AccessExpression.dereference (HilExp.AccessExpression.base base))
maybe_uninit_vars
| _ -> | _ ->
maybe_uninit_vars maybe_uninit_vars
@ -69,14 +73,14 @@ module MaybeUninitVars = struct
match base with match base with
| _, {Typ.desc= Tptr (elt, _)} -> | _, {Typ.desc= Tptr (elt, _)} ->
remove remove
(AccessExpression.array_offset (AccessExpression.base base) elt []) (HilExp.AccessExpression.array_offset (HilExp.AccessExpression.base base) elt [])
maybe_uninit_vars maybe_uninit_vars
| _ -> | _ ->
maybe_uninit_vars maybe_uninit_vars
let remove_everything_under tenv access_expr maybe_uninit_vars = let remove_everything_under tenv access_expr maybe_uninit_vars =
let base = AccessExpression.get_base access_expr in let base = HilExp.AccessExpression.get_base access_expr in
maybe_uninit_vars |> remove access_expr |> remove_all_fields tenv base maybe_uninit_vars |> remove access_expr |> remove_all_fields tenv base
|> remove_all_array_elements base |> remove_dereference_access base |> remove_all_array_elements base |> remove_dereference_access base
end end

@ -49,7 +49,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
in in
let is_receiver_safe = function let is_receiver_safe = function
| HilExp.AccessExpression receiver_access_exp :: _ -> ( | HilExp.AccessExpression receiver_access_exp :: _ -> (
let receiver_access_path = AccessExpression.to_access_path receiver_access_exp in let receiver_access_path = HilExp.AccessExpression.to_access_path receiver_access_exp in
match AccessPath.truncate receiver_access_path with match AccessPath.truncate receiver_access_path with
| receiver_prefix, Some receiver_field -> | receiver_prefix, Some receiver_field ->
is_safe_access receiver_field receiver_prefix tenv is_safe_access receiver_field receiver_prefix tenv
@ -109,7 +109,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
in in
List.fold List.fold
~f:(fun acc access_expr -> ~f:(fun acc access_expr ->
let base, accesses = AccessExpression.to_access_path access_expr in let base, accesses = HilExp.AccessExpression.to_access_path access_expr in
add_field_accesses (base, []) acc accesses ) add_field_accesses (base, []) acc accesses )
~init:accesses (HilExp.get_access_exprs exp) ~init:accesses (HilExp.get_access_exprs exp)
@ -176,7 +176,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let get_receiver_ap actuals = let get_receiver_ap actuals =
match List.hd actuals with match List.hd actuals with
| Some (HilExp.AccessExpression receiver_expr) -> | Some (HilExp.AccessExpression receiver_expr) ->
AccessExpression.to_access_path receiver_expr HilExp.AccessExpression.to_access_path receiver_expr
| _ -> | _ ->
L.(die InternalError) L.(die InternalError)
"Call to %a is marked as a container write, but has no receiver" Typ.Procname.pp "Call to %a is marked as a container write, but has no receiver" Typ.Procname.pp
@ -206,7 +206,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
else else
let rec get_access_path = function let rec get_access_path = function
| HilExp.AccessExpression access_expr -> | HilExp.AccessExpression access_expr ->
Some (AccessExpression.to_access_path access_expr) Some (HilExp.AccessExpression.to_access_path access_expr)
| HilExp.Cast (_, e) | HilExp.Exception e -> | HilExp.Cast (_, e) | HilExp.Exception e ->
get_access_path e get_access_path e
| _ -> | _ ->
@ -246,7 +246,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(* the actual is a constant, so it's owned in the caller. *) (* the actual is a constant, so it's owned in the caller. *)
Conjunction actual_indexes Conjunction actual_indexes
| HilExp.AccessExpression access_expr -> ( | HilExp.AccessExpression access_expr -> (
let actual_access_path = AccessExpression.to_access_path access_expr in let actual_access_path = HilExp.AccessExpression.to_access_path access_expr in
if OwnershipDomain.is_owned actual_access_path caller_astate.ownership then if OwnershipDomain.is_owned actual_access_path caller_astate.ownership then
(* the actual passed to the current callee is owned. drop all the conditional accesses (* the actual passed to the current callee is owned. drop all the conditional accesses
for that actual, since they're all safe *) for that actual, since they're all safe *)
@ -329,7 +329,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
if is_box callee_pname then if is_box callee_pname then
match actuals with match actuals with
| HilExp.AccessExpression actual_access_expr :: _ -> | HilExp.AccessExpression actual_access_expr :: _ ->
let actual_ap = AccessExpression.to_access_path actual_access_expr in let actual_ap = HilExp.AccessExpression.to_access_path actual_access_expr in
if AttributeMapDomain.has_attribute actual_ap Functional astate.attribute_map then if AttributeMapDomain.has_attribute actual_ap Functional astate.attribute_map then
(* TODO: check for constants, which are functional? *) (* TODO: check for constants, which are functional? *)
let attribute_map = let attribute_map =
@ -484,13 +484,13 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
in in
{astate_callee with ownership; attribute_map} {astate_callee with ownership; attribute_map}
| Assign (lhs_access_expr, rhs_exp, loc) -> | Assign (lhs_access_expr, rhs_exp, loc) ->
let lhs_access_path = AccessExpression.to_access_path lhs_access_expr in let lhs_access_path = HilExp.AccessExpression.to_access_path lhs_access_expr in
let rhs_accesses = let rhs_accesses =
add_access rhs_exp loc ~is_write_access:false astate.accesses astate.locks astate.threads add_access rhs_exp loc ~is_write_access:false astate.accesses astate.locks astate.threads
astate.ownership proc_data astate.ownership proc_data
in in
let rhs_access_paths = let rhs_access_paths =
AccessExpression.to_access_paths (HilExp.get_access_exprs rhs_exp) HilExp.AccessExpression.to_access_paths (HilExp.get_access_exprs rhs_exp)
in in
let is_functional = let is_functional =
(not (List.is_empty rhs_access_paths)) (not (List.is_empty rhs_access_paths))
@ -514,8 +514,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
report spurious read/write races *) report spurious read/write races *)
rhs_accesses rhs_accesses
else else
add_access (AccessExpression lhs_access_expr) loc ~is_write_access:true rhs_accesses add_access (HilExp.AccessExpression lhs_access_expr) loc ~is_write_access:true
astate.locks astate.threads astate.ownership proc_data rhs_accesses astate.locks astate.threads astate.ownership proc_data
in in
let ownership = let ownership =
OwnershipDomain.propagate_assignment lhs_access_path rhs_exp astate.ownership OwnershipDomain.propagate_assignment lhs_access_path rhs_exp astate.ownership
@ -536,7 +536,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
evaluating it *) evaluating it *)
and eval_bexp var = function and eval_bexp var = function
| HilExp.AccessExpression access_expr -> | HilExp.AccessExpression access_expr ->
if AccessPath.equal (AccessExpression.to_access_path access_expr) var then Some true if AccessPath.equal (HilExp.AccessExpression.to_access_path access_expr) var then
Some true
else None else None
| HilExp.Constant c -> | HilExp.Constant c ->
Some (not (Const.iszero_int_float c)) Some (not (Const.iszero_int_float c))
@ -575,7 +576,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let astate' = let astate' =
match HilExp.get_access_exprs assume_exp with match HilExp.get_access_exprs assume_exp with
| [access_expr] -> ( | [access_expr] -> (
let access_path = AccessExpression.to_access_path access_expr in let access_path = HilExp.AccessExpression.to_access_path access_expr in
let choices = AttributeMapDomain.get_choices access_path astate.attribute_map in let choices = AttributeMapDomain.get_choices access_path astate.attribute_map in
match eval_bexp access_path assume_exp with match eval_bexp access_path assume_exp with
| Some bool_value -> | Some bool_value ->

@ -46,7 +46,7 @@ let timeunit_of_exp =
in in
let str_of_exp = function let str_of_exp = function
| HilExp.AccessExpression timeunit_acc_exp -> | HilExp.AccessExpression timeunit_acc_exp ->
AccessExpression.to_access_path timeunit_acc_exp |> str_of_access_path HilExp.AccessExpression.to_access_path timeunit_acc_exp |> str_of_access_path
| _ -> | _ ->
None None
in in

@ -65,7 +65,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
in in
let get_lock_path = function let get_lock_path = function
| HilExp.AccessExpression access_exp -> ( | HilExp.AccessExpression access_exp -> (
match AccessExpression.to_access_path access_exp with match HilExp.AccessExpression.to_access_path access_exp with
| (((Var.ProgramVar pvar, _) as base), _) as path | (((Var.ProgramVar pvar, _) as base), _) as path
when FormalMap.is_formal base extras || Pvar.is_global pvar -> when FormalMap.is_formal base extras || Pvar.is_global pvar ->
Some (AccessPath.inner_class_normalize path) Some (AccessPath.inner_class_normalize path)

@ -229,7 +229,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| [arg] when HilExp.is_null_literal arg -> | [arg] when HilExp.is_null_literal arg ->
astate astate
| HilExp.AccessExpression access_expr :: other_args -> | HilExp.AccessExpression access_expr :: other_args ->
let ap = AccessExpression.to_access_path access_expr in let ap = HilExp.AccessExpression.to_access_path access_expr in
check_nil_in_objc_container proc_data loc other_args (check_ap proc_data loc ap astate) check_nil_in_objc_container proc_data loc other_args (check_ap proc_data loc ap astate)
| _ :: other_args -> | _ :: other_args ->
check_nil_in_objc_container proc_data loc other_args astate check_nil_in_objc_container proc_data loc other_args astate
@ -257,7 +257,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
remove_nullable_ap (ret_var, []) astate remove_nullable_ap (ret_var, []) astate
| Call (_, Direct callee_pname, HilExp.AccessExpression receiver :: _, _, _) | Call (_, Direct callee_pname, HilExp.AccessExpression receiver :: _, _, _)
when Models.is_check_not_null callee_pname -> when Models.is_check_not_null callee_pname ->
assume_pnames_notnull (AccessExpression.to_access_path receiver) astate assume_pnames_notnull (HilExp.AccessExpression.to_access_path receiver) astate
| Call (_, Direct callee_pname, _, _, _) when is_blacklisted_method callee_pname -> | Call (_, Direct callee_pname, _, _, _) when is_blacklisted_method callee_pname ->
astate astate
| Call (ret_var, Direct callee_pname, _, _, loc) | Call (ret_var, Direct callee_pname, _, _, loc)
@ -269,7 +269,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
check_nil_in_objc_container proc_data loc args astate check_nil_in_objc_container proc_data loc args astate
| Call (_, Direct callee_pname, HilExp.AccessExpression receiver :: _, _, loc) | Call (_, Direct callee_pname, HilExp.AccessExpression receiver :: _, _, loc)
when is_non_objc_instance_method callee_pname -> when is_non_objc_instance_method callee_pname ->
check_ap proc_data loc (AccessExpression.to_access_path receiver) astate check_ap proc_data loc (HilExp.AccessExpression.to_access_path receiver) astate
| Call | Call
( ((_, ret_typ) as ret_var) ( ((_, ret_typ) as ret_var)
, Direct callee_pname , Direct callee_pname
@ -277,7 +277,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
, _ , _
, _ ) , _ )
when Typ.is_pointer ret_typ && is_objc_instance_method callee_pname -> ( when Typ.is_pointer ret_typ && is_objc_instance_method callee_pname -> (
match longest_nullable_prefix (AccessExpression.to_access_path receiver) astate with match longest_nullable_prefix (HilExp.AccessExpression.to_access_path receiver) astate with
| None -> | None ->
astate astate
| Some (_, call_sites) -> | Some (_, call_sites) ->
@ -286,7 +286,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Call (ret_var, _, _, _, _) -> | Call (ret_var, _, _, _, _) ->
remove_nullable_ap (ret_var, []) astate remove_nullable_ap (ret_var, []) astate
| Assign (lhs_access_expr, rhs, loc) -> ( | Assign (lhs_access_expr, rhs, loc) -> (
let lhs = AccessExpression.to_access_path lhs_access_expr in let lhs = HilExp.AccessExpression.to_access_path lhs_access_expr in
Option.iter Option.iter
~f:(fun (nullable_ap, call_sites) -> ~f:(fun (nullable_ap, call_sites) ->
if not (is_pointer_assignment proc_data.ProcData.tenv nullable_ap rhs) then if not (is_pointer_assignment proc_data.ProcData.tenv nullable_ap rhs) then
@ -298,7 +298,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| HilExp.AccessExpression access_expr -> ( | HilExp.AccessExpression access_expr -> (
try try
(* Add the lhs to the list of nullable values if the rhs is nullable *) (* Add the lhs to the list of nullable values if the rhs is nullable *)
let ap = AccessExpression.to_access_path access_expr in let ap = HilExp.AccessExpression.to_access_path access_expr in
add_nullable_ap lhs (find_nullable_ap ap astate) astate add_nullable_ap lhs (find_nullable_ap ap astate) astate
with Caml.Not_found -> with Caml.Not_found ->
(* Remove the lhs from the list of nullable values if the rhs is not nullable *) (* Remove the lhs from the list of nullable values if the rhs is not nullable *)
@ -307,7 +307,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(* Remove the lhs from the list of nullable values if the rhs is not an access path *) (* Remove the lhs from the list of nullable values if the rhs is not an access path *)
remove_nullable_ap lhs astate ) remove_nullable_ap lhs astate )
| Assume (HilExp.AccessExpression access_expr, _, _, _) -> | Assume (HilExp.AccessExpression access_expr, _, _, _) ->
assume_pnames_notnull (AccessExpression.to_access_path access_expr) astate assume_pnames_notnull (HilExp.AccessExpression.to_access_path access_expr) astate
| Assume | Assume
( ( HilExp.BinaryOperator (Binop.Ne, HilExp.AccessExpression access_expr, exp) ( ( HilExp.BinaryOperator (Binop.Ne, HilExp.AccessExpression access_expr, exp)
| HilExp.BinaryOperator (Binop.Ne, exp, HilExp.AccessExpression access_expr) ) | HilExp.BinaryOperator (Binop.Ne, exp, HilExp.AccessExpression access_expr) )
@ -324,7 +324,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
, _ , _
, _ ) -> , _ ) ->
if HilExp.is_null_literal exp then if HilExp.is_null_literal exp then
assume_pnames_notnull (AccessExpression.to_access_path access_expr) astate assume_pnames_notnull (HilExp.AccessExpression.to_access_path access_expr) astate
else astate else astate
| _ -> | _ ->
astate astate

@ -66,7 +66,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
Some (UseDefChain.NullDefAssign (loc, lhs)) Some (UseDefChain.NullDefAssign (loc, lhs))
| HilExp.AccessExpression access_expr -> ( | HilExp.AccessExpression access_expr -> (
try try
let ap = AccessExpression.to_access_path access_expr in let ap = HilExp.AccessExpression.to_access_path access_expr in
match Domain.find ap astate with match Domain.find ap astate with
| UseDefChain.NullDefCompare _ -> | UseDefChain.NullDefCompare _ ->
(* Stop NullDefCompare from propagating here because we want to prevent (* Stop NullDefCompare from propagating here because we want to prevent
@ -85,7 +85,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
extract_null_compare_expr e extract_null_compare_expr e
| HilExp.BinaryOperator ((Eq | Ne), HilExp.AccessExpression access_expr, exp) | HilExp.BinaryOperator ((Eq | Ne), HilExp.AccessExpression access_expr, exp)
| HilExp.BinaryOperator ((Eq | Ne), exp, HilExp.AccessExpression access_expr) -> | HilExp.BinaryOperator ((Eq | Ne), exp, HilExp.AccessExpression access_expr) ->
Option.some_if (HilExp.is_null_literal exp) (AccessExpression.to_access_path access_expr) Option.some_if (HilExp.is_null_literal exp)
(HilExp.AccessExpression.to_access_path access_expr)
| _ -> | _ ->
None None
@ -103,7 +104,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(* For now we just assume the callee always return non-null *) (* For now we just assume the callee always return non-null *)
astate astate
| Assign (lhs_access_expr, rhs, loc) -> | Assign (lhs_access_expr, rhs, loc) ->
let lhs = AccessExpression.to_access_path lhs_access_expr in let lhs = HilExp.AccessExpression.to_access_path lhs_access_expr in
if not (is_access_nullable lhs proc_data) then if not (is_access_nullable lhs proc_data) then
match nullable_usedef_chain_of rhs lhs astate loc with match nullable_usedef_chain_of rhs lhs astate loc with
| Some udchain -> | Some udchain ->

@ -33,7 +33,7 @@ include TaintAnalysis.Make (struct
(* "this" is always the first arg of a constructor; propagate taint there *) (* "this" is always the first arg of a constructor; propagate taint there *)
[TaintSpec.Propagate_to_receiver] [TaintSpec.Propagate_to_receiver]
| Tvoid, HilExp.AccessExpression access_expr :: _ -> ( | Tvoid, HilExp.AccessExpression access_expr :: _ -> (
match AccessExpression.to_access_path access_expr with match HilExp.AccessExpression.to_access_path access_expr with
| (Var.ProgramVar pvar, {desc= Typ.Tptr (_, Typ.Pk_pointer)}), [] | (Var.ProgramVar pvar, {desc= Typ.Tptr (_, Typ.Pk_pointer)}), []
when Pvar.is_frontend_tmp pvar -> when Pvar.is_frontend_tmp pvar ->
(* no return value, but the frontend has introduced a dummy return variable and will (* no return value, but the frontend has introduced a dummy return variable and will

@ -97,7 +97,7 @@ module SourceKind = struct
(* accessed global will be passed to us as the only parameter *) (* accessed global will be passed to us as the only parameter *)
match List.map actuals ~f:HilExp.ignore_cast with match List.map actuals ~f:HilExp.ignore_cast with
| [HilExp.AccessExpression access_expr] -> | [HilExp.AccessExpression access_expr] ->
let access_path = AccessExpression.to_access_path access_expr in let access_path = HilExp.AccessExpression.to_access_path access_expr in
if is_gflag access_path then if is_gflag access_path then
let (global_pvar, _), _ = access_path in let (global_pvar, _), _ = access_path in
let typ_desc = let typ_desc =

@ -26,7 +26,7 @@ include TaintAnalysis.Make (struct
| HilExp.Cast (_, e) -> | HilExp.Cast (_, e) ->
get_receiver_typ tenv e get_receiver_typ tenv e
| HilExp.AccessExpression access_expr -> | HilExp.AccessExpression access_expr ->
AccessPath.get_typ (AccessExpression.to_access_path access_expr) tenv AccessPath.get_typ (HilExp.AccessExpression.to_access_path access_expr) tenv
| _ -> | _ ->
None None
in in

@ -122,7 +122,7 @@ module SourceKind = struct
(* accessed global will be passed to us as the only parameter *) (* accessed global will be passed to us as the only parameter *)
match List.map actuals ~f:HilExp.ignore_cast with match List.map actuals ~f:HilExp.ignore_cast with
| [HilExp.AccessExpression access_expr] -> ( | [HilExp.AccessExpression access_expr] -> (
match AccessExpression.to_access_path access_expr with match HilExp.AccessExpression.to_access_path access_expr with
| (Var.ProgramVar pvar, _), _ -> | (Var.ProgramVar pvar, _), _ ->
let pvar_string = Pvar.to_string pvar in let pvar_string = Pvar.to_string pvar in
(* checking substring instead of prefix because we expect field names like (* checking substring instead of prefix because we expect field names like

@ -74,7 +74,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
match exp with match exp with
| AccessExpression access_expr -> | AccessExpression access_expr ->
exp_get_node_ ~abstracted exp_get_node_ ~abstracted
(AccessExpression.to_access_path access_expr) (HilExp.AccessExpression.to_access_path access_expr)
access_tree proc_data access_tree proc_data
| Cast (_, e) | Exception e | UnaryOperator (_, e, _) -> | Cast (_, e) | Exception e | UnaryOperator (_, e, _) ->
hil_exp_get_node ~abstracted e access_tree proc_data hil_exp_get_node ~abstracted e access_tree proc_data
@ -101,7 +101,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
match HilExp.ignore_cast (List.nth_exn actuals index) with match HilExp.ignore_cast (List.nth_exn actuals index) with
| HilExp.AccessExpression actual_ae_raw -> | HilExp.AccessExpression actual_ae_raw ->
let actual_ap = let actual_ap =
AccessPath.Abs.Abstracted (AccessExpression.to_access_path actual_ae_raw) AccessPath.Abs.Abstracted (HilExp.AccessExpression.to_access_path actual_ae_raw)
in in
let trace = access_path_get_trace actual_ap access_tree proc_data in let trace = access_path_get_trace actual_ap access_tree proc_data in
TaintDomain.add_trace actual_ap (TraceDomain.add_source source trace) access_tree TaintDomain.add_trace actual_ap (TraceDomain.add_source source trace) access_tree
@ -340,7 +340,8 @@ module Make (TaintSpecification : TaintSpec.S) = struct
(TraceDomain.Sources.Footprint.is_empty (TraceDomain.Sources.Footprint.is_empty
(TraceDomain.sources actual_trace').footprint) -> (TraceDomain.sources actual_trace').footprint) ->
let actual_ap = let actual_ap =
AccessPath.Abs.Abstracted (AccessExpression.to_access_path actual_ae_raw) AccessPath.Abs.Abstracted
(HilExp.AccessExpression.to_access_path actual_ae_raw)
in in
TaintDomain.add_trace actual_ap actual_trace' access_tree_acc TaintDomain.add_trace actual_ap actual_trace' access_tree_acc
| _ -> | _ ->
@ -393,7 +394,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
match Option.map (List.nth actuals (Ident.get_stamp id)) ~f:HilExp.ignore_cast with match Option.map (List.nth actuals (Ident.get_stamp id)) ~f:HilExp.ignore_cast with
| Some (HilExp.AccessExpression actual_ae) -> | Some (HilExp.AccessExpression actual_ae) ->
let projected_ap = let projected_ap =
project ~formal_ap ~actual_ap:(AccessExpression.to_access_path actual_ae) project ~formal_ap ~actual_ap:(HilExp.AccessExpression.to_access_path actual_ae)
in in
let caller_node_opt = access_path_get_node projected_ap access_tree proc_data in let caller_node_opt = access_path_get_node projected_ap access_tree proc_data in
(Some projected_ap, Option.value ~default:TaintDomain.empty_node caller_node_opt) (Some projected_ap, Option.value ~default:TaintDomain.empty_node caller_node_opt)
@ -450,14 +451,14 @@ module Make (TaintSpecification : TaintSpec.S) = struct
existing machinery for adding function call sinks *) existing machinery for adding function call sinks *)
let add_sinks_for_access_path access_expr loc astate = let add_sinks_for_access_path access_expr loc astate =
let rec add_sinks_for_access astate_acc = function let rec add_sinks_for_access astate_acc = function
| AccessExpression.Base _ -> | HilExp.AccessExpression.Base _ ->
astate_acc astate_acc
| AccessExpression.FieldOffset (ae, _) | HilExp.AccessExpression.FieldOffset (ae, _)
| ArrayOffset (ae, _, []) | ArrayOffset (ae, _, [])
| AddressOf ae | AddressOf ae
| Dereference ae -> | Dereference ae ->
add_sinks_for_access astate_acc ae add_sinks_for_access astate_acc ae
| AccessExpression.ArrayOffset (ae, _, indexes) -> | HilExp.AccessExpression.ArrayOffset (ae, _, indexes) ->
let dummy_call_site = CallSite.make BuiltinDecl.__array_access loc in let dummy_call_site = CallSite.make BuiltinDecl.__array_access loc in
let dummy_actuals = let dummy_actuals =
List.map ~f:(fun index_ae -> HilExp.AccessExpression index_ae) indexes List.map ~f:(fun index_ae -> HilExp.AccessExpression index_ae) indexes
@ -475,7 +476,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
add_sinks_for_access astate access_expr add_sinks_for_access astate access_expr
in in
let add_sources_for_access_path access_expr loc astate = let add_sources_for_access_path access_expr loc astate =
let var, _ = AccessExpression.get_base access_expr in let var, _ = HilExp.AccessExpression.get_base access_expr in
if Var.is_global var then if Var.is_global var then
let dummy_call_site = CallSite.make BuiltinDecl.__global_access loc in let dummy_call_site = CallSite.make BuiltinDecl.__global_access loc in
let sources = let sources =
@ -485,7 +486,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
in in
List.fold sources ~init:astate ~f:(fun astate {TraceDomain.Source.source} -> List.fold sources ~init:astate ~f:(fun astate {TraceDomain.Source.source} ->
let access_path = let access_path =
AccessPath.Abs.Exact (AccessExpression.to_access_path access_expr) AccessPath.Abs.Exact (HilExp.AccessExpression.to_access_path access_expr)
in in
let trace, subtree = let trace, subtree =
Option.value ~default:TaintDomain.empty_node Option.value ~default:TaintDomain.empty_node
@ -510,18 +511,17 @@ module Make (TaintSpecification : TaintSpec.S) = struct
let rhs_node = let rhs_node =
Option.value (hil_exp_get_node rhs_exp astate proc_data) ~default:TaintDomain.empty_node Option.value (hil_exp_get_node rhs_exp astate proc_data) ~default:TaintDomain.empty_node
in in
let lhs_access_path = AccessExpression.to_access_path lhs_access_expr in let lhs_access_path = HilExp.AccessExpression.to_access_path lhs_access_expr in
TaintDomain.add_node (AccessPath.Abs.Exact lhs_access_path) rhs_node astate TaintDomain.add_node (AccessPath.Abs.Exact lhs_access_path) rhs_node astate
in in
match instr with match instr with
| Assign (AccessExpression.Base (Var.ProgramVar pvar, _), HilExp.Exception _, _) | Assign (Base (Var.ProgramVar pvar, _), HilExp.Exception _, _) when Pvar.is_return pvar ->
when Pvar.is_return pvar ->
(* the Java frontend translates `throw Exception` as `return Exception`, which is a bit (* the Java frontend translates `throw Exception` as `return Exception`, which is a bit
wonky. this translation causes problems for us in computing a summary when an wonky. this translation causes problems for us in computing a summary when an
exception is "returned" from a void function. skip code like this for now, fix via exception is "returned" from a void function. skip code like this for now, fix via
t14159157 later *) t14159157 later *)
astate astate
| Assign (AccessExpression.Base (Var.ProgramVar pvar, _), rhs_exp, _) | Assign (Base (Var.ProgramVar pvar, _), rhs_exp, _)
when Pvar.is_return pvar && HilExp.is_null_literal rhs_exp when Pvar.is_return pvar && HilExp.is_null_literal rhs_exp
&& Typ.equal_desc Tvoid (Procdesc.get_ret_type proc_data.pdesc).desc -> && Typ.equal_desc Tvoid (Procdesc.get_ret_type proc_data.pdesc).desc ->
(* similar to the case above; the Java frontend translates "return no exception" as (* similar to the case above; the Java frontend translates "return no exception" as
@ -596,13 +596,13 @@ module Make (TaintSpecification : TaintSpec.S) = struct
| ( TaintSpec.Propagate_to_receiver | ( TaintSpec.Propagate_to_receiver
, AccessExpression receiver_ae :: (_ :: _ as other_actuals) ) -> , AccessExpression receiver_ae :: (_ :: _ as other_actuals) ) ->
propagate_to_access_path propagate_to_access_path
(AccessPath.Abs.Abstracted (AccessExpression.to_access_path receiver_ae)) (AccessPath.Abs.Abstracted (HilExp.AccessExpression.to_access_path receiver_ae))
other_actuals astate_acc other_actuals astate_acc
| TaintSpec.Propagate_to_actual actual_index, _ -> ( | TaintSpec.Propagate_to_actual actual_index, _ -> (
match Option.map (List.nth actuals actual_index) ~f:HilExp.ignore_cast with match Option.map (List.nth actuals actual_index) ~f:HilExp.ignore_cast with
| Some (HilExp.AccessExpression actual_ae) -> | Some (HilExp.AccessExpression actual_ae) ->
propagate_to_access_path propagate_to_access_path
(AccessPath.Abs.Abstracted (AccessExpression.to_access_path actual_ae)) (AccessPath.Abs.Abstracted (HilExp.AccessExpression.to_access_path actual_ae))
actuals astate_acc actuals astate_acc
| _ -> | _ ->
astate_acc ) astate_acc )
@ -621,8 +621,8 @@ module Make (TaintSpecification : TaintSpec.S) = struct
| [AccessExpression lhs_access_expr; rhs_exp; HilExp.AccessExpression access_expr] -> ( | [AccessExpression lhs_access_expr; rhs_exp; HilExp.AccessExpression access_expr] -> (
let dummy_ret_access_expr = access_expr in let dummy_ret_access_expr = access_expr in
match dummy_ret_access_expr with match dummy_ret_access_expr with
| AccessExpression.Base (Var.ProgramVar pvar, _) when Pvar.is_frontend_tmp pvar | HilExp.AccessExpression.Base (Var.ProgramVar pvar, _)
-> when Pvar.is_frontend_tmp pvar ->
(* the frontend translates operator=(x, y) as operator=(x, y, dummy_ret) when (* the frontend translates operator=(x, y) as operator=(x, y, dummy_ret) when
operator= returns a value type *) operator= returns a value type *)
exec_write lhs_access_expr rhs_exp access_tree exec_write lhs_access_expr rhs_exp access_tree
@ -652,7 +652,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
assigning to it. understand this pattern by pretending it's the return value *) assigning to it. understand this pattern by pretending it's the return value *)
match List.last actuals with match List.last actuals with
| Some (HilExp.AccessExpression access_expr) -> ( | Some (HilExp.AccessExpression access_expr) -> (
match AccessExpression.to_access_path access_expr with match HilExp.AccessExpression.to_access_path access_expr with
| ((Var.ProgramVar pvar, _) as ret_base), [] when Pvar.is_frontend_tmp pvar -> | ((Var.ProgramVar pvar, _) as ret_base), [] when Pvar.is_frontend_tmp pvar ->
Some ret_base Some ret_base
| _ -> | _ ->

Loading…
Cancel
Save