[dead stores] report on dead stores to values captured by value in a lambda

Summary:
Before D7100561, the frontend translated capture-by-ref and capture-by-value in the same way.
Now we can tell the difference and report bugs in the capture-by-value case.

Reviewed By: jeremydubreil

Differential Revision: D7102214

fbshipit-source-id: e9d3ac7
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent aca9d034a7
commit e687ef40b3

@ -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

@ -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

@ -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

@ -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

@ -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]

Loading…
Cancel
Save