brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.6 KiB · 0cf729e Raw
114 lines · plain
1// RUN: %clang_tsan %s -lc++ -fobjc-arc -lobjc -o %t -framework Foundation2// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s3 4// Check that we do not report races between:5// - Object retain and initialize6// - Object release and dealloc7// - Object release and .cxx_destruct8 9#import <Foundation/Foundation.h>10#include "../test.h"11invisible_barrier_t barrier2;12 13class NeedCleanup {14  public:15    int x;16    NeedCleanup() {17      x = 1;18    }19    ~NeedCleanup() {20      x = 0;21    }22};23 24@interface TestDeallocObject : NSObject {25  @public26    int v;27  }28  - (id)init;29  - (void)accessMember;30  - (void)dealloc;31@end32 33@implementation TestDeallocObject34  - (id)init {35    if ([super self]) {36      v = 1;37      return self;38    }39    return nil;40  }41  - (void)accessMember {42    int local = v;43    local++;44  }45  - (void)dealloc {46    v = 0;47  }48@end49 50@interface TestCXXDestructObject : NSObject {51  @public52    NeedCleanup cxxMemberWithCleanup;53  }54  - (void)accessMember;55@end56 57@implementation TestCXXDestructObject58  - (void)accessMember {59    int local = cxxMemberWithCleanup.x;60    local++;61  }62@end63 64@interface TestInitializeObject : NSObject65@end66 67@implementation TestInitializeObject68  static long InitializerAccessedGlobal = 0;69  + (void)initialize {70      InitializerAccessedGlobal = 42;71  }72@end73 74int main(int argc, const char *argv[]) {75  // Ensure that there is no race when calling initialize on TestInitializeObject;76  // otherwise, the locking from ObjC runtime becomes observable. Also ensures that77  // blocks are dispatched to 2 different threads.78  barrier_init(&barrier, 2);79  // Ensure that objects are destructed during block object release.80  barrier_init(&barrier2, 3);81 82  TestDeallocObject *tdo = [[TestDeallocObject alloc] init];83  TestCXXDestructObject *tcxxdo = [[TestCXXDestructObject alloc] init];84  [tdo accessMember];85  [tcxxdo accessMember];86  {87    dispatch_queue_t q = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);88    dispatch_async(q, ^{89        [TestInitializeObject new];90        barrier_wait(&barrier);91        long local = InitializerAccessedGlobal;92        local++;93        [tdo accessMember];94        [tcxxdo accessMember];95        barrier_wait(&barrier2);96    });97    dispatch_async(q, ^{98        barrier_wait(&barrier);99        [TestInitializeObject new];100        long local = InitializerAccessedGlobal;101        local++;102        [tdo accessMember];103        [tcxxdo accessMember];104        barrier_wait(&barrier2);105    });106  }107  barrier_wait(&barrier2);108  NSLog(@"Done.");109  return 0;110}111 112// CHECK: Done.113// CHECK-NOT: ThreadSanitizer: data race114