[thread-safety][c++] Model std::unique_lock::owns_lock

Summary:
Code often uses std::unique_lock::owns_lock to test if a deferred lock
using the 2-arg std::unique_lock constructor actually acquired the
lock.

Reviewed By: sblackshear

Differential Revision: D6181631

fbshipit-source-id: 11e9df2
master
Josh Berdine 7 years ago committed by Facebook Github Bot
parent 3bab37b261
commit 149deb97ed

@ -87,6 +87,10 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
in in
fun pname -> fun pname ->
QualifiedCppName.Match.match_qualifiers matcher (Typ.Procname.get_qualifiers pname) QualifiedCppName.Match.match_qualifiers matcher (Typ.Procname.get_qualifiers pname)
and is_cpp_trylock =
let matcher = QualifiedCppName.Match.of_fuzzy_qual_names ["std::unique_lock::owns_lock"] in
fun pname ->
QualifiedCppName.Match.match_qualifiers matcher (Typ.Procname.get_qualifiers pname)
in in
fun pname actuals -> fun pname actuals ->
match pname with match pname with
@ -121,6 +125,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
Lock Lock
| Typ.Procname.ObjC_Cpp _ as pname when is_cpp_unlock pname -> | Typ.Procname.ObjC_Cpp _ as pname when is_cpp_unlock pname ->
Unlock Unlock
| Typ.Procname.ObjC_Cpp _ as pname when is_cpp_trylock pname ->
LockedIfTrue
| pname when Typ.Procname.equal pname BuiltinDecl.__set_locked_attribute -> | pname when Typ.Procname.equal pname BuiltinDecl.__set_locked_attribute ->
Lock Lock
| pname when Typ.Procname.equal pname BuiltinDecl.__delete_locked_attribute -> | pname when Typ.Procname.equal pname BuiltinDecl.__delete_locked_attribute ->

@ -12,3 +12,4 @@ codetoanalyze/cpp/racerd/unique_lock.cpp, basics::UniqueLock_get2, 3, LOCK_CONSI
codetoanalyze/cpp/racerd/unique_lock.cpp, basics::UniqueLock_get2, 4, LOCK_CONSISTENCY_VIOLATION, [<Read trace>,access to `&this.suspiciously_written2`,<Write trace>,access to `&this.suspiciously_written2`] codetoanalyze/cpp/racerd/unique_lock.cpp, basics::UniqueLock_get2, 4, LOCK_CONSISTENCY_VIOLATION, [<Read trace>,access to `&this.suspiciously_written2`,<Write trace>,access to `&this.suspiciously_written2`]
codetoanalyze/cpp/racerd/unique_lock.cpp, basics::UniqueLock_get4, 1, LOCK_CONSISTENCY_VIOLATION, [<Read trace>,access to `&this.suspiciously_read1`,<Write trace>,access to `&this.suspiciously_read1`] codetoanalyze/cpp/racerd/unique_lock.cpp, basics::UniqueLock_get4, 1, LOCK_CONSISTENCY_VIOLATION, [<Read trace>,access to `&this.suspiciously_read1`,<Write trace>,access to `&this.suspiciously_read1`]
codetoanalyze/cpp/racerd/unique_lock.cpp, basics::UniqueLock_get4, 2, LOCK_CONSISTENCY_VIOLATION, [<Read trace>,access to `&this.suspiciously_read2`,<Write trace>,access to `&this.suspiciously_read2`] codetoanalyze/cpp/racerd/unique_lock.cpp, basics::UniqueLock_get4, 2, LOCK_CONSISTENCY_VIOLATION, [<Read trace>,access to `&this.suspiciously_read2`,<Write trace>,access to `&this.suspiciously_read2`]
codetoanalyze/cpp/racerd/unique_lock.cpp, basics::UniqueLock_get5, 5, LOCK_CONSISTENCY_VIOLATION, [<Read trace>,access to `&this.suspiciously_read1`,<Write trace>,access to `&this.suspiciously_read1`]

@ -58,6 +58,15 @@ class UniqueLock {
return result + suspiciously_read2; return result + suspiciously_read2;
} }
int get5() {
std::unique_lock<std::mutex> lock(mutex_, std::try_to_lock);
if (lock.owns_lock()) {
return well_guarded1;
} else {
return suspiciously_read1;
}
}
private: private:
int well_guarded1; int well_guarded1;
int suspiciously_read1; int suspiciously_read1;

Loading…
Cancel
Save