forked from OSchip/llvm-project
Thread-safety analysis: ignore edges from throw expressions in CFG.
llvm-svn: 172858
This commit is contained in:
parent
e9ec2458e7
commit
9fa426a666
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue