aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Analysis/ThreadSafetyCommon.cpp21
-rw-r--r--clang/test/SemaObjCXX/no-crash-thread-safety-analysis.mm15
-rw-r--r--clang/test/SemaObjCXX/thread-safety-analysis.h17
-rw-r--r--clang/test/SemaObjCXX/warn-thread-safety-analysis.mm18
4 files changed, 46 insertions, 25 deletions
diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp
index e687d96..373dfc7 100644
--- a/clang/lib/Analysis/ThreadSafetyCommon.cpp
+++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp
@@ -276,18 +276,23 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
// Function parameters require substitution and/or renaming.
if (const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
- const auto *FD =
- cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
unsigned I = PV->getFunctionScopeIndex();
-
- if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
- // Substitute call arguments for references to function parameters
- assert(I < Ctx->NumArgs);
- return translate(Ctx->FunArgs[I], Ctx->Prev);
+ const DeclContext *D = PV->getDeclContext();
+ if (Ctx && Ctx->FunArgs) {
+ const Decl *Canonical = Ctx->AttrDecl->getCanonicalDecl();
+ if (isa<FunctionDecl>(D)
+ ? (cast<FunctionDecl>(D)->getCanonicalDecl() == Canonical)
+ : (cast<ObjCMethodDecl>(D)->getCanonicalDecl() == Canonical)) {
+ // Substitute call arguments for references to function parameters
+ assert(I < Ctx->NumArgs);
+ return translate(Ctx->FunArgs[I], Ctx->Prev);
+ }
}
// Map the param back to the param of the original function declaration
// for consistent comparisons.
- VD = FD->getParamDecl(I);
+ VD = isa<FunctionDecl>(D)
+ ? cast<FunctionDecl>(D)->getCanonicalDecl()->getParamDecl(I)
+ : cast<ObjCMethodDecl>(D)->getCanonicalDecl()->getParamDecl(I);
}
// For non-local variables, treat it as a reference to a named object.
diff --git a/clang/test/SemaObjCXX/no-crash-thread-safety-analysis.mm b/clang/test/SemaObjCXX/no-crash-thread-safety-analysis.mm
new file mode 100644
index 0000000..6abd391
--- /dev/null
+++ b/clang/test/SemaObjCXX/no-crash-thread-safety-analysis.mm
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -Wno-objc-root-class %s
+
+// Thread safety analysis used to crash when used with ObjC methods.
+
+#include "thread-safety-analysis.h"
+
+@interface MyInterface
+- (void)doIt:(class Lock *)myLock;
+@end
+
+@implementation MyInterface
+- (void)doIt:(class Lock *)myLock {
+ AutoLock lock(*myLock);
+}
+@end
diff --git a/clang/test/SemaObjCXX/thread-safety-analysis.h b/clang/test/SemaObjCXX/thread-safety-analysis.h
new file mode 100644
index 0000000..f657b7e
--- /dev/null
+++ b/clang/test/SemaObjCXX/thread-safety-analysis.h
@@ -0,0 +1,17 @@
+class __attribute__((lockable)) Lock {
+public:
+ void Acquire() __attribute__((exclusive_lock_function())) {}
+ void Release() __attribute__((unlock_function())) {}
+};
+
+class __attribute__((scoped_lockable)) AutoLock {
+public:
+ AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock)))
+ : lock_(lock) {
+ lock.Acquire();
+ }
+ ~AutoLock() __attribute__((unlock_function())) { lock_.Release(); }
+
+private:
+ Lock &lock_;
+};
diff --git a/clang/test/SemaObjCXX/warn-thread-safety-analysis.mm b/clang/test/SemaObjCXX/warn-thread-safety-analysis.mm
index 262ab7d..a50c6f2 100644
--- a/clang/test/SemaObjCXX/warn-thread-safety-analysis.mm
+++ b/clang/test/SemaObjCXX/warn-thread-safety-analysis.mm
@@ -1,22 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s
-class __attribute__((lockable)) Lock {
-public:
- void Acquire() __attribute__((exclusive_lock_function())) {}
- void Release() __attribute__((unlock_function())) {}
-};
-
-class __attribute__((scoped_lockable)) AutoLock {
-public:
- AutoLock(Lock &lock) __attribute__((exclusive_lock_function(lock)))
- : lock_(lock) {
- lock.Acquire();
- }
- ~AutoLock() __attribute__((unlock_function())) { lock_.Release(); }
-
-private:
- Lock &lock_;
-};
+#include "thread-safety-analysis.h"
@interface MyInterface {
@private