From 6f5f20570a04a97d42128396571043cdd756fcd8 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 9 May 2014 17:08:01 +0000 Subject: [PATCH] ThreadSafetyAnalysis: Don't crash when trying to analyze objc methods. 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 --- .../Analysis/Analyses/ThreadSafetyCommon.h | 6 +++--- lib/Analysis/ThreadSafetyCommon.cpp | 10 ++++++---- test/SemaObjC/warn-thread-safety-analysis.m | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 test/SemaObjC/warn-thread-safety-analysis.m diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 5ad8132e47..c01114fd86 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -193,8 +193,8 @@ public: const CFG *getGraph() const { return CFGraph; } CFG *getGraph() { return CFGraph; } - const FunctionDecl *getDecl() const { - return dyn_cast(ACtx->getDecl()); + const NamedDecl *getDecl() const { + return dyn_cast(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); diff --git a/lib/Analysis/ThreadSafetyCommon.cpp b/lib/Analysis/ThreadSafetyCommon.cpp index 0a6efebd31..fb96834b3e 100644 --- a/lib/Analysis/ThreadSafetyCommon.cpp +++ b/lib/Analysis/ThreadSafetyCommon.cpp @@ -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(D) ? cast(D)->parameters() + : cast(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 index 0000000000..0e29ff2535 --- /dev/null +++ b/test/SemaObjC/warn-thread-safety-analysis.m @@ -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 -- 2.40.0