aaronpuchert created this revision. aaronpuchert added reviewers: aaron.ballman, delesley. Herald added subscribers: cfe-commits, kristina.
When people are really sure they'll get the lock they sometimes use __builtin_expect. It's also used by some assertion implementations. Asserting that try-lock succeeded is basically the same as asserting that the lock is not held by anyone else (and acquiring it). Repository: rC Clang https://reviews.llvm.org/D52398 Files: lib/Analysis/ThreadSafety.cpp test/SemaCXX/warn-thread-safety-analysis.cpp Index: test/SemaCXX/warn-thread-safety-analysis.cpp =================================================================== --- test/SemaCXX/warn-thread-safety-analysis.cpp +++ test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1754,14 +1754,29 @@ mu.Unlock(); } + void foo2_builtin_expect() { + if (__builtin_expect(!mu.TryLock(), false)) + return; + a = 2; + mu.Unlock(); + } + void foo3() { bool b = mu.TryLock(); if (b) { a = 3; mu.Unlock(); } } + void foo3_builtin_expect() { + bool b = mu.TryLock(); + if (__builtin_expect(b, true)) { + a = 3; + mu.Unlock(); + } + } + void foo4() { bool b = mu.TryLock(); if (!b) return; Index: lib/Analysis/ThreadSafety.cpp =================================================================== --- lib/Analysis/ThreadSafety.cpp +++ lib/Analysis/ThreadSafety.cpp @@ -33,6 +33,7 @@ #include "clang/Analysis/Analyses/ThreadSafetyUtil.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/CFG.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" @@ -1388,8 +1389,11 @@ if (!Cond) return nullptr; - if (const auto *CallExp = dyn_cast<CallExpr>(Cond)) + if (const auto *CallExp = dyn_cast<CallExpr>(Cond)) { + if (CallExp->getBuiltinCallee() == Builtin::BI__builtin_expect) + return getTrylockCallExpr(CallExp->getArg(0), C, Negate); return CallExp; + } else if (const auto *PE = dyn_cast<ParenExpr>(Cond)) return getTrylockCallExpr(PE->getSubExpr(), C, Negate); else if (const auto *CE = dyn_cast<ImplicitCastExpr>(Cond))
Index: test/SemaCXX/warn-thread-safety-analysis.cpp =================================================================== --- test/SemaCXX/warn-thread-safety-analysis.cpp +++ test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1754,14 +1754,29 @@ mu.Unlock(); } + void foo2_builtin_expect() { + if (__builtin_expect(!mu.TryLock(), false)) + return; + a = 2; + mu.Unlock(); + } + void foo3() { bool b = mu.TryLock(); if (b) { a = 3; mu.Unlock(); } } + void foo3_builtin_expect() { + bool b = mu.TryLock(); + if (__builtin_expect(b, true)) { + a = 3; + mu.Unlock(); + } + } + void foo4() { bool b = mu.TryLock(); if (!b) return; Index: lib/Analysis/ThreadSafety.cpp =================================================================== --- lib/Analysis/ThreadSafety.cpp +++ lib/Analysis/ThreadSafety.cpp @@ -33,6 +33,7 @@ #include "clang/Analysis/Analyses/ThreadSafetyUtil.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/CFG.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" @@ -1388,8 +1389,11 @@ if (!Cond) return nullptr; - if (const auto *CallExp = dyn_cast<CallExpr>(Cond)) + if (const auto *CallExp = dyn_cast<CallExpr>(Cond)) { + if (CallExp->getBuiltinCallee() == Builtin::BI__builtin_expect) + return getTrylockCallExpr(CallExp->getArg(0), C, Negate); return CallExp; + } else if (const auto *PE = dyn_cast<ParenExpr>(Cond)) return getTrylockCallExpr(PE->getSubExpr(), C, Negate); else if (const auto *CE = dyn_cast<ImplicitCastExpr>(Cond))
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits