diff --git a/infer/src/checkers/uninit.ml b/infer/src/checkers/uninit.ml index fdafa86d9..6eebcd64d 100644 --- a/infer/src/checkers/uninit.ml +++ b/infer/src/checkers/uninit.ml @@ -31,6 +31,8 @@ end) let intraprocedural_only = true +let is_address_pvar e = match e with Exp.Lvar _ -> true | _ -> false + module TransferFunctions (CFG : ProcCfg.S) = struct module CFG = CFG module Domain = RecordDomain @@ -131,8 +133,14 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = in match instr with | Sil.Load (_, Exp.Lvar pv, _, loc) - | Sil.Store (_, _, Exp.Lvar pv, loc) - when exp_in_set (Exp.Lvar pv) uninit_vars -> + when not (Pvar.is_frontend_tmp pv) && exp_in_set (Exp.Lvar pv) uninit_vars -> + let message = + F.asprintf "The value read from %a was never initialized" Exp.pp (Exp.Lvar pv) + in + report message loc + | Sil.Store (lhs, _, Exp.Lvar pv, loc) + when not (Pvar.is_frontend_tmp pv) && exp_in_set (Exp.Lvar pv) uninit_vars + && not (is_address_pvar lhs) -> let message = F.asprintf "The value read from %a was never initialized" Exp.pp (Exp.Lvar pv) in @@ -186,3 +194,4 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = (Procdesc.get_proc_name proc_desc) ; summary ) else summary + diff --git a/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp b/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp index a3153ccb5..924aa1342 100644 --- a/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp +++ b/infer/tests/codetoanalyze/cpp/uninit/uninit.cpp @@ -140,3 +140,9 @@ int ok6() { // this crashes HIL if we're not careful void deref_magic_addr_ok() { *(int*)0xdeadbeef = 0; } + +char ok7() { + char buf[1024], *res = buf; + res[1] = 'a'; + return res[1]; +}