diff options
author | Aaron Puchert <aaronpuchert@alice-dsl.net> | 2018-10-03 11:58:19 +0000 |
---|---|---|
committer | Aaron Puchert <aaronpuchert@alice-dsl.net> | 2018-10-03 11:58:19 +0000 |
commit | 7146b0032fa4f713da5e199e4b96cfa84a630119 (patch) | |
tree | 20c1321ca8f440fba0700fc4e32a5636315a73cc /clang | |
parent | d5a39553ff3eafaab675e581d973f700a4d7a6b5 (diff) | |
download | bcm5719-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.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-thread-safety-analysis.cpp | 15 |
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; |