diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index af639b8ef..a5a9cc35c 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -733,7 +733,7 @@ and ( annotation_reachability and litho = mk_checker ~long:"litho" "Experimental checkers supporting the Litho framework" and liveness = mk_checker ~long:"liveness" ~default:true "the detection of dead stores and unused variables" - and ownership = mk_checker ~long:"ownership" ~default:false "the detection of C++ lifetime bugs" + and ownership = mk_checker ~long:"ownership" ~default:true "the detection of C++ lifetime bugs" and printf_args = mk_checker ~long:"printf-args" ~default:true "the detection of mismatch between the Java printf format strings and the argument types \ diff --git a/infer/src/checkers/Ownership.ml b/infer/src/checkers/Ownership.ml index df97cd1c3..5ae48db71 100644 --- a/infer/src/checkers/Ownership.ml +++ b/infer/src/checkers/Ownership.ml @@ -237,8 +237,12 @@ module TransferFunctions (CFG : ProcCfg.S) = struct Domain.actuals_add_reads other_actuals loc summary astate |> Domain.add placement_base CapabilityDomain.Owned |> Domain.borrow_vars return_base (VarSet.singleton placement_base) |> Option.some + | _ :: other_actuals, Some return_base -> + Domain.actuals_add_reads other_actuals loc summary astate + |> Domain.add return_base CapabilityDomain.Owned |> Option.some | _ -> - L.die InternalError "Placement new without placement arg and/or return" + L.die InternalError "Placement new without placement or return in %a %a" + Typ.Procname.pp pname Location.pp loc else if Typ.Procname.is_constructor pname then match actuals with | (HilExp.AccessExpression Base constructed_base) :: other_actuals -> diff --git a/infer/tests/codetoanalyze/cpp/ownership/use_after_destructor.cpp b/infer/tests/codetoanalyze/cpp/ownership/use_after_destructor.cpp index ad314af07..6e3141148 100644 --- a/infer/tests/codetoanalyze/cpp/ownership/use_after_destructor.cpp +++ b/infer/tests/codetoanalyze/cpp/ownership/use_after_destructor.cpp @@ -144,6 +144,16 @@ S* FN_placement_new_aliasing2_bad() { return alias; // bad, returning freed memory } +void placement_new_non_var_ok() { + struct M { + S* s; + } m; + m.s = new S(1); + m.s->~S(); + new (m.s) S(2); + delete m.s; +} + void destructor_in_loop_ok() { for (int i = 0; i < 10; i++) { S s(1);