]> granicus.if.org Git - clang/commitdiff
ThreadSafetyAnalysis: Don't crash when trying to analyze objc methods.
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 9 May 2014 17:08:01 +0000 (17:08 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 9 May 2014 17:08:01 +0000 (17:08 +0000)
The thread safety analysis isn't very useful in ObjC (you can't annotate
ObjC classes or methods) but we can still analyze the actual code and
show violations in usage of C/C++ functions.

Fixes PR19541, which does not use thread safety attributes but crashes
with -Weverything.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208436 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Analysis/Analyses/ThreadSafetyCommon.h
lib/Analysis/ThreadSafetyCommon.cpp
test/SemaObjC/warn-thread-safety-analysis.m [new file with mode: 0644]

index 5ad8132e478406ec054bf3812a0ee1dcd4ac39ea..c01114fd86227cfbbf8c38860959e9479a7e9262 100644 (file)
@@ -193,8 +193,8 @@ public:
   const CFG *getGraph() const { return CFGraph; }
   CFG *getGraph() { return CFGraph; }
 
-  const FunctionDecl *getDecl() const {
-    return dyn_cast<FunctionDecl>(ACtx->getDecl());
+  const NamedDecl *getDecl() const {
+    return dyn_cast<NamedDecl>(ACtx->getDecl());
   }
 
   const PostOrderCFGView *getSortedGraph() const { return SortedGraph; }
@@ -326,7 +326,7 @@ private:
   // We implement the CFGVisitor API
   friend class CFGWalker;
 
-  void enterCFG(CFG *Cfg, const FunctionDecl *D, const CFGBlock *First);
+  void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First);
   void enterCFGBlock(const CFGBlock *B);
   bool visitPredecessors() { return true; }
   void handlePredecessor(const CFGBlock *Pred);
index 0a6efebd3110de1707ad31ad0301b236fe64da2c..fb96834b3e70adfd2828ea25440ba96cdd23fe7e 100644 (file)
@@ -14,6 +14,7 @@
 #include "clang/Analysis/Analyses/ThreadSafetyCommon.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
@@ -634,8 +635,7 @@ void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) {
   }
 }
 
-
-void SExprBuilder::enterCFG(CFG *Cfg, const FunctionDecl *FD,
+void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D,
                             const CFGBlock *First) {
   // Perform initial setup operations.
   unsigned NBlocks = Cfg->getNumBlockIDs();
@@ -649,10 +649,12 @@ void SExprBuilder::enterCFG(CFG *Cfg, const FunctionDecl *FD,
     auto *BB = new (Arena) til::BasicBlock(Arena, 0, B->size());
     BlockMap[B->getBlockID()] = BB;
   }
-  CallCtx.reset(new SExprBuilder::CallingContext(FD));
+  CallCtx.reset(new SExprBuilder::CallingContext(D));
 
   CurrentBB = lookupBlock(&Cfg->getEntry());
-  for (auto *Pm : FD->parameters()) {
+  auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
+                                      : cast<FunctionDecl>(D)->parameters();
+  for (auto *Pm : Parms) {
     QualType T = Pm->getType();
     if (!T.isTrivialType(Pm->getASTContext()))
       continue;
diff --git a/test/SemaObjC/warn-thread-safety-analysis.m b/test/SemaObjC/warn-thread-safety-analysis.m
new file mode 100644 (file)
index 0000000..0e29ff2
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s
+
+struct __attribute__ ((lockable)) Mutex {};
+
+struct Mutex mu1;
+
+int Foo_fun1(int i) __attribute__ ((exclusive_locks_required((mu1)))) {
+  return i;
+}
+
+@interface test
+@end
+
+@implementation test
+- (void) PR19541 {
+  Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu1' exclusively}}
+}
+
+@end