aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/ThreadSafety.cpp
diff options
context:
space:
mode:
authorHaojian Wu <hokein@google.com>2018-08-13 12:50:30 +0000
committerHaojian Wu <hokein@google.com>2018-08-13 12:50:30 +0000
commit74e0f40d9819bfe539dae50650dc0f2e76b37583 (patch)
treea764aa8e9b12f7ba25b02fbbebff0ed9bce56f3d /clang/lib/Analysis/ThreadSafety.cpp
parent7b31fae9836ccc3973c01117aebcba643e34e7fe (diff)
downloadllvm-74e0f40d9819bfe539dae50650dc0f2e76b37583.zip
llvm-74e0f40d9819bfe539dae50650dc0f2e76b37583.tar.gz
llvm-74e0f40d9819bfe539dae50650dc0f2e76b37583.tar.bz2
Revert "Allow relockable scopes with thread safety attributes."
This reverts commit r339456. The change introduces a new crash, see class SCOPED_LOCKABLE FileLock { public: explicit FileLock() EXCLUSIVE_LOCK_FUNCTION(file_); ~FileLock() UNLOCK_FUNCTION(file_); void Lock() EXCLUSIVE_LOCK_FUNCTION(file_); Mutex file_; }; void relockShared2() { FileLock file_lock; file_lock.Lock(); } llvm-svn: 339558
Diffstat (limited to 'clang/lib/Analysis/ThreadSafety.cpp')
-rw-r--r--clang/lib/Analysis/ThreadSafety.cpp82
1 files changed, 14 insertions, 68 deletions
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 9884001..a8c17d5 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -86,8 +86,8 @@ static void warnInvalidLock(ThreadSafetyHandler &Handler,
namespace {
-/// A set of CapabilityExpr objects, which are compiled from thread safety
-/// attributes on a function.
+/// A set of CapabilityInfo objects, which are compiled from the
+/// requires attributes on a function.
class CapExprSet : public SmallVector<CapabilityExpr, 4> {
public:
/// Push M onto list, but discard duplicates.
@@ -944,23 +944,6 @@ public:
if (FullyRemove)
FSet.removeLock(FactMan, Cp);
}
-
- void Relock(FactSet &FSet, FactManager &FactMan, LockKind LK,
- SourceLocation RelockLoc, ThreadSafetyHandler &Handler,
- StringRef DiagKind) const {
- for (const auto *UnderlyingMutex : UnderlyingMutexes) {
- CapabilityExpr UnderCp(UnderlyingMutex, false);
-
- // We're relocking the underlying mutexes. Warn on double locking.
- if (FSet.findLock(FactMan, UnderCp))
- Handler.handleDoubleLock(DiagKind, UnderCp.toString(), RelockLoc);
- else {
- FSet.removeLock(FactMan, !UnderCp);
- FSet.addLock(FactMan, llvm::make_unique<LockableFactEntry>(UnderCp, LK,
- RelockLoc));
- }
- }
- }
};
/// Class which implements the core thread safety analysis routines.
@@ -991,9 +974,6 @@ public:
void removeLock(FactSet &FSet, const CapabilityExpr &CapE,
SourceLocation UnlockLoc, bool FullyRemove, LockKind Kind,
StringRef DiagKind);
- void relockScopedLock(FactSet &FSet, const CapabilityExpr &CapE,
- SourceLocation RelockLoc, LockKind Kind,
- StringRef DiagKind);
template <typename AttrType>
void getMutexIDs(CapExprSet &Mtxs, AttrType *Attr, Expr *Exp,
@@ -1305,27 +1285,6 @@ void ThreadSafetyAnalyzer::removeLock(FactSet &FSet, const CapabilityExpr &Cp,
DiagKind);
}
-void ThreadSafetyAnalyzer::relockScopedLock(FactSet &FSet,
- const CapabilityExpr &Cp,
- SourceLocation RelockLoc,
- LockKind Kind, StringRef DiagKind) {
- if (Cp.shouldIgnore())
- return;
-
- const FactEntry *LDat = FSet.findLock(FactMan, Cp);
- if (!LDat) {
- // FIXME: It's possible to manually destruct the scope and then relock it.
- // Should that be a separate warning? For now we pretend nothing happened.
- // It's undefined behavior, so not related to thread safety.
- return;
- }
-
- // We should only land here if Cp is a scoped capability, so if we have any
- // fact, it must be a ScopedLockableFactEntry.
- const auto *SLDat = static_cast<const ScopedLockableFactEntry *>(LDat);
- SLDat->Relock(FSet, FactMan, Kind, RelockLoc, Handler, DiagKind);
-}
-
/// Extract the list of mutexIDs from the attribute on an expression,
/// and push them onto Mtxs, discarding any duplicates.
template <typename AttrType>
@@ -1767,19 +1726,14 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) {
StringRef CapDiagKind = "mutex";
// Figure out if we're constructing an object of scoped lockable class
- bool isScopedConstructor = false, isScopedMemberCall = false;
+ bool isScopedVar = false;
if (VD) {
if (const auto *CD = dyn_cast<const CXXConstructorDecl>(D)) {
const CXXRecordDecl* PD = CD->getParent();
if (PD && PD->hasAttr<ScopedLockableAttr>())
- isScopedConstructor = true;
+ isScopedVar = true;
}
}
- if (const auto *MCD = dyn_cast<const CXXMemberCallExpr>(Exp)) {
- const CXXRecordDecl *PD = MCD->getRecordDecl();
- if (PD && PD->hasAttr<ScopedLockableAttr>())
- isScopedMemberCall = true;
- }
for(const Attr *At : D->attrs()) {
switch (At->getKind()) {
@@ -1859,7 +1813,7 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) {
POK_FunctionCall, ClassifyDiagnostic(A),
Exp->getExprLoc());
// use for adopting a lock
- if (isScopedConstructor) {
+ if (isScopedVar) {
Analyzer->getMutexIDs(A->isShared() ? ScopedSharedReqs
: ScopedExclusiveReqs,
A, Exp, D, VD);
@@ -1892,24 +1846,16 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) {
Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Generic, CapDiagKind);
// Add locks.
- if (isScopedMemberCall) {
- // If the call is on a scoped capability, we need to relock instead.
- for (const auto &M : ExclusiveLocksToAdd)
- Analyzer->relockScopedLock(FSet, M, Loc, LK_Exclusive, CapDiagKind);
- for (const auto &M : SharedLocksToAdd)
- Analyzer->relockScopedLock(FSet, M, Loc, LK_Shared, CapDiagKind);
- } else {
- for (const auto &M : ExclusiveLocksToAdd)
- Analyzer->addLock(FSet, llvm::make_unique<LockableFactEntry>(
- M, LK_Exclusive, Loc, isScopedConstructor),
- CapDiagKind);
- for (const auto &M : SharedLocksToAdd)
- Analyzer->addLock(FSet, llvm::make_unique<LockableFactEntry>(
- M, LK_Shared, Loc, isScopedConstructor),
- CapDiagKind);
- }
+ for (const auto &M : ExclusiveLocksToAdd)
+ Analyzer->addLock(FSet, llvm::make_unique<LockableFactEntry>(
+ M, LK_Exclusive, Loc, isScopedVar),
+ CapDiagKind);
+ for (const auto &M : SharedLocksToAdd)
+ Analyzer->addLock(FSet, llvm::make_unique<LockableFactEntry>(
+ M, LK_Shared, Loc, isScopedVar),
+ CapDiagKind);
- if (isScopedConstructor) {
+ if (isScopedVar) {
// Add the managing object as a dummy mutex, mapped to the underlying mutex.
SourceLocation MLoc = VD->getLocation();
DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, VD->getLocation());