[dead stores] fix FPs due to capture by ref

Reviewed By: jeremydubreil

Differential Revision: D5534605

fbshipit-source-id: e8048a5
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 36ea71a983
commit 25d9f940fe

@ -64,11 +64,24 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary =
let invariant_map =
Analyzer.exec_cfg cfg (ProcData.make_default proc_desc tenv) ~initial:Domain.empty ~debug:true
in
let procname = Procdesc.get_proc_name proc_desc in
let is_cpp_lambda =
match Typ.Procname.get_method procname with "operator()" -> true | _ -> false
in
let is_captured_var pvar =
let pvar_name = Pvar.get_name pvar in
let pvar_matches (name, _) = Mangled.equal name pvar_name in
(* var is captured if the procedure is a lambda and the var is not in the locals or formals *)
is_cpp_lambda
&& not
( List.exists ~f:pvar_matches (Procdesc.get_locals proc_desc)
|| List.exists ~f:pvar_matches (Procdesc.get_formals proc_desc) )
in
let report_dead_store live_vars = function
| Sil.Store (Lvar pvar, _, _, loc)
when not
( Pvar.is_frontend_tmp pvar || Pvar.is_return pvar || Pvar.is_global pvar
|| Domain.mem (Var.of_pvar pvar) live_vars )
|| Domain.mem (Var.of_pvar pvar) live_vars || is_captured_var pvar )
-> let issue_id = Localise.to_issue_id Localise.dead_store in
let message = F.asprintf "The value written to %a is never used" (Pvar.pp Pp.text) pvar in
let ltr = [Errlog.make_trace_element 0 loc "Write of unused value" []] in

@ -124,6 +124,15 @@ int plus_plus_loop_ok(int n) {
return i;
}
void lambda_bad() {
int x = []() {
int y = 1;
y = 2;
return y;
}();
return x;
}
void capture1_ok() {
int x = 1;
[x]() { return x; }();
@ -133,12 +142,31 @@ void capture2_ok(int x) {
[x]() { return x; }();
}
int FP_capture_by_ref_ok() {
int capture_by_ref1_ok() {
int x = 0;
[&x]() { x++; }();
return x;
}
int capture_by_ref2_ok() {
int x = 0;
int y = 0;
[&]() {
x = x + y;
y = x;
}();
return x + y;
}
int FN_capture_by_ref_reuseBad() {
int x = 0;
[&x]() {
x = 1; // dead, but we won't report
x = 2;
}();
return x;
}
void init_capture_ok() {
[i = 0]() { return i; };
}

@ -1,8 +1,8 @@
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::FP_capture_by_ref_ok::lambda_dead_stores.cpp:138:3_operator(), 0, 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_then_live_bad, 1, DEAD_STORE, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::easy_bad, 0, DEAD_STORE, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::lambda_bad::lambda_dead_stores.cpp:128:11_operator(), 1, DEAD_STORE, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus1_bad, 2, DEAD_STORE, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus2_bad, 2, DEAD_STORE, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus3_bad, 2, DEAD_STORE, [Write of unused value]

Loading…
Cancel
Save