r208436 - ThreadSafetyAnalysis: Don't crash when trying to analyze objc methods.
Benjamin Kramer
benny.kra at googlemail.com
Fri May 9 10:08:01 PDT 2014
Author: d0k
Date: Fri May 9 12:08:01 2014
New Revision: 208436
URL: http://llvm.org/viewvc/llvm-project?rev=208436&view=rev
Log:
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.
Added:
cfe/trunk/test/SemaObjC/warn-thread-safety-analysis.m
Modified:
cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp
Modified: cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h?rev=208436&r1=208435&r2=208436&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/ThreadSafetyCommon.h Fri May 9 12:08:01 2014
@@ -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);
Modified: cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp?rev=208436&r1=208435&r2=208436&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp (original)
+++ cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp Fri May 9 12:08:01 2014
@@ -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
}
}
-
-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, co
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;
Added: cfe/trunk/test/SemaObjC/warn-thread-safety-analysis.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/warn-thread-safety-analysis.m?rev=208436&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/warn-thread-safety-analysis.m (added)
+++ cfe/trunk/test/SemaObjC/warn-thread-safety-analysis.m Fri May 9 12:08:01 2014
@@ -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;
+}
+
+ at interface test
+ at end
+
+ at implementation test
+- (void) PR19541 {
+ Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu1' exclusively}}
+}
+
+ at end
More information about the cfe-commits
mailing list