Thread-safety analysis: ignore edges from throw expressions in CFG.

llvm-svn: 172858
This commit is contained in:
DeLesley Hutchins 2013-01-18 22:15:45 +00:00
parent e9ec2458e7
commit 9fa426a666
2 changed files with 37 additions and 3 deletions

View File

@ -2226,6 +2226,21 @@ void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &FSet1,
}
// Return true if block B never continues to its successors.
inline bool neverReturns(const CFGBlock* B) {
if (B->hasNoReturnElement())
return true;
if (B->empty())
return false;
CFGElement Last = B->back();
if (CFGStmt* S = dyn_cast<CFGStmt>(&Last)) {
if (isa<CXXThrowExpr>(S->getStmt()))
return true;
}
return false;
}
/// \brief Check a function's CFG for thread-safety violations.
///
@ -2355,7 +2370,7 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
// Ignore edges from blocks that can't return.
if ((*PI)->hasNoReturnElement() || !PrevBlockInfo->Reachable)
if (neverReturns(*PI) || !PrevBlockInfo->Reachable)
continue;
// Okay, we can reach this block from the entry.
@ -2372,7 +2387,6 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
}
}
FactSet PrevLockset;
getEdgeLockset(PrevLockset, PrevBlockInfo->ExitSet, *PI, CurrBlock);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -fcxx-exceptions %s
// FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
// FIXME: should also run %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
@ -3882,3 +3882,23 @@ private:
} // namespace GuardedNonPrimitive_MemberAccess
namespace TestThrowExpr {
class Foo {
Mutex mu_;
bool hasError();
void test() {
mu_.Lock();
if (hasError()) {
throw "ugly";
}
mu_.Unlock();
}
};
} // end namespace TestThrowExpr