diff --git a/infer/src/IR/DotCfg.ml b/infer/src/IR/DotCfg.ml index 7ef246642..43269fcd1 100644 --- a/infer/src/IR/DotCfg.ml +++ b/infer/src/IR/DotCfg.ml @@ -21,8 +21,10 @@ let pp_etlist fmt etl = let pp_var_list fmt etl = - List.iter etl ~f:(fun (id, ty) -> - Format.fprintf fmt " %a:%a" Mangled.pp id (Typ.pp_full Pp.text) ty ) + List.iter etl ~f:(fun (id, ty, mode) -> + Format.fprintf fmt " [%s]%a:%a" + (Pvar.string_of_capture_mode mode) + Mangled.pp id (Typ.pp_full Pp.text) ty ) let pp_local_list fmt etl = List.iter ~f:(Procdesc.pp_local fmt) etl diff --git a/infer/src/IR/Exp.ml b/infer/src/IR/Exp.ml index a0ed6bf07..2fb6bcccf 100644 --- a/infer/src/IR/Exp.ml +++ b/infer/src/IR/Exp.ml @@ -18,7 +18,7 @@ type ident_ = Ident.t let compare_ident_ x y = Ident.compare y x -type closure = {name: Procname.t; captured_vars: (t * Pvar.t * Typ.t) list} +type closure = {name: Procname.t; captured_vars: (t * Pvar.t * Typ.t * Pvar.capture_mode) list} (** This records information about a [sizeof(typ)] expression. @@ -184,7 +184,7 @@ let fold_captured ~f exp acc = fold_captured_ e1 captured_acc |> fold_captured_ e2 | Closure {captured_vars} -> List.fold captured_vars - ~f:(fun acc (captured_exp, _, _) -> f acc captured_exp) + ~f:(fun acc (captured_exp, _, _, _) -> f acc captured_exp) ~init:captured_acc | Const _ | Lvar _ | Var _ | Sizeof _ -> captured_acc @@ -249,12 +249,14 @@ let rec pp_ pe pp_t f e = subtype -and pp_captured_var pe pp_t f (exp, var, typ) = +and pp_captured_var pe pp_t f (exp, var, typ, mode) = match exp with | Lvar evar when Pvar.equal var evar -> (Pvar.pp pe) f var | _ -> - F.fprintf f "(%a %a:%a)" (pp_ pe pp_t) exp (Pvar.pp pe) var (Typ.pp pe) typ + F.fprintf f "([%s]%a %a:%a)" + (Pvar.string_of_capture_mode mode) + (pp_ pe pp_t) exp (Pvar.pp pe) var (Typ.pp pe) typ let pp_printenv ~print_types pe f e = @@ -323,7 +325,7 @@ let rec gen_free_vars = | Cast (_, e) | Exn e | Lfield (e, _, _) | Sizeof {dynamic_length= Some e} | UnOp (_, e, _) -> gen_free_vars e | Closure {captured_vars} -> - ISequence.gen_sequence_list captured_vars ~f:(fun (e, _, _) -> gen_free_vars e) + ISequence.gen_sequence_list captured_vars ~f:(fun (e, _, _, _) -> gen_free_vars e) | Const (Cint _ | Cfun _ | Cstr _ | Cfloat _ | Cclass _) | Lvar _ | Sizeof {dynamic_length= None} -> return () @@ -347,7 +349,7 @@ let rec gen_program_vars = | BinOp (_, e1, e2) | Lindex (e1, e2) -> gen_program_vars e1 >>= fun () -> gen_program_vars e2 | Closure {captured_vars} -> - ISequence.gen_sequence_list captured_vars ~f:(fun (e, _, _) -> gen_program_vars e) + ISequence.gen_sequence_list captured_vars ~f:(fun (e, _, _, _) -> gen_program_vars e) let program_vars e = Sequence.Generator.run (gen_program_vars e) @@ -363,7 +365,7 @@ let rec rename_pvars ~(f : string -> string) : t -> t = | Exn e -> Exn (re e) | Closure {name; captured_vars} -> - let captured_vars = List.map ~f:(function e, v, t -> (re e, rv v, t)) captured_vars in + let captured_vars = List.map ~f:(function e, v, t, m -> (re e, rv v, t, m)) captured_vars in Closure {name; captured_vars} | Cast (t, e) -> Cast (t, re e) diff --git a/infer/src/IR/Exp.mli b/infer/src/IR/Exp.mli index 0b332f64e..c343a73fe 100644 --- a/infer/src/IR/Exp.mli +++ b/infer/src/IR/Exp.mli @@ -13,7 +13,7 @@ open! IStd module F = Format -type closure = {name: Procname.t; captured_vars: (t * Pvar.t * Typ.t) list} +type closure = {name: Procname.t; captured_vars: (t * Pvar.t * Typ.t * Pvar.capture_mode) list} (** This records information about a [sizeof(typ)] expression. diff --git a/infer/src/IR/ProcAttributes.ml b/infer/src/IR/ProcAttributes.ml index 2c356f43a..7a666290b 100644 --- a/infer/src/IR/ProcAttributes.ml +++ b/infer/src/IR/ProcAttributes.ml @@ -39,7 +39,8 @@ let pp_var_data fmt {name; typ; modify_in_block} = type t = { access: PredSymb.access (** visibility access *) - ; captured: (Mangled.t * Typ.t) list (** name and type of variables captured in blocks *) + ; captured: (Mangled.t * Typ.t * Pvar.capture_mode) 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 *) @@ -118,6 +119,13 @@ let pp_parameters = Pp.semicolon_seq ~print_env:Pp.text_break (Pp.pair ~fst:Mangled.pp ~snd:(Typ.pp_full Pp.text)) +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 f ({ access ; captured @@ -152,8 +160,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) list] default.captured captured) then - F.fprintf f "; captured= [@[%a@]]@," pp_parameters captured ; + 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: 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 13eb14504..20296fd85 100644 --- a/infer/src/IR/ProcAttributes.mli +++ b/infer/src/IR/ProcAttributes.mli @@ -21,7 +21,8 @@ type var_data = type t = { access: PredSymb.access (** visibility access *) - ; captured: (Mangled.t * Typ.t) list (** name and type of variables captured in blocks *) + ; captured: (Mangled.t * Typ.t * Pvar.capture_mode) 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 *) ; const_formals: int list (** list of indices of formals that are const-qualified *) diff --git a/infer/src/IR/Procdesc.ml b/infer/src/IR/Procdesc.ml index fe0f8a122..255f48326 100644 --- a/infer/src/IR/Procdesc.ml +++ b/infer/src/IR/Procdesc.ml @@ -741,6 +741,15 @@ let pp_variable_list fmt etl = etl +let pp_captured_list fmt etl = + List.iter + ~f:(fun (id, ty, mode) -> + Format.fprintf fmt " [%s] %a:%a" + (Pvar.string_of_capture_mode mode) + Mangled.pp id (Typ.pp_full Pp.text) ty ) + etl + + let pp_objc_accessor fmt accessor = match accessor with | Some (ProcAttributes.Objc_getter field) -> @@ -760,7 +769,7 @@ let pp_signature fmt pdesc = attributes.ProcAttributes.objc_accessor pp_variable_list (get_formals pdesc) pp_locals_list (get_locals pdesc) ; if not (List.is_empty (get_captured pdesc)) then - Format.fprintf fmt ", Captured: %a" pp_variable_list (get_captured pdesc) ; + Format.fprintf fmt ", Captured: %a" pp_captured_list (get_captured pdesc) ; let method_annotation = attributes.ProcAttributes.method_annotation in ( if not (Annot.Method.is_empty method_annotation) then let pname_string = Procname.to_string pname in @@ -792,9 +801,11 @@ let is_captured_pvar procdesc pvar = | _ -> false in + let pvar_matches_in_captured (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 && List.exists ~f:pvar_matches (get_captured procdesc) + Procname.is_objc_block procname + && List.exists ~f:pvar_matches_in_captured (get_captured procdesc) in is_captured_var_cpp_lambda || is_captured_var_objc_block diff --git a/infer/src/IR/Procdesc.mli b/infer/src/IR/Procdesc.mli index b03e887ab..dc6dbbb72 100644 --- a/infer/src/IR/Procdesc.mli +++ b/infer/src/IR/Procdesc.mli @@ -225,7 +225,7 @@ val get_attributes : t -> ProcAttributes.t val set_attributes : t -> ProcAttributes.t -> unit -val get_captured : t -> (Mangled.t * Typ.t) list +val get_captured : t -> (Mangled.t * Typ.t * Pvar.capture_mode) list (** Return name and type of block's captured variables *) val get_exit_node : t -> Node.t diff --git a/infer/src/IR/Pvar.ml b/infer/src/IR/Pvar.ml index 2e776fb3e..4a91b9ef8 100644 --- a/infer/src/IR/Pvar.ml +++ b/infer/src/IR/Pvar.ml @@ -324,3 +324,7 @@ module Set = PrettyPrintable.MakePPSet (struct let pp = pp Pp.text end) + +type capture_mode = ByReference | ByValue [@@deriving compare] + +let string_of_capture_mode = function ByReference -> "by ref" | ByValue -> "by value" diff --git a/infer/src/IR/Pvar.mli b/infer/src/IR/Pvar.mli index 370b000cf..0b943b609 100644 --- a/infer/src/IR/Pvar.mli +++ b/infer/src/IR/Pvar.mli @@ -171,3 +171,7 @@ val rename : f:(string -> string) -> t -> t (** Sets of pvars. *) module Set : PrettyPrintable.PPSet with type elt = t + +type capture_mode = ByReference | ByValue [@@deriving compare] + +val string_of_capture_mode : capture_mode -> string diff --git a/infer/src/IR/SpecializeProcdesc.ml b/infer/src/IR/SpecializeProcdesc.ml index 7d6ca7304..5d64bacdc 100644 --- a/infer/src/IR/SpecializeProcdesc.ml +++ b/infer/src/IR/SpecializeProcdesc.ml @@ -212,7 +212,7 @@ let with_block_args_instrs resolved_pdesc substitutions = let id = Ident.create_fresh_specialized_with_blocks Ident.knormal in let pvar = Pvar.mk var resolved_pname in ( Var.of_id id - , (Exp.Var id, pvar, typ) + , (Exp.Var id, pvar, typ, Pvar.ByReference) , Sil.Load {id; e= Exp.Lvar pvar; root_typ= typ; typ; loc} ) ) |> List.unzip3 in @@ -259,7 +259,7 @@ let with_block_args_instrs resolved_pdesc substitutions = get_block_name_and_load_captured_vars_instrs block_var loc in let call_instr = - let id_exps = List.map ~f:(fun (id, _, typ) -> (id, typ)) id_exp_typs in + let id_exps = List.map ~f:(fun (id, _, typ, _) -> (id, typ)) id_exp_typs in let converted_args = List.map ~f:(fun (exp, typ) -> (convert_exp exp, typ)) origin_args in Sil.Call ( return_ids @@ -304,7 +304,7 @@ let with_block_args callee_pdesc pname_with_block_args block_args = | Some (cl : Exp.closure) -> let formals_from_captured = List.map - ~f:(fun (_, var, typ) -> + ~f:(fun (_, var, typ, _) -> (* Here we create fresh names for the new formals, based on the names of the captured variables annotated with the name of the caller method *) (Pvar.get_name_of_local_with_procname var, typ) ) diff --git a/infer/src/absint/HilExp.ml b/infer/src/absint/HilExp.ml index c0d959fd5..bbc117514 100644 --- a/infer/src/absint/HilExp.ml +++ b/infer/src/absint/HilExp.ml @@ -547,7 +547,7 @@ and of_sil ~include_array_indexes ~f_resolve_id ~add_deref exp typ = | Closure closure -> let environment = List.map - ~f:(fun (value, pvar, typ) -> + ~f:(fun (value, pvar, typ, _) -> (* TODO: this is a hack than can disappear once we have proper AccessExpressions (t23176430) *) let typ' = match value with diff --git a/infer/src/biabduction/Predicates.ml b/infer/src/biabduction/Predicates.ml index 8bb12912f..4807dea44 100644 --- a/infer/src/biabduction/Predicates.ml +++ b/infer/src/biabduction/Predicates.ml @@ -928,10 +928,10 @@ let rec exp_sub_ids (f : subst_fun) exp = if phys_equal e' e then exp else Exp.Exn e' | Closure c -> let captured_vars = - IList.map_changed ~equal:[%compare.equal: Exp.t * Pvar.t * Typ.t] - ~f:(fun ((e, pvar, typ) as captured) -> + IList.map_changed ~equal:[%compare.equal: Exp.t * Pvar.t * Typ.t * Pvar.capture_mode] + ~f:(fun ((e, pvar, typ, mode) as captured) -> let e' = exp_sub_ids f e in - if phys_equal e' e then captured else (e', pvar, typ) ) + if phys_equal e' e then captured else (e', pvar, typ, mode) ) c.captured_vars in if phys_equal captured_vars c.captured_vars then exp else Exp.Closure {c with captured_vars} diff --git a/infer/src/biabduction/Prop.ml b/infer/src/biabduction/Prop.ml index 92d29e639..106cfd6cf 100644 --- a/infer/src/biabduction/Prop.ml +++ b/infer/src/biabduction/Prop.ml @@ -673,7 +673,7 @@ module Normalize = struct e | Closure c -> let captured_vars = - List.map ~f:(fun (exp, pvar, typ) -> (eval exp, pvar, typ)) c.captured_vars + List.map ~f:(fun (exp, pvar, typ, mode) -> (eval exp, pvar, typ, mode)) c.captured_vars in Closure {c with captured_vars} | Const _ -> @@ -1399,12 +1399,12 @@ module Normalize = struct match (hpred : Predicates.hpred) with | Hpointsto (Exp.Lvar var, Eexp (Exp.Var id, _), _) -> IList.map_changed ~equal:phys_equal - ~f:(fun ((e_captured, var_captured, t) as captured_item) -> + ~f:(fun ((e_captured, var_captured, t, mode) as captured_item) -> match e_captured with | Exp.Var id_captured -> if Ident.equal id id_captured && Pvar.equal var var_captured then captured_item - else if Ident.equal id id_captured then (e_captured, var, t) - else if Pvar.equal var var_captured then (Exp.Var id, var_captured, t) + else if Ident.equal id id_captured then (e_captured, var, t, mode) + else if Pvar.equal var var_captured then (Exp.Var id, var_captured, t, mode) else captured_item | _ -> captured_item ) @@ -2114,7 +2114,7 @@ let rec exp_captured_ren ren (e : Exp.t) : Exp.t = Exn (exp_captured_ren ren e) | Closure {name; captured_vars} -> let captured_vars' = - List.map ~f:(fun (e, v, t) -> (exp_captured_ren ren e, v, t)) captured_vars + List.map ~f:(fun (e, v, t, m) -> (exp_captured_ren ren e, v, t, m)) captured_vars in Closure {name; captured_vars= captured_vars'} | Const _ -> diff --git a/infer/src/biabduction/Rearrange.ml b/infer/src/biabduction/Rearrange.ml index 368b28414..5b4a32972 100644 --- a/infer/src/biabduction/Rearrange.ml +++ b/infer/src/biabduction/Rearrange.ml @@ -1289,7 +1289,7 @@ 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 (cn, _, _) -> Mangled.equal name cn) (Procdesc.get_captured pdesc) | _ -> false in diff --git a/infer/src/biabduction/RetainCycles.ml b/infer/src/biabduction/RetainCycles.ml index 403f070fa..bcd0d2c6b 100644 --- a/infer/src/biabduction/RetainCycles.ml +++ b/infer/src/biabduction/RetainCycles.ml @@ -119,7 +119,7 @@ let get_cycle_blocks root_node exp = match exp with | Exp.Closure {name; captured_vars} -> List.find_map - ~f:(fun (e, var, typ) -> + ~f:(fun (e, var, typ, _) -> match typ.Typ.desc with | Typ.Tptr (_, Typ.Pk_objc_weak) | Typ.Tptr (_, Typ.Pk_objc_unsafe_unretained) -> None diff --git a/infer/src/biabduction/SymExec.ml b/infer/src/biabduction/SymExec.ml index 2442b6e28..4a04b236a 100644 --- a/infer/src/biabduction/SymExec.ml +++ b/infer/src/biabduction/SymExec.ml @@ -1108,7 +1108,7 @@ let rec sym_exec | Exp.Closure c -> let proc_exp = Exp.Const (Const.Cfun c.name) in let proc_exp' = Prop.exp_normalize_prop tenv prop_ proc_exp in - let par' = List.map ~f:(fun (id_exp, _, typ) -> (id_exp, typ)) c.captured_vars in + let par' = List.map ~f:(fun (id_exp, _, typ, _) -> (id_exp, typ)) c.captured_vars in Sil.Call (ret, proc_exp', par' @ par, loc, call_flags) | _ -> Sil.Call (ret, exp', par, loc, call_flags) diff --git a/infer/src/biabduction/SymExecBlocks.ml b/infer/src/biabduction/SymExecBlocks.ml index 7d9d57e46..28db1989a 100644 --- a/infer/src/biabduction/SymExecBlocks.ml +++ b/infer/src/biabduction/SymExecBlocks.ml @@ -34,7 +34,7 @@ let get_extended_args_for_method_with_block_analysis act_params = match act_param with | Exp.Closure cl, _, _ -> let captured = - List.map ~f:(fun (exp, var, typ) -> (exp, Some var, typ)) cl.captured_vars + List.map ~f:(fun (exp, var, typ, _) -> (exp, Some var, typ)) cl.captured_vars in append_no_duplicates_vars all_args captured | _ -> diff --git a/infer/src/bufferoverrun/bufferOverrunChecker.ml b/infer/src/bufferoverrun/bufferOverrunChecker.ml index f19ee9140..62ab905c9 100644 --- a/infer/src/bufferoverrun/bufferOverrunChecker.ml +++ b/infer/src/bufferoverrun/bufferOverrunChecker.ml @@ -173,7 +173,7 @@ let check_expr_for_array_access : | Exp.Cast (_, e) -> check_sub_expr e cond_set | Exp.Closure {captured_vars} -> - List.fold captured_vars ~init:cond_set ~f:(fun cond_set (e, _, _) -> + List.fold captured_vars ~init:cond_set ~f:(fun cond_set (e, _, _, _) -> check_sub_expr e cond_set ) | Exp.Var _ | Exp.Lvar _ | Exp.Const _ | Exp.Sizeof _ -> cond_set @@ -226,7 +226,7 @@ let rec check_expr_for_integer_overflow integer_type_widths pname exp location m |> check_expr_for_integer_overflow integer_type_widths pname e1 location mem |> check_expr_for_integer_overflow integer_type_widths pname e2 location mem | Exp.Closure {captured_vars} -> - List.fold captured_vars ~init:cond_set ~f:(fun cond_set (e, _, _) -> + List.fold captured_vars ~init:cond_set ~f:(fun cond_set (e, _, _, _) -> check_expr_for_integer_overflow integer_type_widths pname e location mem cond_set ) | Exp.Var _ | Exp.Const _ | Exp.Lvar _ | Exp.Sizeof {dynamic_length= None} -> cond_set diff --git a/infer/src/checkers/SelfInBlock.ml b/infer/src/checkers/SelfInBlock.ml index ccfdf32cf..5fdd531c9 100644 --- a/infer/src/checkers/SelfInBlock.ml +++ b/infer/src/checkers/SelfInBlock.ml @@ -151,7 +151,7 @@ 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 (captured, typ, _) -> Mangled.equal captured pvar_name && Typ.is_strong_pointer typ) attributes.ProcAttributes.captured @@ -159,7 +159,7 @@ module TransferFunctions = struct let is_captured_strong_self attributes pvar = (not (Pvar.is_self pvar)) && List.exists - ~f:(fun (captured, typ) -> + ~f:(fun (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 +168,7 @@ module TransferFunctions = struct let is_captured_weak_self attributes pvar = List.exists - ~f:(fun (captured, typ) -> + ~f:(fun (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 ) @@ -270,7 +270,7 @@ module TransferFunctions = struct actual "use" of the captured variable in the source program though, and causes false positives. Here we remove the ids from the domain when that id is being added to a closure. *) let remove_ids_in_closures_from_domain (domain : Domain.t) (instr : Sil.instr) = - let remove_id_in_closures_from_domain vars ((exp : Exp.t), _, _) = + let remove_id_in_closures_from_domain vars ((exp : Exp.t), _, _, _) = match exp with Var id -> Vars.remove id vars | _ -> vars in let do_exp vars (exp : Exp.t) = diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index b8080d620..18e2e565f 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -216,10 +216,15 @@ let create_local_procdesc ?(set_objc_accessor_attr = false) trans_unit_ctx cfg t let formals = List.map ~f:(fun ({name; typ} : CMethodSignature.param_type) -> (name, typ)) all_params in - let captured_mangled = List.map ~f:(fun (var, t) -> (Pvar.get_name var, t)) captured in + let captured_mangled = + List.map ~f:(fun (var, t, mode) -> (Pvar.get_name var, t, mode)) captured + in (* Captured variables for blocks are treated as parameters *) - let formals = captured_mangled @ formals in - let const_formals = get_const_params_indices ~shift:(List.length captured_mangled) all_params in + let captured_as_formals = List.map ~f:(fun (var, t, _) -> (var, t)) captured_mangled in + let formals = captured_as_formals @ formals in + let const_formals = + get_const_params_indices ~shift:(List.length captured_as_formals) all_params + in let source_range = ms.CMethodSignature.loc in L.(debug Capture Verbose) "@\nCreating a new procdesc for function: '%a'@\n@." Procname.pp proc_name ; diff --git a/infer/src/clang/cMethod_trans.mli b/infer/src/clang/cMethod_trans.mli index 53b166947..952a62a82 100644 --- a/infer/src/clang/cMethod_trans.mli +++ b/infer/src/clang/cMethod_trans.mli @@ -31,7 +31,7 @@ val create_local_procdesc : -> Tenv.t -> CMethodSignature.t -> Clang_ast_t.stmt list - -> (Pvar.t * Typ.t) list + -> (Pvar.t * Typ.t * Pvar.capture_mode) list -> bool val create_external_procdesc : diff --git a/infer/src/clang/cModule_type.ml b/infer/src/clang/cModule_type.ml index eae026dbc..39e974264 100644 --- a/infer/src/clang/cModule_type.ml +++ b/infer/src/clang/cModule_type.ml @@ -8,7 +8,7 @@ open! IStd type block_data = - { captured_vars: (Pvar.t * Typ.t) list + { captured_vars: (Pvar.t * Typ.t * Pvar.capture_mode) list ; context: CContext.t ; passed_as_noescape_block_to: Procname.t option ; procname: Procname.t diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 6842a8b9b..5bc1de34a 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -291,10 +291,10 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s (** Given a captured var, return the instruction to assign it to a temp *) - let assign_captured_var loc (cvar, typ) = + let assign_captured_var loc (cvar, typ, mode) = let id = Ident.create_fresh Ident.knormal in let instr = Sil.Load {id; e= Exp.Lvar cvar; root_typ= typ; typ; loc} in - ((Exp.Var id, cvar, typ), instr) + ((Exp.Var id, cvar, typ, mode), instr) let closure_trans closure_pname captured_vars context stmt_info expr_info = @@ -2833,11 +2833,15 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s CType_decl.CProcname.from_decl decl ~tenv:context.tenv ~block_return_type:return_type ~outer_proc in - let captured_vars = + let captured_vars_no_mode = CVar_decl.captured_vars_from_block_info context stmt_info.Clang_ast_t.si_source_range block_decl_info.Clang_ast_t.bdi_captured_variables in let passed_as_noescape_block_to = trans_state.passed_as_noescape_block_to in + (* TODO: set correct capture mode *) + let captured_vars = + List.map captured_vars_no_mode ~f:(fun (var, typ) -> (var, typ, Pvar.ByReference)) + in let res = closure_trans procname captured_vars context stmt_info expr_info in let block_data = Some @@ -2870,16 +2874,18 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s CFrontend_errors.incorrect_assumption __POS__ stmt_info.Clang_ast_t.si_source_range "Capture-init statement without var decl" in - let translate_normal_capture ~is_by_ref ((pvar, typ) as pvar_typ) - (trans_results_acc, captured_vars_acc) = + let translate_normal_capture mode (pvar, typ) (trans_results_acc, captured_vars_acc) = let loc = CLocation.location_of_stmt_info context.translation_unit_context.source_file stmt_info in - if is_by_ref then (trans_results_acc, (Exp.Lvar pvar, pvar, typ) :: captured_vars_acc) - else - let ((exp, _, typ) as exp_pvar_typ), instr = assign_captured_var loc pvar_typ in - let trans_results = mk_trans_result (exp, typ) {empty_control with instrs= [instr]} in - (trans_results :: trans_results_acc, exp_pvar_typ :: captured_vars_acc) + match mode with + | Pvar.ByReference -> + (trans_results_acc, (Exp.Lvar pvar, pvar, typ, mode) :: captured_vars_acc) + | Pvar.ByValue -> + let pvar_typ_mode = (pvar, typ, mode) in + let ((exp, _, typ, _) as exp_pvar_typ), instr = assign_captured_var loc pvar_typ_mode in + let trans_results = mk_trans_result (exp, typ) {empty_control with instrs= [instr]} in + (trans_results :: trans_results_acc, exp_pvar_typ :: captured_vars_acc) in let translate_captured {Clang_ast_t.lci_captured_var; lci_init_captured_vardecl; lci_capture_this; lci_capture_kind} @@ -2899,27 +2905,28 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s | `LCK_StarThis (* [*this] is special syntax for capturing current object by value *) -> false in + let mode = if is_by_ref then Pvar.ByReference else Pvar.ByValue in match (lci_captured_var, lci_init_captured_vardecl) with | Some captured_var_decl_ref, Some init_decl -> ( (* capture and init *) match get_captured_pvar_typ captured_var_decl_ref with - | Some pvar_typ -> + | Some ((pvar, typ) as pvar_typ) -> ( translate_capture_init pvar_typ init_decl :: trans_results_acc - , (Exp.Lvar (fst pvar_typ), fst pvar_typ, snd pvar_typ) :: captured_vars_acc ) + , (Exp.Lvar pvar, pvar, typ, mode) :: captured_vars_acc ) | None -> (trans_results_acc, captured_vars_acc) ) | Some captured_var_decl_ref, None -> ( (* just capture *) match get_captured_pvar_typ captured_var_decl_ref with | Some pvar_typ -> - translate_normal_capture ~is_by_ref pvar_typ acc + translate_normal_capture mode pvar_typ acc | None -> (trans_results_acc, captured_vars_acc) ) | None, None -> if lci_capture_this then (* captured [this] *) let this_typ = get_this_pvar_typ stmt_info context in - translate_normal_capture ~is_by_ref this_typ acc + translate_normal_capture mode this_typ acc else acc | None, Some _ -> CFrontend_errors.incorrect_assumption __POS__ stmt_info.Clang_ast_t.si_source_range diff --git a/infer/src/clang/cVar_decl.ml b/infer/src/clang/cVar_decl.ml index de71c293d..3740d8a22 100644 --- a/infer/src/clang/cVar_decl.ml +++ b/infer/src/clang/cVar_decl.ml @@ -101,6 +101,7 @@ let sil_var_of_captured_var context source_range procname decl_ref = in match (var_opt, typ_opt) with | Some var, Some typ -> + (* TODO: set correct capture mode *) Some (var, typ) | None, None -> None diff --git a/infer/src/pulse/PulseOperations.ml b/infer/src/pulse/PulseOperations.ml index d30bd5df0..44f74ee25 100644 --- a/infer/src/pulse/PulseOperations.ml +++ b/infer/src/pulse/PulseOperations.ml @@ -72,9 +72,9 @@ module Closures = struct List.rev_filter_map captured ~f:(fun (captured_as, (address_captured, trace_captured), mode) -> match mode with - | `ByValue -> + | Pvar.ByValue -> None - | `ByReference -> + | Pvar.ByReference -> let new_trace = ValueHistory.Capture {captured_as; location} :: trace_captured in Some (address_captured, new_trace) ) in @@ -114,12 +114,8 @@ let eval location exp0 astate = | Closure {name; captured_vars} -> let+ astate, rev_captured = List.fold_result captured_vars ~init:(astate, []) - ~f:(fun (astate, rev_captured) (capt_exp, captured_as, _) -> + ~f:(fun (astate, rev_captured) (capt_exp, captured_as, _, mode) -> let+ astate, addr_trace = eval capt_exp astate in - let mode = - (* HACK: the frontend follows this discipline *) - match (capt_exp : Exp.t) with Lvar _ -> `ByReference | _ -> `ByValue - in (astate, (captured_as, addr_trace, mode) :: rev_captured) ) in Closures.record location name (List.rev rev_captured) astate diff --git a/infer/src/unit/addressTakenTests.ml b/infer/src/unit/addressTakenTests.ml index db2daf8ba..1c73a2a83 100644 --- a/infer/src/unit/addressTakenTests.ml +++ b/infer/src/unit/addressTakenTests.ml @@ -16,7 +16,9 @@ let tests = let int_ptr_typ = Typ.mk (Tptr (int_typ, Pk_pointer)) in let fun_ptr_typ = Typ.mk (Tptr (Typ.mk Tfun, Pk_pointer)) in let closure_exp captureds = - let mk_captured_var str = (Exp.Var (ident_of_str str), pvar_of_str str, int_ptr_typ) in + let mk_captured_var str = + (Exp.Var (ident_of_str str), pvar_of_str str, int_ptr_typ, Pvar.ByReference) + in let captured_vars = List.map ~f:mk_captured_var captureds in let closure = {Exp.name= dummy_procname; captured_vars} in Exp.Closure closure diff --git a/infer/src/unit/livenessTests.ml b/infer/src/unit/livenessTests.ml index 86d5275be..b522e2e94 100644 --- a/infer/src/unit/livenessTests.ml +++ b/infer/src/unit/livenessTests.ml @@ -15,7 +15,9 @@ let tests = let assert_empty = invariant "{ }" in let fun_ptr_typ = Typ.mk (Tptr (Typ.mk Tfun, Pk_pointer)) in let closure_exp captured_pvars = - let mk_captured_var str = (Exp.Var (ident_of_str str), pvar_of_str str, dummy_typ) in + let mk_captured_var str = + (Exp.Var (ident_of_str str), pvar_of_str str, dummy_typ, Pvar.ByReference) + in let captured_vars = List.map ~f:mk_captured_var captured_pvars in let closure = {Exp.name= dummy_procname; captured_vars} in Exp.Closure closure diff --git a/infer/tests/codetoanalyze/cpp/shared/lambda/lambda1.cpp.dot b/infer/tests/codetoanalyze/cpp/shared/lambda/lambda1.cpp.dot index c2da2cb14..cd8a63ff7 100644 --- a/infer/tests/codetoanalyze/cpp/shared/lambda/lambda1.cpp.dot +++ b/infer/tests/codetoanalyze/cpp/shared/lambda/lambda1.cpp.dot @@ -121,7 +121,7 @@ digraph cfg { "normal_capture#5533029764254319855.11493b249dddd657790695e287170b84_2" [label="2: Exit normal_capture \n " color=yellow style=filled] -"normal_capture#5533029764254319855.11493b249dddd657790695e287170b84_3" [label="3: Return Stmt \n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10); [line 31, column 10]\n n$6=*&x:int [line 31, column 10]\n n$5=*&y:int [line 31, column 10]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10=(_fun_normal_capture::lambda_shared_lambda_lambda1.cpp:31:10::operator(),(n$6 &x:int),(n$5 &y:int)) [line 31, column 10]\n n$7=_fun_normal_capture::lambda_shared_lambda_lambda1.cpp:31:10::operator()(&0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10&) [line 31, column 10]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10 [line 31, column 37]\n n$2=_fun_normal_capture::lambda_shared_lambda_lambda1.cpp:31:10::~(&0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10*) injected [line 31, column 37]\n *&return:int=n$7 [line 31, column 3]\n " shape="box"] +"normal_capture#5533029764254319855.11493b249dddd657790695e287170b84_3" [label="3: Return Stmt \n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10); [line 31, column 10]\n n$6=*&x:int [line 31, column 10]\n n$5=*&y:int [line 31, column 10]\n *&0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10=(_fun_normal_capture::lambda_shared_lambda_lambda1.cpp:31:10::operator(),([by value]n$6 &x:int),([by value]n$5 &y:int)) [line 31, column 10]\n n$7=_fun_normal_capture::lambda_shared_lambda_lambda1.cpp:31:10::operator()(&0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10&) [line 31, column 10]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10 [line 31, column 37]\n n$2=_fun_normal_capture::lambda_shared_lambda_lambda1.cpp:31:10::~(&0$?%__sil_tmpSIL_materialize_temp__n$0:normal_capture::lambda_shared_lambda_lambda1.cpp:31:10*) injected [line 31, column 37]\n *&return:int=n$7 [line 31, column 3]\n " shape="box"] "normal_capture#5533029764254319855.11493b249dddd657790695e287170b84_3" -> "normal_capture#5533029764254319855.11493b249dddd657790695e287170b84_2" ; @@ -144,7 +144,7 @@ digraph cfg { "struct_capture#7773507847510274281.f3db763dc0b20b24ec397f7802254c90_3" -> "struct_capture#7773507847510274281.f3db763dc0b20b24ec397f7802254c90_2" ; -"struct_capture#7773507847510274281.f3db763dc0b20b24ec397f7802254c90_4" [label="4: DeclStmt \n VARIABLE_DECLARED(f:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12); [line 77, column 3]\n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12); [line 77, column 12]\n n$14=*&x:SomeStruct [line 77, column 12]\n n$13=*&y:SomeStruct [line 77, column 12]\n *&0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12=(_fun_struct_capture::lambda_shared_lambda_lambda1.cpp:77:12::operator(),(n$14 &x:SomeStruct),(n$13 &y:SomeStruct)) [line 77, column 12]\n n$15=_fun_struct_capture::lambda_shared_lambda_lambda1.cpp:77:12::(&f:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12*,&0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12&) [line 77, column 12]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12 [line 77, column 41]\n n$11=_fun_struct_capture::lambda_shared_lambda_lambda1.cpp:77:12::~(&0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12*) injected [line 77, column 41]\n " shape="box"] +"struct_capture#7773507847510274281.f3db763dc0b20b24ec397f7802254c90_4" [label="4: DeclStmt \n VARIABLE_DECLARED(f:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12); [line 77, column 3]\n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12); [line 77, column 12]\n n$14=*&x:SomeStruct [line 77, column 12]\n n$13=*&y:SomeStruct [line 77, column 12]\n *&0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12=(_fun_struct_capture::lambda_shared_lambda_lambda1.cpp:77:12::operator(),([by value]n$14 &x:SomeStruct),([by value]n$13 &y:SomeStruct)) [line 77, column 12]\n n$15=_fun_struct_capture::lambda_shared_lambda_lambda1.cpp:77:12::(&f:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12*,&0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12&) [line 77, column 12]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12 [line 77, column 41]\n n$11=_fun_struct_capture::lambda_shared_lambda_lambda1.cpp:77:12::~(&0$?%__sil_tmpSIL_materialize_temp__n$9:struct_capture::lambda_shared_lambda_lambda1.cpp:77:12*) injected [line 77, column 41]\n " shape="box"] "struct_capture#7773507847510274281.f3db763dc0b20b24ec397f7802254c90_4" -> "struct_capture#7773507847510274281.f3db763dc0b20b24ec397f7802254c90_3" ; @@ -197,7 +197,7 @@ digraph cfg { "capture_star_this#Capture#(2506493005619132138).63fd6aa2a7efbd48dc1a62c0c2bd2161_3" -> "capture_star_this#Capture#(2506493005619132138).63fd6aa2a7efbd48dc1a62c0c2bd2161_2" ; -"capture_star_this#Capture#(2506493005619132138).63fd6aa2a7efbd48dc1a62c0c2bd2161_4" [label="4: DeclStmt \n VARIABLE_DECLARED(lambda:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19); [line 55, column 5]\n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19); [line 55, column 19]\n n$7=*&this:Capture* [line 55, column 19]\n *&0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19=(_fun_Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19::operator(),(n$7 &this:Capture*)) [line 55, column 19]\n n$8=_fun_Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19::(&lambda:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19*,&0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19&) [line 55, column 19]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19 [line 57, column 5]\n n$5=_fun_Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19::~(&0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19*) injected [line 57, column 5]\n " shape="box"] +"capture_star_this#Capture#(2506493005619132138).63fd6aa2a7efbd48dc1a62c0c2bd2161_4" [label="4: DeclStmt \n VARIABLE_DECLARED(lambda:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19); [line 55, column 5]\n VARIABLE_DECLARED(0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19); [line 55, column 19]\n n$7=*&this:Capture* [line 55, column 19]\n *&0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19=(_fun_Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19::operator(),([by value]n$7 &this:Capture*)) [line 55, column 19]\n n$8=_fun_Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19::(&lambda:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19*,&0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19&) [line 55, column 19]\n _=*&0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19 [line 57, column 5]\n n$5=_fun_Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19::~(&0$?%__sil_tmpSIL_materialize_temp__n$3:Capture::capture_star_this::lambda_shared_lambda_lambda1.cpp:55:19*) injected [line 57, column 5]\n " shape="box"] "capture_star_this#Capture#(2506493005619132138).63fd6aa2a7efbd48dc1a62c0c2bd2161_4" -> "capture_star_this#Capture#(2506493005619132138).63fd6aa2a7efbd48dc1a62c0c2bd2161_3" ; diff --git a/infer/tests/codetoanalyze/objc/frontend/block/retain_cycle.m.dot b/infer/tests/codetoanalyze/objc/frontend/block/retain_cycle.m.dot index f7f893f9e..5eee73bb4 100644 --- a/infer/tests/codetoanalyze/objc/frontend/block/retain_cycle.m.dot +++ b/infer/tests/codetoanalyze/objc/frontend/block/retain_cycle.m.dot @@ -34,7 +34,7 @@ digraph cfg { "main.fad58de7366495db4650cfefac2fcd61_5" -> "main.fad58de7366495db4650cfefac2fcd61_4" ; -"objc_blockA.capture_1(class A,class D).8e9a52049a11f3e729d697583cda7110_1" [label="1: Start objc_blockA.capture_1\nFormals: self:A* d:D*\nLocals: \nCaptured: self:A* \n " color=yellow style=filled] +"objc_blockA.capture_1(class A,class D).8e9a52049a11f3e729d697583cda7110_1" [label="1: Start objc_blockA.capture_1\nFormals: self:A* d:D*\nLocals: \nCaptured: [by ref]self:A* \n " color=yellow style=filled] "objc_blockA.capture_1(class A,class D).8e9a52049a11f3e729d697583cda7110_1" -> "objc_blockA.capture_1(class A,class D).8e9a52049a11f3e729d697583cda7110_3" ; @@ -52,7 +52,7 @@ digraph cfg { "capture#A#instance.d411336575e4bf632a1828f5f5979726_2" [label="2: Exit A.capture \n " color=yellow style=filled] -"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" [label="3: Message Call: sHandler: \n n$3=*&self:A* [line 45, column 4]\n n$4=*n$3._b:B* [line 45, column 4]\n n$0=*&self:A* [line 45, column 16]\n n$5=_fun_B.sHandler:(n$4:B*,(_fun_objc_blockA.capture_1,(n$0 &self:A*)):_fn_(*)) block_params virtual [line 45, column 3]\n " shape="box"] +"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" [label="3: Message Call: sHandler: \n n$3=*&self:A* [line 45, column 4]\n n$4=*n$3._b:B* [line 45, column 4]\n n$0=*&self:A* [line 45, column 16]\n n$5=_fun_B.sHandler:(n$4:B*,(_fun_objc_blockA.capture_1,([by ref]n$0 &self:A*)):_fn_(*)) block_params virtual [line 45, column 3]\n " shape="box"] "capture#A#instance.d411336575e4bf632a1828f5f5979726_3" -> "capture#A#instance.d411336575e4bf632a1828f5f5979726_2" ; diff --git a/infer/tests/codetoanalyze/objc/pulse/issues.exp b/infer/tests/codetoanalyze/objc/pulse/issues.exp index aa7da5dac..49ec14266 100644 --- a/infer/tests/codetoanalyze/objc/pulse/issues.exp +++ b/infer/tests/codetoanalyze/objc/pulse/issues.exp @@ -6,7 +6,7 @@ codetoanalyze/objc/pulse/MemoryLeaks.m, MemoryLeaks.cg_path_create_with_rect_lea codetoanalyze/objc/pulse/MemoryLeaks.m, MemoryLeaks.no_bridge_leak_bad, 1, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `CFLocaleCreate` (modelled),allocation part of the trace ends here,memory becomes unreachable here] codetoanalyze/objc/pulse/MemoryLeaks.m, call_bridge_interproc_leak_ok_FP, 2, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `CFLocaleCreate` (modelled),allocation part of the trace ends here,memory becomes unreachable here] codetoanalyze/objc/pulse/MemoryLeaks.m, call_cfrelease_interproc_leak_ok_FP, 2, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `CFLocaleCreate` (modelled),allocation part of the trace ends here,memory becomes unreachable here] -codetoanalyze/objc/pulse/MemoryLeaksInBlocks.m, block_captured_var_leak_bad, 3, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `malloc_no_fail` (modelled),allocation part of the trace ends here,memory becomes unreachable here] -codetoanalyze/objc/pulse/MemoryLeaksInBlocks.m, block_free_ok_FP, 3, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `malloc_no_fail` (modelled),allocation part of the trace ends here,memory becomes unreachable here] +codetoanalyze/objc/pulse/MemoryLeaksInBlocks.m, block_captured_var_leak_bad, 6, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `malloc_no_fail` (modelled),allocation part of the trace ends here,memory becomes unreachable here] +codetoanalyze/objc/pulse/MemoryLeaksInBlocks.m, block_free_ok_FP, 8, MEMORY_LEAK, no_bucket, ERROR, [allocation part of the trace starts here,allocated by call to `malloc_no_fail` (modelled),allocation part of the trace ends here,memory becomes unreachable here] codetoanalyze/objc/pulse/use_after_free.m, PulseTest.use_after_free_simple_in_objc_method_bad:, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `x` of PulseTest.use_after_free_simple_in_objc_method_bad:,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of PulseTest.use_after_free_simple_in_objc_method_bad:,invalid access occurs here] codetoanalyze/objc/pulse/use_after_free.m, use_after_free_simple_bad, 2, USE_AFTER_FREE, no_bucket, ERROR, [invalidation part of the trace starts here,parameter `x` of use_after_free_simple_bad,was invalidated by call to `free()`,use-after-lifetime part of the trace starts here,parameter `x` of use_after_free_simple_bad,invalid access occurs here] diff --git a/infer/tests/codetoanalyze/objc/shared/block/BlockVar.m.dot b/infer/tests/codetoanalyze/objc/shared/block/BlockVar.m.dot index cd9d50f5e..b0582950b 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/BlockVar.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/block/BlockVar.m.dot @@ -1,6 +1,6 @@ /* @generated */ digraph cfg { -"objc_blockBlockVar.blockPostBad_2.9b5fc6c216acf1eebade4e80598bd292_1" [label="1: Start objc_blockBlockVar.blockPostBad_2\nFormals: x:int*\nLocals: \nCaptured: x:int* \n " color=yellow style=filled] +"objc_blockBlockVar.blockPostBad_2.9b5fc6c216acf1eebade4e80598bd292_1" [label="1: Start objc_blockBlockVar.blockPostBad_2\nFormals: x:int*\nLocals: \nCaptured: [by ref]x:int* \n " color=yellow style=filled] "objc_blockBlockVar.blockPostBad_2.9b5fc6c216acf1eebade4e80598bd292_1" -> "objc_blockBlockVar.blockPostBad_2.9b5fc6c216acf1eebade4e80598bd292_3" ; @@ -11,7 +11,7 @@ digraph cfg { "objc_blockBlockVar.blockPostBad_2.9b5fc6c216acf1eebade4e80598bd292_3" -> "objc_blockBlockVar.blockPostBad_2.9b5fc6c216acf1eebade4e80598bd292_2" ; -"objc_blockBlockVar.blockPostOk_3.860b502fd4305d26ee26104b0e266b62_1" [label="1: Start objc_blockBlockVar.blockPostOk_3\nFormals: x:int*\nLocals: \nCaptured: x:int* \n " color=yellow style=filled] +"objc_blockBlockVar.blockPostOk_3.860b502fd4305d26ee26104b0e266b62_1" [label="1: Start objc_blockBlockVar.blockPostOk_3\nFormals: x:int*\nLocals: \nCaptured: [by ref]x:int* \n " color=yellow style=filled] "objc_blockBlockVar.blockPostOk_3.860b502fd4305d26ee26104b0e266b62_1" -> "objc_blockBlockVar.blockPostOk_3.860b502fd4305d26ee26104b0e266b62_3" ; @@ -22,7 +22,7 @@ digraph cfg { "objc_blockBlockVar.blockPostOk_3.860b502fd4305d26ee26104b0e266b62_3" -> "objc_blockBlockVar.blockPostOk_3.860b502fd4305d26ee26104b0e266b62_2" ; -"objc_blockBlockVar.capturedNoNullDeref_5.05728b28cff98ce99554f69b47154636_1" [label="1: Start objc_blockBlockVar.capturedNoNullDeref_5\nFormals: x:int*\nLocals: \nCaptured: x:int* \n " color=yellow style=filled] +"objc_blockBlockVar.capturedNoNullDeref_5.05728b28cff98ce99554f69b47154636_1" [label="1: Start objc_blockBlockVar.capturedNoNullDeref_5\nFormals: x:int*\nLocals: \nCaptured: [by ref]x:int* \n " color=yellow style=filled] "objc_blockBlockVar.capturedNoNullDeref_5.05728b28cff98ce99554f69b47154636_1" -> "objc_blockBlockVar.capturedNoNullDeref_5.05728b28cff98ce99554f69b47154636_3" ; @@ -33,7 +33,7 @@ digraph cfg { "objc_blockBlockVar.capturedNoNullDeref_5.05728b28cff98ce99554f69b47154636_3" -> "objc_blockBlockVar.capturedNoNullDeref_5.05728b28cff98ce99554f69b47154636_2" ; -"objc_blockBlockVar.capturedNullDeref_4.b2398d8a441f4c0e3ff276c92e1e2c2b_1" [label="1: Start objc_blockBlockVar.capturedNullDeref_4\nFormals: x:int*\nLocals: \nCaptured: x:int* \n " color=yellow style=filled] +"objc_blockBlockVar.capturedNullDeref_4.b2398d8a441f4c0e3ff276c92e1e2c2b_1" [label="1: Start objc_blockBlockVar.capturedNullDeref_4\nFormals: x:int*\nLocals: \nCaptured: [by ref]x:int* \n " color=yellow style=filled] "objc_blockBlockVar.capturedNullDeref_4.b2398d8a441f4c0e3ff276c92e1e2c2b_1" -> "objc_blockBlockVar.capturedNullDeref_4.b2398d8a441f4c0e3ff276c92e1e2c2b_3" ; @@ -129,7 +129,7 @@ digraph cfg { "blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_3" -> "blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_2" ; -"blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_4" [label="4: DeclStmt \n VARIABLE_DECLARED(my_block:_fn_(*)); [line 31, column 3]\n n$14=*&x:int* [line 31, column 28]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar.blockPostBad_2,(n$14 &x:int*)) [line 31, column 3]\n " shape="box"] +"blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_4" [label="4: DeclStmt \n VARIABLE_DECLARED(my_block:_fn_(*)); [line 31, column 3]\n n$14=*&x:int* [line 31, column 28]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar.blockPostBad_2,([by ref]n$14 &x:int*)) [line 31, column 3]\n " shape="box"] "blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_4" -> "blockPostBad#BlockVar#instance.60292f870cad8c1a5cefdbfe4194d6f9_3" ; @@ -148,7 +148,7 @@ digraph cfg { "blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_3" -> "blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_2" ; -"blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_4" [label="4: DeclStmt \n VARIABLE_DECLARED(my_block:_fn_(*)); [line 40, column 3]\n n$19=*&x:int* [line 40, column 28]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar.blockPostOk_3,(n$19 &x:int*)) [line 40, column 3]\n " shape="box"] +"blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_4" [label="4: DeclStmt \n VARIABLE_DECLARED(my_block:_fn_(*)); [line 40, column 3]\n n$19=*&x:int* [line 40, column 28]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar.blockPostOk_3,([by ref]n$19 &x:int*)) [line 40, column 3]\n " shape="box"] "blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_4" -> "blockPostOk#BlockVar#instance.1bb64a946f8b169b31996644931ed82d_3" ; @@ -175,7 +175,7 @@ digraph cfg { "capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_4" -> "capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_3" ; -"capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_5" [label="5: DeclStmt \n VARIABLE_DECLARED(my_block:_fn_(*)); [line 57, column 3]\n n$28=*&x:int* [line 57, column 27]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar.capturedNoNullDeref_5,(n$28 &x:int*)) [line 57, column 3]\n " shape="box"] +"capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_5" [label="5: DeclStmt \n VARIABLE_DECLARED(my_block:_fn_(*)); [line 57, column 3]\n n$28=*&x:int* [line 57, column 27]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar.capturedNoNullDeref_5,([by ref]n$28 &x:int*)) [line 57, column 3]\n " shape="box"] "capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_5" -> "capturedNoNullDeref#BlockVar#instance.ebe646baaabdc58144a5916780ee8c76_4" ; @@ -198,7 +198,7 @@ digraph cfg { "capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_3" -> "capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_2" ; -"capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_4" [label="4: DeclStmt \n VARIABLE_DECLARED(my_block:_fn_(*)); [line 48, column 3]\n n$23=*&x:int* [line 48, column 27]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar.capturedNullDeref_4,(n$23 &x:int*)) [line 48, column 3]\n " shape="box"] +"capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_4" [label="4: DeclStmt \n VARIABLE_DECLARED(my_block:_fn_(*)); [line 48, column 3]\n n$23=*&x:int* [line 48, column 27]\n *&my_block:_fn_(*)=(_fun_objc_blockBlockVar.capturedNullDeref_4,([by ref]n$23 &x:int*)) [line 48, column 3]\n " shape="box"] "capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_4" -> "capturedNullDeref#BlockVar#instance.48c44f7ae26caf7a1ac522523ebac894_3" ; diff --git a/infer/tests/codetoanalyze/objc/shared/block/Blocks_as_parameters.m.dot b/infer/tests/codetoanalyze/objc/shared/block/Blocks_as_parameters.m.dot index 1348fda56..2e38b858b 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/Blocks_as_parameters.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/block/Blocks_as_parameters.m.dot @@ -1,6 +1,6 @@ /* @generated */ digraph cfg { -"objc_blockB.f_1(class B).c1c611f4be5cea3fe56d67e34da1fffd_1" [label="1: Start objc_blockB.f_1\nFormals: self:B* const \nLocals: \nCaptured: self:B* const \n " color=yellow style=filled] +"objc_blockB.f_1(class B).c1c611f4be5cea3fe56d67e34da1fffd_1" [label="1: Start objc_blockB.f_1\nFormals: self:B* const \nLocals: \nCaptured: [by ref]self:B* const \n " color=yellow style=filled] "objc_blockB.f_1(class B).c1c611f4be5cea3fe56d67e34da1fffd_1" -> "objc_blockB.f_1(class B).c1c611f4be5cea3fe56d67e34da1fffd_3" ; @@ -33,7 +33,7 @@ digraph cfg { "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_3" -> "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_2" ; -"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" [label="4: Message Call: foo:and: \n n$4=*&self:B* [line 23, column 10]\n n$5=*n$4.h:int [line 23, column 10]\n n$2=*&self:B* const [line 24, column 11]\n n$6=_fun_B.foo:and:(n$5:int,(_fun_objc_blockB.f_1,(n$2 &self:B* const )):_fn_(*)) block_params [line 23, column 3]\n " shape="box"] +"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" [label="4: Message Call: foo:and: \n n$4=*&self:B* [line 23, column 10]\n n$5=*n$4.h:int [line 23, column 10]\n n$2=*&self:B* const [line 24, column 11]\n n$6=_fun_B.foo:and:(n$5:int,(_fun_objc_blockB.f_1,([by ref]n$2 &self:B* const )):_fn_(*)) block_params [line 23, column 3]\n " shape="box"] "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" -> "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_3" ; diff --git a/infer/tests/codetoanalyze/objc/shared/block/block.m.dot b/infer/tests/codetoanalyze/objc/shared/block/block.m.dot index b98a033f0..da8ef27f7 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/block.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/block/block.m.dot @@ -38,7 +38,7 @@ digraph cfg { "main1.38f534a9576db7ec6ebcbca8c111f942_7" -> "main1.38f534a9576db7ec6ebcbca8c111f942_6" ; -"main1.38f534a9576db7ec6ebcbca8c111f942_8" [label="8: BinaryOperatorStmt: Assign \n n$9=*&x:int [line 16, column 14]\n *&addblock:_fn_(*)=(_fun_objc_blockmain1_2,(n$9 &x:int)) [line 16, column 3]\n " shape="box"] +"main1.38f534a9576db7ec6ebcbca8c111f942_8" [label="8: BinaryOperatorStmt: Assign \n n$9=*&x:int [line 16, column 14]\n *&addblock:_fn_(*)=(_fun_objc_blockmain1_2,([by ref]n$9 &x:int)) [line 16, column 3]\n " shape="box"] "main1.38f534a9576db7ec6ebcbca8c111f942_8" -> "main1.38f534a9576db7ec6ebcbca8c111f942_7" ; @@ -61,7 +61,7 @@ digraph cfg { "objc_blockmain1_1.74199543de3b6a9a736f23ef5e45586a_3" -> "objc_blockmain1_1.74199543de3b6a9a736f23ef5e45586a_2" ; -"objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_1" [label="1: Start objc_blockmain1_2\nFormals: x:int c:int d:int\nLocals: bla:int add2:int addblock2:_fn_(*)\nCaptured: x:int \n " color=yellow style=filled] +"objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_1" [label="1: Start objc_blockmain1_2\nFormals: x:int c:int d:int\nLocals: bla:int add2:int addblock2:_fn_(*)\nCaptured: [by ref]x:int \n " color=yellow style=filled] "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_1" -> "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_6" ; @@ -76,7 +76,7 @@ digraph cfg { "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_4" -> "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_3" ; -"objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_5" [label="5: BinaryOperatorStmt: Assign \n n$15=*&x:int [line 21, column 17]\n n$16=*&bla:int [line 21, column 17]\n *&addblock2:_fn_(*)=(_fun_objc_blockobjc_blockmain1_2_3,(n$15 &x:int),(n$16 &bla:int)) [line 21, column 5]\n " shape="box"] +"objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_5" [label="5: BinaryOperatorStmt: Assign \n n$15=*&x:int [line 21, column 17]\n n$16=*&bla:int [line 21, column 17]\n *&addblock2:_fn_(*)=(_fun_objc_blockobjc_blockmain1_2_3,([by ref]n$15 &x:int),([by ref]n$16 &bla:int)) [line 21, column 5]\n " shape="box"] "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_5" -> "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_4" ; @@ -84,7 +84,7 @@ digraph cfg { "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_6" -> "objc_blockmain1_2.0d332204bbe33f46a9283d2c0df5700a_5" ; -"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_1" [label="1: Start objc_blockobjc_blockmain1_2_3\nFormals: x:int bla:int z:int\nLocals: \nCaptured: x:int bla:int \n " color=yellow style=filled] +"objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_1" [label="1: Start objc_blockobjc_blockmain1_2_3\nFormals: x:int bla:int z:int\nLocals: \nCaptured: [by ref]x:int [by ref]bla:int \n " color=yellow style=filled] "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_1" -> "objc_blockobjc_blockmain1_2_3.0824f0806cf4ebad2920e9a12535d20e_3" ; diff --git a/infer/tests/codetoanalyze/objc/shared/block/block_no_args.m.dot b/infer/tests/codetoanalyze/objc/shared/block/block_no_args.m.dot index d688eed67..bf66678e0 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/block_no_args.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/block/block_no_args.m.dot @@ -1,6 +1,6 @@ /* @generated */ digraph cfg { -"objc_blockBlock_no_args.m_1.4d7585adf186f5ddc971eca39c81e1b8_1" [label="1: Start objc_blockBlock_no_args.m_1\nFormals: z:int\nLocals: \nCaptured: z:int \n " color=yellow style=filled] +"objc_blockBlock_no_args.m_1.4d7585adf186f5ddc971eca39c81e1b8_1" [label="1: Start objc_blockBlock_no_args.m_1\nFormals: z:int\nLocals: \nCaptured: [by ref]z:int \n " color=yellow style=filled] "objc_blockBlock_no_args.m_1.4d7585adf186f5ddc971eca39c81e1b8_1" -> "objc_blockBlock_no_args.m_1.4d7585adf186f5ddc971eca39c81e1b8_3" ; @@ -66,7 +66,7 @@ digraph cfg { "m#Block_no_args#instance.385f8c4982ef6acc28cdc868a8cd4272_11" -> "m#Block_no_args#instance.385f8c4982ef6acc28cdc868a8cd4272_10" ; -"m#Block_no_args#instance.385f8c4982ef6acc28cdc868a8cd4272_12" [label="12: BinaryOperatorStmt: Assign \n n$7=*&z:int [line 23, column 7]\n *&b:_fn_(*)=(_fun_objc_blockBlock_no_args.m_1,(n$7 &z:int)) [line 23, column 3]\n " shape="box"] +"m#Block_no_args#instance.385f8c4982ef6acc28cdc868a8cd4272_12" [label="12: BinaryOperatorStmt: Assign \n n$7=*&z:int [line 23, column 7]\n *&b:_fn_(*)=(_fun_objc_blockBlock_no_args.m_1,([by ref]n$7 &z:int)) [line 23, column 3]\n " shape="box"] "m#Block_no_args#instance.385f8c4982ef6acc28cdc868a8cd4272_12" -> "m#Block_no_args#instance.385f8c4982ef6acc28cdc868a8cd4272_11" ; diff --git a/infer/tests/codetoanalyze/objc/shared/block/block_release.m.dot b/infer/tests/codetoanalyze/objc/shared/block/block_release.m.dot index 1b118ff01..26681edf7 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/block_release.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/block/block_release.m.dot @@ -1,6 +1,6 @@ /* @generated */ digraph cfg { -"objc_blockMy_manager.blockReleaseNoLeak_1(struct CGImage).d2039f8bbb0530575d5ff258d059d268_1" [label="1: Start objc_blockMy_manager.blockReleaseNoLeak_1\nFormals: newImage:CGImage* a:int\nLocals: \nCaptured: newImage:CGImage* \n " color=yellow style=filled] +"objc_blockMy_manager.blockReleaseNoLeak_1(struct CGImage).d2039f8bbb0530575d5ff258d059d268_1" [label="1: Start objc_blockMy_manager.blockReleaseNoLeak_1\nFormals: newImage:CGImage* a:int\nLocals: \nCaptured: [by ref]newImage:CGImage* \n " color=yellow style=filled] "objc_blockMy_manager.blockReleaseNoLeak_1(struct CGImage).d2039f8bbb0530575d5ff258d059d268_1" -> "objc_blockMy_manager.blockReleaseNoLeak_1(struct CGImage).d2039f8bbb0530575d5ff258d059d268_5" ; @@ -60,7 +60,7 @@ digraph cfg { "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_8" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_5" ; "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_8" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_6" ; -"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_9" [label="9: BinaryOperatorStmt: Assign \n n$9=*&newImage:CGImage* [line 23, column 7]\n *&b:_fn_(*)=(_fun_objc_blockMy_manager.blockReleaseNoLeak_1,(n$9 &newImage:CGImage*)) [line 23, column 3]\n " shape="box"] +"blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_9" [label="9: BinaryOperatorStmt: Assign \n n$9=*&newImage:CGImage* [line 23, column 7]\n *&b:_fn_(*)=(_fun_objc_blockMy_manager.blockReleaseNoLeak_1,([by ref]n$9 &newImage:CGImage*)) [line 23, column 3]\n " shape="box"] "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_9" -> "blockReleaseNoLeak#My_manager#instance.0c48f80f024250b18a529440f1313af6_8" ; diff --git a/infer/tests/codetoanalyze/objc/shared/block/dispatch.m.dot b/infer/tests/codetoanalyze/objc/shared/block/dispatch.m.dot index 03b6b4e6a..6cf11277e 100644 --- a/infer/tests/codetoanalyze/objc/shared/block/dispatch.m.dot +++ b/infer/tests/codetoanalyze/objc/shared/block/dispatch.m.dot @@ -44,7 +44,7 @@ digraph cfg { "DispatchMain.f6461dbdaeaf9a114cbe40f5f72fbb3f_11" -> "DispatchMain.f6461dbdaeaf9a114cbe40f5f72fbb3f_10" ; -"objc_blockDispatchA.block_attribute_2(class DispatchA).fbb5956dc6c8f95a8f2ae751ac2b44a1_1" [label="1: Start objc_blockDispatchA.block_attribute_2\nFormals: a:DispatchA*\nLocals: \nCaptured: a:DispatchA* \n " color=yellow style=filled] +"objc_blockDispatchA.block_attribute_2(class DispatchA).fbb5956dc6c8f95a8f2ae751ac2b44a1_1" [label="1: Start objc_blockDispatchA.block_attribute_2\nFormals: a:DispatchA*\nLocals: \nCaptured: [by ref]a:DispatchA* \n " color=yellow style=filled] "objc_blockDispatchA.block_attribute_2(class DispatchA).fbb5956dc6c8f95a8f2ae751ac2b44a1_1" -> "objc_blockDispatchA.block_attribute_2(class DispatchA).fbb5956dc6c8f95a8f2ae751ac2b44a1_3" ; @@ -110,7 +110,7 @@ digraph cfg { "block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_3" -> "block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_2" ; -"block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_4" [label="4: Call _fun__dispatch_once \n n$7=*&a:DispatchA* [line 37, column 24]\n n$9=_fun__dispatch_once(&#GB$DispatchA.block_attribute.once:long*,(_fun_objc_blockDispatchA.block_attribute_2,(n$7 &a:DispatchA*)):_fn_(*)) block_params [line 37, column 3]\n " shape="box"] +"block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_4" [label="4: Call _fun__dispatch_once \n n$7=*&a:DispatchA* [line 37, column 24]\n n$9=_fun__dispatch_once(&#GB$DispatchA.block_attribute.once:long*,(_fun_objc_blockDispatchA.block_attribute_2,([by ref]n$7 &a:DispatchA*)):_fn_(*)) block_params [line 37, column 3]\n " shape="box"] "block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_4" -> "block_attribute#DispatchA#class.df997e345dbf19ec3438c667c942e14a_3" ;