diff --git a/infer/src/checkers/uninit.ml b/infer/src/checkers/uninit.ml index 1a46161cd..7a2df12e5 100644 --- a/infer/src/checkers/uninit.ml +++ b/infer/src/checkers/uninit.ml @@ -103,6 +103,9 @@ module TransferFunctions (CFG : ProcCfg.S) = struct | Assign (((lhs_var, _), _), _, _) -> let uninit_vars = D.remove lhs_var astate.uninit_vars in {astate with uninit_vars} + | Call (_, Direct callee_pname, _, _, _) + when Typ.Procname.equal callee_pname BuiltinDecl.objc_cpp_throw -> + {astate with uninit_vars= D.empty} | Call (_, call, actuals, _, loc) -> (* in case of intraprocedural only analysis we assume that parameters passed by reference to a function will be initialized inside that function *) diff --git a/infer/tests/codetoanalyze/cpp/uninit/issues.exp b/infer/tests/codetoanalyze/cpp/uninit/issues.exp index c443da408..7bff93098 100644 --- a/infer/tests/codetoanalyze/cpp/uninit/issues.exp +++ b/infer/tests/codetoanalyze/cpp/uninit/issues.exp @@ -1,6 +1,8 @@ +codetoanalyze/cpp/uninit/uninit.cpp, FP_no_warning_noreturn_callee_ok, 7, UNINITIALIZED_VALUE, [] codetoanalyze/cpp/uninit/uninit.cpp, bad1, 2, UNINITIALIZED_VALUE, [] codetoanalyze/cpp/uninit/uninit.cpp, bad2, 2, UNINITIALIZED_VALUE, [] codetoanalyze/cpp/uninit/uninit.cpp, branch1_FP, 11, UNINITIALIZED_VALUE, [] codetoanalyze/cpp/uninit/uninit.cpp, loop1_FP, 10, UNINITIALIZED_VALUE, [] codetoanalyze/cpp/uninit/uninit.cpp, no_init_return_bad, 2, UNINITIALIZED_VALUE, [] codetoanalyze/cpp/uninit/uninit.cpp, ret_undef, 2, UNINITIALIZED_VALUE, [] +codetoanalyze/cpp/uninit/uninit.cpp, warning_when_throw_in_other_branch_bad, 9, UNINITIALIZED_VALUE, [] diff --git a/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp b/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp index 88feca526..4c59edfc5 100644 --- a/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp +++ b/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp @@ -224,3 +224,37 @@ int capture_by_ref_init_ok() { [&x]() { x = 1; }(); return x; } + +int no_warning_on_throw_ok(bool t) { + int x; + if (t) { + x = 2; + } else { + throw; + } + return x; +} + +int warning_when_throw_in_other_branch_bad(int t) { + int x; + if (t > 0) { + x = 2; + } else if (t < 0) { + // reports because x is not initialized in this branch + } else { + throw; + } + return x; +} + +[[noreturn]] void noreturn_function() {} + +int FP_no_warning_noreturn_callee_ok(bool t) { + int x; + if (t) { + x = 2; + } else { + noreturn_function(); + } + return x; +}