]> granicus.if.org Git - clang/commitdiff
Added support for thread safety attributes on destructors.
authorDeLesley Hutchins <delesley@google.com>
Fri, 21 Oct 2011 20:51:27 +0000 (20:51 +0000)
committerDeLesley Hutchins <delesley@google.com>
Fri, 21 Oct 2011 20:51:27 +0000 (20:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142685 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 5b813ff2eae5f3e307d2c5447251a13bec6c0cde..7b9a693bb777b59fc1959fdd46ac35022fcaf5e5 100644 (file)
@@ -227,6 +227,9 @@ class MutexID {
       Parent = 0;  // FIXME -- get the parent from DeclStmt
       NumArgs = CE->getNumArgs();
       FunArgs = CE->getArgs();
+    } else if (D && isa<CXXDestructorDecl>(D)) {
+      // There's no such thing as a "destructor call" in the AST.
+      Parent = DeclExp;
     }
 
     // If the attribute has no arguments, then assume the argument is "this".
@@ -879,8 +882,30 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisContext &AC) {
     BuildLockset LocksetBuilder(Handler, Entryset, LocksetFactory);
     for (CFGBlock::const_iterator BI = CurrBlock->begin(),
          BE = CurrBlock->end(); BI != BE; ++BI) {
-      if (const CFGStmt *CfgStmt = dyn_cast<CFGStmt>(&*BI))
-        LocksetBuilder.Visit(const_cast<Stmt*>(CfgStmt->getStmt()));
+      switch (BI->getKind()) {
+        case CFGElement::Statement: {
+          const CFGStmt *CS = cast<CFGStmt>(&*BI);
+          LocksetBuilder.Visit(const_cast<Stmt*>(CS->getStmt()));
+          break;
+        }
+        // Ignore BaseDtor, MemberDtor, and TemporaryDtor for now.
+        case CFGElement::AutomaticObjectDtor: {
+          const CFGAutomaticObjDtor *AD = cast<CFGAutomaticObjDtor>(&*BI);
+          CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
+            AD->getDestructorDecl(AC.getASTContext()));
+          if (!DD->hasAttrs())
+            break;
+
+          // Create a dummy expression,
+          VarDecl *VD = const_cast<VarDecl*>(AD->getVarDecl());
+          DeclRefExpr DRE(VD, VD->getType(), VK_LValue,
+                          AD->getTriggerStmt()->getLocEnd());
+          LocksetBuilder.handleCall(&DRE, DD);
+          break;
+        }
+        default:
+          break;
+      }
     }
     Exitset = LocksetBuilder.getLockset();
 
index 14ef6d1c04763895b5ee26928ebb964b58bb689b..7adead763ee211f7ffc89a63614a622aa0aa40c3 100644 (file)
@@ -1487,9 +1487,7 @@ namespace constructor_destructor_tests {
   };
 
   void fooTest() {
-    // destructors not implemented yet...
-    Foo foo; // \
-    // expected-warning {{mutex 'fooMu' is still locked at the end of function}}
+    Foo foo;
     myVar = 0;
   }
 }
@@ -1500,7 +1498,7 @@ namespace invalid_lock_expression_test {
 class LOCKABLE MyLockable {
 public:
   MyLockable() __attribute__((exclusive_lock_function)) { }
-  ~MyLockable() __attribute__((unlock_function)) { }
+  ~MyLockable() { }
 };
 
 // create an empty lock expression