zaks.anna updated this revision to Diff 76643.
zaks.anna added a comment.

Addressed the review comments.

I also added ObjC +initialize method to the list because TSan does not observe 
the guaranteed synchronization between +initialize and initial object accesses.


https://reviews.llvm.org/D25857

Files:
  lib/CodeGen/CodeGenFunction.cpp
  test/CodeGen/sanitize-thread-no-checking-at-run-time.m


Index: test/CodeGen/sanitize-thread-no-checking-at-run-time.m
===================================================================
--- /dev/null
+++ test/CodeGen/sanitize-thread-no-checking-at-run-time.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o 
- %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o 
- %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+
+__attribute__((objc_root_class))
+@interface NSObject
+- (void)dealloc;
+@end
+
+class NeedCleanup {
+public:
+  ~NeedCleanup() __attribute__((no_sanitize("thread"))) {}
+};
+
+@interface MyObject : NSObject {
+  NeedCleanup v;
+};
++ (void) initialize;
+- (void) dealloc;
+@end
+
+@implementation MyObject
++ (void)initialize {
+}
+- (void)dealloc {
+  [super dealloc];
+}
+@end
+
+// WITHOUT-NOT: "sanitize_thread_no_checking_at_run_time"
+
+// TSAN: initialize{{.*}}) [[ATTR:#[0-9]+]]
+// TSAN: dealloc{{.*}}) [[ATTR:#[0-9]+]]
+// TSAN: cxx_destruct{{.*}}) [[ATTR:#[0-9]+]]
+// TSAN: attributes [[ATTR]] = { nounwind {{.*}} 
"sanitize_thread_no_checking_at_run_time" {{.*}} }
+// TSAN-NOT: sanitize_thread
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -731,6 +731,20 @@
   if (SanOpts.has(SanitizerKind::SafeStack))
     Fn->addFnAttr(llvm::Attribute::SafeStack);
 
+  // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize,
+  // .cxx_destruct and all of their calees at run time.
+  if (SanOpts.has(SanitizerKind::Thread)) {
+    if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
+      IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
+      if (OMD->getMethodFamily() == OMF_dealloc ||
+          OMD->getMethodFamily() == OMF_initialize ||
+          (OMD->getSelector().isUnarySelector() && 
II->isStr(".cxx_destruct"))) {
+        Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
+        Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
+      }
+    }
+  }
+
   // Apply xray attributes to the function (as a string, for now)
   if (D && ShouldXRayInstrumentFunction()) {
     if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) {


Index: test/CodeGen/sanitize-thread-no-checking-at-run-time.m
===================================================================
--- /dev/null
+++ test/CodeGen/sanitize-thread-no-checking-at-run-time.m
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+
+__attribute__((objc_root_class))
+@interface NSObject
+- (void)dealloc;
+@end
+
+class NeedCleanup {
+public:
+  ~NeedCleanup() __attribute__((no_sanitize("thread"))) {}
+};
+
+@interface MyObject : NSObject {
+  NeedCleanup v;
+};
++ (void) initialize;
+- (void) dealloc;
+@end
+
+@implementation MyObject
++ (void)initialize {
+}
+- (void)dealloc {
+  [super dealloc];
+}
+@end
+
+// WITHOUT-NOT: "sanitize_thread_no_checking_at_run_time"
+
+// TSAN: initialize{{.*}}) [[ATTR:#[0-9]+]]
+// TSAN: dealloc{{.*}}) [[ATTR:#[0-9]+]]
+// TSAN: cxx_destruct{{.*}}) [[ATTR:#[0-9]+]]
+// TSAN: attributes [[ATTR]] = { nounwind {{.*}} "sanitize_thread_no_checking_at_run_time" {{.*}} }
+// TSAN-NOT: sanitize_thread
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -731,6 +731,20 @@
   if (SanOpts.has(SanitizerKind::SafeStack))
     Fn->addFnAttr(llvm::Attribute::SafeStack);
 
+  // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize,
+  // .cxx_destruct and all of their calees at run time.
+  if (SanOpts.has(SanitizerKind::Thread)) {
+    if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
+      IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
+      if (OMD->getMethodFamily() == OMF_dealloc ||
+          OMD->getMethodFamily() == OMF_initialize ||
+          (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) {
+        Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
+        Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
+      }
+    }
+  }
+
   // Apply xray attributes to the function (as a string, for now)
   if (D && ShouldXRayInstrumentFunction()) {
     if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to