diff --git a/infer/src/checkers/liveness.ml b/infer/src/checkers/liveness.ml index 4933e1c61..7cbb6ecb8 100644 --- a/infer/src/checkers/liveness.ml +++ b/infer/src/checkers/liveness.ml @@ -48,27 +48,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct add_live_actuals_ actuals live_acc - (* In C++14, for a lambda at block scope, constexpr variables in the - 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 + let exec_instr astate _ _ = function | Sil.Load (lhs_id, _, _, _) when Ident.is_none lhs_id -> (* dummy deref inserted by frontend--don't count as a read *) astate @@ -87,7 +67,6 @@ module TransferFunctions (CFG : ProcCfg.S) = struct | Sil.Call ((ret_id, _), call_exp, actuals, _, _) -> Domain.remove (Var.of_id ret_id) astate |> exp_add_live call_exp |> add_live_actuals actuals call_exp - |> add_local_consts_for_lambdas pdesc call_exp | Sil.Remove_temps _ | Abstract _ | Nullify _ -> astate diff --git a/infer/tests/codetoanalyze/cpp/liveness/dead_stores_constexpr.cpp b/infer/tests/codetoanalyze/cpp/liveness/dead_stores_constexpr.cpp index 139a3a93a..313814df8 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/dead_stores_constexpr.cpp +++ b/infer/tests/codetoanalyze/cpp/liveness/dead_stores_constexpr.cpp @@ -17,7 +17,7 @@ void capture_constexpr_good() { void call_it(void (*f)(void)) { f(); } -void FP_capture_constexpr_good() { +void capture_constexpr2_good() { constexpr int x = 1; auto lambda = []() { foo(x); @@ -26,6 +26,14 @@ void FP_capture_constexpr_good() { 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 void FN_capture_constexpr_good() { constexpr int x = 10; diff --git a/infer/tests/codetoanalyze/cpp/liveness/issues.exp b/infer/tests/codetoanalyze/cpp/liveness/issues.exp index 2a8fd1d86..56b16d825 100644 --- a/infer/tests/codetoanalyze/cpp/liveness/issues.exp +++ b/infer/tests/codetoanalyze/cpp/liveness/issues.exp @@ -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::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_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, instanciateTemplateBad, 3, DEAD_STORE, no_bucket, ERROR, [Write of unused value]