summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAaron Puchert <aaronpuchert@alice-dsl.net>2018-10-03 11:58:19 +0000
committerAaron Puchert <aaronpuchert@alice-dsl.net>2018-10-03 11:58:19 +0000
commit7146b0032fa4f713da5e199e4b96cfa84a630119 (patch)
tree20c1321ca8f440fba0700fc4e32a5636315a73cc /clang
parentd5a39553ff3eafaab675e581d973f700a4d7a6b5 (diff)
downloadbcm5719-llvm-7146b0032fa4f713da5e199e4b96cfa84a630119.tar.gz
bcm5719-llvm-7146b0032fa4f713da5e199e4b96cfa84a630119.zip
Thread safety analysis: Unwrap __builtin_expect in getTrylockCallExpr
Summary: 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). Reviewers: aaron.ballman, delesley Reviewed By: aaron.ballman Subscribers: kristina, cfe-commits Differential Revision: https://reviews.llvm.org/D52398 llvm-svn: 343681
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp6
-rw-r--r--clang/test/SemaCXX/warn-thread-safety-analysis.cpp15
2 files changed, 20 insertions, 1 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 65904fd3600..be1f8b8eebe 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/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 @@ const CallExpr* ThreadSafetyAnalyzer::getTrylockCallExpr(const Stmt *Cond,
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))
diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
index 057fd17608f..ce3c6b9fcc0 100644
--- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -1754,6 +1754,13 @@ struct TestTryLock {
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) {
@@ -1762,6 +1769,14 @@ struct TestTryLock {
}
}
+ 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;
OpenPOWER on IntegriCloud