]> granicus.if.org Git - clang/commitdiff
Thread-safety analysis: ignore edges from throw expressions in CFG.
authorDeLesley Hutchins <delesley@google.com>
Fri, 18 Jan 2013 22:15:45 +0000 (22:15 +0000)
committerDeLesley Hutchins <delesley@google.com>
Fri, 18 Jan 2013 22:15:45 +0000 (22:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172858 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ThreadSafety.cpp
test/SemaCXX/warn-thread-safety-analysis.cpp

index 8fae529643f7d78b2dcbb89820e972179f2d6338..20d8f97e2d267df26ecf9756f80d7f5f4b35f610 100644 (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);
 
index 19e2aa15fd8eed9cfaa962a6096abd8e8f2d8058..26a3df0ef3dc696f1b1676752db3ee70dac5db71 100644 (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
+
+