diff --git a/infer/src/IR/Exp.ml b/infer/src/IR/Exp.ml index 62c42246c..20c1d2222 100644 --- a/infer/src/IR/Exp.ml +++ b/infer/src/IR/Exp.ml @@ -206,7 +206,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_pvar, _) -> f acc captured_pvar) + ~f:(fun acc (captured_exp, _, _) -> f acc captured_exp) ~init:captured_acc | Const _ | Lvar _ | Var _ | Sizeof _ -> captured_acc diff --git a/infer/src/IR/Exp.mli b/infer/src/IR/Exp.mli index 085a7f031..b3b4ee398 100644 --- a/infer/src/IR/Exp.mli +++ b/infer/src/IR/Exp.mli @@ -122,8 +122,8 @@ val get_vars : t -> Ident.t list * Pvar.t list val program_vars : t -> Pvar.t Sequence.t (** all the program variables appearing in the expression *) -val fold_captured : f:('a -> Pvar.t -> 'a) -> t -> 'a -> 'a -(** Extract the program variables captured by this expression *) +val fold_captured : f:('a -> t -> 'a) -> t -> 'a -> 'a +(** Fold over the expressions captured by this expression. *) val pp_printenv : Pp.env -> (Pp.env -> F.formatter -> Typ.t -> unit) -> F.formatter -> t -> unit diff --git a/infer/src/checkers/liveness.ml b/infer/src/checkers/liveness.ml index d870f9889..25de8447e 100644 --- a/infer/src/checkers/liveness.ml +++ b/infer/src/checkers/liveness.ml @@ -105,7 +105,16 @@ module CapturedByRefTransferFunctions (CFG : ProcCfg.S) = struct let exec_instr astate _ _ instr = List.fold (Sil.instr_get_exps instr) ~f:(fun acc exp -> - Exp.fold_captured ~f:(fun acc pvar -> Domain.add (Var.of_pvar pvar) acc) exp acc ) + Exp.fold_captured exp + ~f:(fun acc exp -> + match exp with + | Exp.Lvar pvar -> + (* captured by reference, add *) + Domain.add (Var.of_pvar pvar) acc + | _ -> + (* captured by value or init-capture, skip *) + acc ) + acc ) ~init:astate end diff --git a/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp b/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp index 004c691c8..99c3d141f 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp +++ b/infer/tests/codetoanalyze/cpp/liveness/dead_stores.cpp @@ -199,9 +199,7 @@ int dead_store_before_capture_by_ref_bad() { return lambda(); } -// frontend can't tell the difference between capture by ref and capture by -// value yet. -int FN_capture_by_value_bad() { +int capture_by_value_bad() { int x = 1; auto lambda = [=] { return x; }; x = 2; // this is dead diff --git a/infer/tests/codetoanalyze/cpp/liveness/issues.exp b/infer/tests/codetoanalyze/cpp/liveness/issues.exp index 950b6ccad..8de37075c 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/issues.exp +++ b/infer/tests/codetoanalyze/cpp/liveness/issues.exp @@ -1,4 +1,5 @@ codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::FP_assign_array_tricky_ok, 3, DEAD_STORE, [Write of unused value] +codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::capture_by_value_bad, 3, DEAD_STORE, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::dead_pointer_bad, 2, DEAD_STORE, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::dead_store_before_capture_by_ref_bad, 1, DEAD_STORE, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::dead_struct_no_destructor_bad, 0, DEAD_STORE, [Write of unused value]