[PATCH] D60639: [TSan][libdispatch] Port gcd-sync-block-copy.mm to C++

Julian Lettner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 12 15:36:04 PDT 2019


yln created this revision.
Herald added subscribers: llvm-commits, Sanitizers, kubamracek.
Herald added projects: Sanitizers, LLVM.
yln added reviewers: kubamracek, dcoughlin.

Apparently, it makes a difference on where a block lives depending on if
it's passed "inline" versus assigned and then passed via a variable.
Both tests in this commit now give a signal, if `Block_copy` is used in
`dispatch_sync`.

Since these tests use different mechanisms (Objective-C retain versus
C++ copy constructor) as proxies to observe if the block was copied, we
should keep both of them.

Commit, that first avoided the unnecessary copy:
faef7d034a9ec6cb757137adce8e8670ec6c2d7b <https://reviews.llvm.org/rGfaef7d034a9ec6cb757137adce8e8670ec6c2d7b>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D60639

Files:
  compiler-rt/test/tsan/Darwin/gcd-sync-block-copy.mm
  compiler-rt/test/tsan/libdispatch/sync-block-copy.cc


Index: compiler-rt/test/tsan/libdispatch/sync-block-copy.cc
===================================================================
--- /dev/null
+++ compiler-rt/test/tsan/libdispatch/sync-block-copy.cc
@@ -0,0 +1,45 @@
+// This test verifies that dispatch_sync() doesn't actually copy the block under TSan (without TSan, it doesn't).
+
+// RUN: %clangxx_tsan %s -o %t_no_tsan -fno-sanitize=thread
+// RUN: %clangxx_tsan %s -o %t_with_tsan
+
+// RUN: %run %t_no_tsan   2>&1 | FileCheck %s
+// RUN: %run %t_with_tsan 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
+
+#include <dispatch/dispatch.h>
+
+#include <stdio.h>
+
+struct MyClass {
+  static int copyCount;
+  static void printCopyCount() {
+    fprintf(stderr, "copyCount = %d\n", copyCount);
+  }
+  MyClass(){};
+  MyClass(const MyClass &obj) { copyCount++; };
+  void foo() const {
+    fprintf(stderr, "MyClass::foo\n");
+  }
+};
+int MyClass::copyCount = 0;
+
+int main(int argc, const char* argv[]) {
+  dispatch_queue_t q = dispatch_queue_create("my.queue", NULL);
+  MyClass obj;
+  MyClass::printCopyCount();
+  void (^block)(void) = ^{
+    obj.foo();
+  };
+  MyClass::printCopyCount();
+  dispatch_sync(q, block);
+  MyClass::printCopyCount();
+
+  fprintf(stderr, "Done.\n");
+  return 0;
+}
+
+// CHECK: copyCount = 0
+// CHECK: copyCount = 1
+// CHECK: MyClass::foo
+// CHECK: copyCount = 1
+// CHECK: Done.
Index: compiler-rt/test/tsan/Darwin/gcd-sync-block-copy.mm
===================================================================
--- compiler-rt/test/tsan/Darwin/gcd-sync-block-copy.mm
+++ compiler-rt/test/tsan/Darwin/gcd-sync-block-copy.mm
@@ -1,9 +1,9 @@
 // This test verifies that dispatch_sync() doesn't actually copy the block under TSan (without TSan, it doesn't).
 
-// RUN: %clang_tsan -fno-sanitize=thread %s -o %t_no_tsan -framework Foundation
-// RUN: %run %t_no_tsan 2>&1 | FileCheck %s
-
+// RUN: %clang_tsan %s -o %t_no_tsan   -framework Foundation -fno-sanitize=thread
 // RUN: %clang_tsan %s -o %t_with_tsan -framework Foundation
+
+// RUN: %run %t_no_tsan   2>&1 | FileCheck %s
 // RUN: %run %t_with_tsan 2>&1 | FileCheck %s
 
 #import <Foundation/Foundation.h>
@@ -22,9 +22,13 @@
 int main(int argc, const char* argv[]) {
   dispatch_queue_t q = dispatch_queue_create("my.queue", NULL);
   id object = [[MyClass alloc] init];
+  void (^block)(void) = ^ {
+    NSLog(@"%@", object);
+  };
   dispatch_sync(q, ^{
     NSLog(@"%@", object);
   });
+  dispatch_sync(q, block);
   [object release];
   NSLog(@"Done.");
   return 0;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60639.194974.patch
Type: text/x-patch
Size: 2533 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190412/e03fdff0/attachment.bin>


More information about the llvm-commits mailing list