diff --git a/infer/src/checkers/ThreadSafety.ml b/infer/src/checkers/ThreadSafety.ml index b51682144..873e972f9 100644 --- a/infer/src/checkers/ThreadSafety.ml +++ b/infer/src/checkers/ThreadSafety.ml @@ -910,7 +910,18 @@ let analyze_procedure { Callbacks.proc_desc; tenv; summary; } = let return_attributes = try AttributeMapDomain.find return_var_ap attribute_map with Not_found -> AttributeSetDomain.empty in - let post = thumbs_up, threads, locks, accesses, return_attributes in + (* A hack for modeling lock_guard by releasing a + lock at the end of the procedure, as destructors are not modeled yet *) + let update_locks = match Procdesc.get_proc_name proc_desc with + | ObjC_Cpp _ when locks -> + let matcher = QualifiedCppName.Match.of_fuzzy_qual_names ["std::lock_guard"] in + (* Unlock, if the procedure contains a local field of type std::lock_guard *) + not (List.exists (Procdesc.get_locals proc_desc) ~f:(fun (_, ft) -> + Option.exists (Typ.name ft) ~f:(fun name -> + QualifiedCppName.Match.match_qualifiers matcher (Typ.Name.qual_name name)) + )) + | _ -> locks in + let post = thumbs_up, threads, update_locks, accesses, return_attributes in Summary.update_summary post summary | None -> summary diff --git a/infer/tests/codetoanalyze/cpp/threadsafety/issues.exp b/infer/tests/codetoanalyze/cpp/threadsafety/issues.exp index cf151a33d..35b2f7bf2 100644 --- a/infer/tests/codetoanalyze/cpp/threadsafety/issues.exp +++ b/infer/tests/codetoanalyze/cpp/threadsafety/issues.exp @@ -6,5 +6,6 @@ codetoanalyze/cpp/threadsafety/basics_with_mutex.cpp, basics::BasicsWithHeader_g codetoanalyze/cpp/threadsafety/lock_guard.cpp, basics::LockGuard_get2, 3, THREAD_SAFETY_VIOLATION, [,access to `suspiciously_written`,,access to `suspiciously_written`] codetoanalyze/cpp/threadsafety/lock_guard.cpp, basics::LockGuard_get3, 0, THREAD_SAFETY_VIOLATION, [,access to `not_guarded`,,access to `not_guarded`] codetoanalyze/cpp/threadsafety/lock_guard.cpp, basics::LockGuard_get4, 0, THREAD_SAFETY_VIOLATION, [,access to `suspiciously_read`,,access to `suspiciously_read`] +codetoanalyze/cpp/threadsafety/lock_guard.cpp, basics::LockGuard_test1, 2, THREAD_SAFETY_VIOLATION, [,access to `suspiciously_read`,,access to `suspiciously_read`] codetoanalyze/cpp/threadsafety/lock_guard_with_scope.cpp, basics::LockGuardWithScope_get3, 0, THREAD_SAFETY_VIOLATION, [,access to `not_guarded`,,access to `not_guarded`] codetoanalyze/cpp/threadsafety/lock_guard_with_scope.cpp, basics::LockGuardWithScope_get4, 0, THREAD_SAFETY_VIOLATION, [,access to `suspiciously_read`,,access to `suspiciously_read`] diff --git a/infer/tests/codetoanalyze/cpp/threadsafety/lock_guard.cpp b/infer/tests/codetoanalyze/cpp/threadsafety/lock_guard.cpp index b143eb7ad..5c474b01c 100644 --- a/infer/tests/codetoanalyze/cpp/threadsafety/lock_guard.cpp +++ b/infer/tests/codetoanalyze/cpp/threadsafety/lock_guard.cpp @@ -41,6 +41,11 @@ class LockGuard { int get4() { return suspiciously_read; } + int test1() { + int result = get1(); + return suspiciously_read + result; + } + private: int well_guarded; int suspiciously_read;