diff --git a/infer/src/IR/CapturedVar.ml b/infer/src/IR/CapturedVar.ml new file mode 100644 index 000000000..26125f6e3 --- /dev/null +++ b/infer/src/IR/CapturedVar.ml @@ -0,0 +1,15 @@ +(* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +open! IStd +module F = Format + +type t = {name: Mangled.t; typ: Typ.t; capture_mode: Pvar.capture_mode} [@@deriving compare] + +let pp fmt {name; typ; capture_mode} = + F.fprintf fmt "(%a,@,%a,@,%s)" Mangled.pp name (Typ.pp_full Pp.text) typ + (Pvar.string_of_capture_mode capture_mode) diff --git a/infer/src/IR/CapturedVar.mli b/infer/src/IR/CapturedVar.mli new file mode 100644 index 000000000..0603bcb0d --- /dev/null +++ b/infer/src/IR/CapturedVar.mli @@ -0,0 +1,12 @@ +(* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +open! IStd + +type t = {name: Mangled.t; typ: Typ.t; capture_mode: Pvar.capture_mode} [@@deriving compare] + +val pp : Format.formatter -> t -> unit diff --git a/infer/src/IR/DotCfg.ml b/infer/src/IR/DotCfg.ml index 160620092..2118c0868 100644 --- a/infer/src/IR/DotCfg.ml +++ b/infer/src/IR/DotCfg.ml @@ -21,10 +21,10 @@ let pp_etlist fmt etl = let pp_var_list fmt etl = - List.iter etl ~f:(fun (id, ty, mode) -> + List.iter etl ~f:(fun {CapturedVar.name; typ; capture_mode} -> Format.fprintf fmt " [%s]%a:%a" - (Pvar.string_of_capture_mode mode) - Mangled.pp id (Typ.pp_full Pp.text) ty ) + (Pvar.string_of_capture_mode capture_mode) + Mangled.pp name (Typ.pp_full Pp.text) typ ) let pp_local_list fmt etl = List.iter ~f:(Procdesc.pp_local fmt) etl diff --git a/infer/src/IR/ProcAttributes.ml b/infer/src/IR/ProcAttributes.ml index e7d03d941..a9d1004d4 100644 --- a/infer/src/IR/ProcAttributes.ml +++ b/infer/src/IR/ProcAttributes.ml @@ -45,8 +45,7 @@ type specialized_with_blocks_info = type t = { access: PredSymb.access (** visibility access *) - ; captured: (Mangled.t * Typ.t * Pvar.capture_mode) list - (** name and type of variables captured in blocks *) + ; captured: CapturedVar.t list (** name and type of variables captured in blocks *) ; exceptions: string list (** exceptions thrown by the procedure *) ; formals: (Mangled.t * Typ.t) list (** name and type of formal parameters *) ; const_formals: int list (** list of indices of formals that are const-qualified *) @@ -155,12 +154,7 @@ let pp_specialized_with_blocks_info fmt info = info.formals_to_procs_and_new_formals -let pp_captured_var fmt (var, typ, mode) = - F.fprintf fmt "(%a,@,%a,@,%s)" Mangled.pp var (Typ.pp_full Pp.text) typ - (Pvar.string_of_capture_mode mode) - - -let pp_captured = Pp.semicolon_seq ~print_env:Pp.text_break pp_captured_var +let pp_captured = Pp.semicolon_seq ~print_env:Pp.text_break CapturedVar.pp let pp f ({ access @@ -198,8 +192,8 @@ let pp f translation_unit ; if not (PredSymb.equal_access default.access access) then F.fprintf f "; access= %a@," (Pp.of_string ~f:PredSymb.string_of_access) access ; - if not ([%compare.equal: (Mangled.t * Typ.t * Pvar.capture_mode) list] default.captured captured) - then F.fprintf f "; captured= [@[%a@]]@," pp_captured captured ; + if not ([%compare.equal: CapturedVar.t list] default.captured captured) then + F.fprintf f "; captured= [@[%a@]]@," pp_captured captured ; if not ([%compare.equal: string list] default.exceptions exceptions) then F.fprintf f "; exceptions= [@[%a@]]@," (Pp.semicolon_seq ~print_env:Pp.text_break F.pp_print_string) diff --git a/infer/src/IR/ProcAttributes.mli b/infer/src/IR/ProcAttributes.mli index 66bcc1291..34e5afc01 100644 --- a/infer/src/IR/ProcAttributes.mli +++ b/infer/src/IR/ProcAttributes.mli @@ -27,7 +27,7 @@ type specialized_with_blocks_info = type t = { access: PredSymb.access (** visibility access *) - ; captured: (Mangled.t * Typ.t * Pvar.capture_mode) list + ; captured: CapturedVar.t list (** name, type, and mode of variables captured in blocks and lambdas *) ; exceptions: string list (** exceptions thrown by the procedure *) ; formals: (Mangled.t * Typ.t) list (** name and type of formal parameters *) diff --git a/infer/src/IR/Procdesc.ml b/infer/src/IR/Procdesc.ml index 2e70ddca9..07f6735a8 100644 --- a/infer/src/IR/Procdesc.ml +++ b/infer/src/IR/Procdesc.ml @@ -789,10 +789,10 @@ let pp_variable_list fmt etl = let pp_captured_list fmt etl = List.iter - ~f:(fun (id, ty, mode) -> + ~f:(fun {CapturedVar.name; typ; capture_mode} -> Format.fprintf fmt " [%s] %a:%a" - (Pvar.string_of_capture_mode mode) - Mangled.pp id (Typ.pp_full Pp.text) ty ) + (Pvar.string_of_capture_mode capture_mode) + Mangled.pp name (Typ.pp_full Pp.text) typ ) etl @@ -847,7 +847,7 @@ let is_captured_pvar procdesc pvar = | _ -> false in - let pvar_matches_in_captured (name, _, _) = Mangled.equal name pvar_name in + let pvar_matches_in_captured {CapturedVar.name} = Mangled.equal name pvar_name in let is_captured_var_objc_block = (* var is captured if the procedure is a objc block and the var is in the captured *) Procname.is_objc_block procname diff --git a/infer/src/IR/Procdesc.mli b/infer/src/IR/Procdesc.mli index abdc1698e..6380ec137 100644 --- a/infer/src/IR/Procdesc.mli +++ b/infer/src/IR/Procdesc.mli @@ -235,7 +235,7 @@ val get_attributes : t -> ProcAttributes.t val set_attributes : t -> ProcAttributes.t -> unit -val get_captured : t -> (Mangled.t * Typ.t * Pvar.capture_mode) list +val get_captured : t -> CapturedVar.t list (** Return name and type of block's captured variables *) val get_exit_node : t -> Node.t diff --git a/infer/src/biabduction/Rearrange.ml b/infer/src/biabduction/Rearrange.ml index b873c4763..9b2a4fcc5 100644 --- a/infer/src/biabduction/Rearrange.ml +++ b/infer/src/biabduction/Rearrange.ml @@ -1289,7 +1289,9 @@ let check_call_to_objc_block_error tenv pdesc prop fun_exp loc = | Some (_, Exp.Lvar pvar) -> (* pvar is the block *) let name = Pvar.get_name pvar in - List.exists ~f:(fun (cn, _, _) -> Mangled.equal name cn) (Procdesc.get_captured pdesc) + List.exists + ~f:(fun {CapturedVar.name= cn} -> Mangled.equal name cn) + (Procdesc.get_captured pdesc) | _ -> false in diff --git a/infer/src/checkers/SelfInBlock.ml b/infer/src/checkers/SelfInBlock.ml index e08dde3ea..f7eac8536 100644 --- a/infer/src/checkers/SelfInBlock.ml +++ b/infer/src/checkers/SelfInBlock.ml @@ -151,7 +151,8 @@ module TransferFunctions = struct let pvar_name = Pvar.get_name pvar in Pvar.is_self pvar && List.exists - ~f:(fun (captured, typ, _) -> Mangled.equal captured pvar_name && Typ.is_strong_pointer typ) + ~f:(fun {CapturedVar.name= captured; typ} -> + Mangled.equal captured pvar_name && Typ.is_strong_pointer typ ) attributes.ProcAttributes.captured @@ -159,7 +160,7 @@ module TransferFunctions = struct let is_captured_strong_self attributes pvar = (not (Pvar.is_self pvar)) && List.exists - ~f:(fun (captured, typ, _) -> + ~f:(fun {CapturedVar.name= captured; typ} -> Typ.is_strong_pointer typ && Mangled.equal captured (Pvar.get_name pvar) && String.is_suffix ~suffix:"self" (String.lowercase (Mangled.to_string captured)) ) @@ -168,7 +169,7 @@ module TransferFunctions = struct let is_captured_weak_self attributes pvar = List.exists - ~f:(fun (captured, typ, _) -> + ~f:(fun {CapturedVar.name= captured; typ} -> Mangled.equal captured (Pvar.get_name pvar) && String.is_substring ~substring:"self" (String.lowercase (Mangled.to_string captured)) && Typ.is_weak_pointer typ ) diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index d931810e4..e7fc86297 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -206,7 +206,9 @@ let create_local_procdesc ?(set_objc_accessor_attr = false) ?(record_lambda_capt PredSymb.Protected in let captured_mangled = - List.map ~f:(fun (var, t, mode) -> (Pvar.get_name var, t, mode)) captured + List.map + ~f:(fun (var, typ, capture_mode) -> {CapturedVar.name= Pvar.get_name var; typ; capture_mode}) + captured in (* Retrieve captured variables from procdesc created when translating captured variables in lambda expression *) (* We want to do this before `should_create_procdesc` is called as it can remove previous procdesc *) @@ -233,7 +235,7 @@ let create_local_procdesc ?(set_objc_accessor_attr = false) ?(record_lambda_capt (* Captured variables for blocks are treated as parameters, but not for cpp lambdas *) let captured_as_formals = if is_cpp_lambda_call_operator then [] - else List.map ~f:(fun (var, t, _) -> (var, t)) captured_mangled + else List.map ~f:(fun {CapturedVar.name; typ} -> (name, typ)) captured_mangled in let formals = captured_as_formals @ formals in let const_formals = diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index b8c6bf0fe..29e4d44bf 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -829,9 +829,9 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s match procname with | Procname.ObjC_Cpp cpp_pname when Procname.ObjC_Cpp.is_cpp_lambda cpp_pname -> let pvar_name = Pvar.get_name pvar in - List.find (Procdesc.get_captured context.procdesc) ~f:(fun (captured_var, _, _) -> - Mangled.equal captured_var pvar_name ) - |> Option.value_map ~f:(fun (_, t, _) -> t) ~default:typ + List.find (Procdesc.get_captured context.procdesc) + ~f:(fun {CapturedVar.name= captured_var} -> Mangled.equal captured_var pvar_name) + |> Option.value_map ~f:(fun {CapturedVar.typ} -> typ) ~default:typ | _ -> typ in diff --git a/infer/src/pulse/PulseAbductiveDomain.ml b/infer/src/pulse/PulseAbductiveDomain.ml index 64f2c7b61..7eaa43d37 100644 --- a/infer/src/pulse/PulseAbductiveDomain.ml +++ b/infer/src/pulse/PulseAbductiveDomain.ml @@ -313,7 +313,7 @@ let mk_initial proc_desc = Procdesc.get_formals proc_desc |> List.map ~f:(fun (mangled, _) -> init_var mangled) in let captured = - Procdesc.get_captured proc_desc |> List.map ~f:(fun (mangled, _, _) -> init_var mangled) + Procdesc.get_captured proc_desc |> List.map ~f:(fun {CapturedVar.name} -> init_var name) in captured @ formals in diff --git a/infer/src/pulse/PulseOperations.ml b/infer/src/pulse/PulseOperations.ml index 54cb0436f..e66e22707 100644 --- a/infer/src/pulse/PulseOperations.ml +++ b/infer/src/pulse/PulseOperations.ml @@ -521,9 +521,9 @@ let call ~caller_proc_desc err_log ~(callee_data : (Procdesc.t * PulseSummary.t) in let captured_vars = Procdesc.get_captured callee_proc_desc - |> List.map ~f:(fun (mangled, _, mode) -> - let pvar = Pvar.mk mangled callee_pname in - (Var.of_pvar pvar, mode) ) + |> List.map ~f:(fun {CapturedVar.name; capture_mode} -> + let pvar = Pvar.mk name callee_pname in + (Var.of_pvar pvar, capture_mode) ) in let+ astate, captured_vars_with_actuals = match actuals with