[dead store] Removed special case for constexpr in lambda captures

Summary: We had a special case for fixing false positives on constexpr implicitly captured by lambdas. However, we do not report dead stores on constexpr anymore, hence, do not need the special case anymore. Moreover, the special case was not only capturing constexpr in lambdas, but also any variables which type had `const` (see new test `capture_const_bad` which was not being reported before this diff)

Reviewed By: mbouaziz

Differential Revision: D9654848

fbshipit-source-id: 882fd2804
master
Daiva Naudziuniene 6 years ago committed by Facebook Github Bot
parent 34b0a6165c
commit 2a35d6579b

@ -48,27 +48,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
add_live_actuals_ actuals live_acc add_live_actuals_ actuals live_acc
(* In C++14, for a lambda at block scope, constexpr variables in the let exec_instr astate _ _ = function
reaching scope may be used inside the lambda, even if they are
not captured. For further details:
https://timsong-cpp.github.io/cppwp/n4140/expr.prim.lambda#12 *)
let add_local_consts_for_lambdas pdesc call_exp astate =
let pname = Procdesc.get_proc_name pdesc in
match call_exp with
| Exp.Const (Cfun (Typ.Procname.ObjC_Cpp cpp_pname))
when Typ.Procname.ObjC_Cpp.is_cpp_lambda cpp_pname ->
Procdesc.get_locals pdesc
|> List.fold ~init:astate ~f:(fun acc var_data ->
let open ProcAttributes in
if Typ.is_const var_data.typ.quals then
let const_local_var = Pvar.mk var_data.name pname |> Var.of_pvar in
Domain.add const_local_var acc
else acc )
| _ ->
astate
let exec_instr astate {ProcData.pdesc} _ = function
| Sil.Load (lhs_id, _, _, _) when Ident.is_none lhs_id -> | Sil.Load (lhs_id, _, _, _) when Ident.is_none lhs_id ->
(* dummy deref inserted by frontend--don't count as a read *) (* dummy deref inserted by frontend--don't count as a read *)
astate astate
@ -87,7 +67,6 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Sil.Call ((ret_id, _), call_exp, actuals, _, _) -> | Sil.Call ((ret_id, _), call_exp, actuals, _, _) ->
Domain.remove (Var.of_id ret_id) astate Domain.remove (Var.of_id ret_id) astate
|> exp_add_live call_exp |> add_live_actuals actuals call_exp |> exp_add_live call_exp |> add_live_actuals actuals call_exp
|> add_local_consts_for_lambdas pdesc call_exp
| Sil.Remove_temps _ | Abstract _ | Nullify _ -> | Sil.Remove_temps _ | Abstract _ | Nullify _ ->
astate astate

@ -17,7 +17,7 @@ void capture_constexpr_good() {
void call_it(void (*f)(void)) { f(); } void call_it(void (*f)(void)) { f(); }
void FP_capture_constexpr_good() { void capture_constexpr2_good() {
constexpr int x = 1; constexpr int x = 1;
auto lambda = []() { auto lambda = []() {
foo(x); foo(x);
@ -26,6 +26,14 @@ void FP_capture_constexpr_good() {
call_it(lambda); call_it(lambda);
} }
void capture_const_bad(const int y) {
const int x = y;
[]() {
foo(0);
return;
}();
}
// we always assume const exprs are captured in lambdas // we always assume const exprs are captured in lambdas
void FN_capture_constexpr_good() { void FN_capture_constexpr_good() {
constexpr int x = 10; constexpr int x = 10;

@ -18,5 +18,6 @@ codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus2_bad, 2, DEAD
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus3_bad, 2, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::plus_plus3_bad, 2, DEAD_STORE, no_bucket, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::reassign_param_bad, 0, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::reassign_param_bad, 0, DEAD_STORE, no_bucket, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::use_then_dead_bad, 3, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/dead_stores.cpp, dead_stores::use_then_dead_bad, 3, DEAD_STORE, no_bucket, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/dead_stores_constexpr.cpp, capture_const_bad, 1, DEAD_STORE, no_bucket, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/non_type_template_param.cpp, X<3>_isZeroBad, 1, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/non_type_template_param.cpp, X<3>_isZeroBad, 1, DEAD_STORE, no_bucket, ERROR, [Write of unused value]
codetoanalyze/cpp/liveness/non_type_template_param.cpp, instanciateTemplateBad, 3, DEAD_STORE, no_bucket, ERROR, [Write of unused value] codetoanalyze/cpp/liveness/non_type_template_param.cpp, instanciateTemplateBad, 3, DEAD_STORE, no_bucket, ERROR, [Write of unused value]

Loading…
Cancel
Save