diff options
Diffstat (limited to 'test/CodeGenObjC/synchronized.m')
| -rw-r--r-- | test/CodeGenObjC/synchronized.m | 56 | 
1 files changed, 47 insertions, 9 deletions
diff --git a/test/CodeGenObjC/synchronized.m b/test/CodeGenObjC/synchronized.m index 1af82345e0bc..2a809063fe03 100644 --- a/test/CodeGenObjC/synchronized.m +++ b/test/CodeGenObjC/synchronized.m @@ -1,6 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -triple=i686-apple-darwin9 -o %t %s -O2 -// RUN: grep 'ret i32' %t | count 1 -// RUN: grep 'ret i32 1' %t | count 1 +// RUN: %clang_cc1 -emit-llvm -triple=i686-apple-darwin9 -o - %s -O2 | FileCheck %s  @interface MyClass  { @@ -10,31 +8,71 @@  @implementation MyClass +// CHECK: define internal void @"\01-[MyClass method]"  - (void)method  { -	@synchronized(self) -	{ -	} +  // CHECK: call void @objc_sync_enter +  // CHECK: call void @objc_exception_try_enter +  // CHECK: call i32 @_setjmp +  @synchronized(self) { +  }  }  @end +// CHECK: define void @foo(  void foo(id a) { +  // CHECK: [[A:%.*]] = alloca i8* +  // CHECK: [[SYNC:%.*]] = alloca i8* + +  // CHECK:      store i8* [[AVAL:%.*]], i8** [[A]] +  // CHECK-NEXT: call void @objc_sync_enter(i8* [[AVAL]]) +  // CHECK-NEXT: store i8* [[AVAL]], i8** [[SYNC]] +  // CHECK-NEXT: call void @objc_exception_try_enter +  // CHECK:      call i32 @_setjmp    @synchronized(a) { +    // This is unreachable, but the optimizers can't know that. +    // CHECK: call void asm sideeffect "", "=*m,=*m,=*m"(i8** [[A]], i8** [[SYNC]] +    // CHECK: call void @objc_sync_exit +    // CHECK: call i8* @objc_exception_extract +    // CHECK: call void @objc_exception_throw +    // CHECK: unreachable + +    // CHECK:      call void @objc_exception_try_exit +    // CHECK:      [[T:%.*]] = load i8** [[SYNC]] +    // CHECK-NEXT: call void @objc_sync_exit +    // CHECK: ret void      return;    } +  } +// CHECK: define i32 @f0(  int f0(id a) { +  // TODO: we can optimize the ret to a constant if we can figure out +  // either that x isn't stored to within the synchronized block or +  // that the synchronized block can't longjmp. + +  // CHECK: [[X:%.*]] = alloca i32 +  // CHECK: store i32 1, i32* [[X]]    int x = 0;    @synchronized((x++, a)) {        } -  return x; // ret i32 1 + +  // CHECK: [[T:%.*]] = load i32* [[X]] +  // CHECK: ret i32 [[T]] +  return x;  } +// CHECK: define void @f1(  void f1(id a) { -  // The trick here is that the return shouldn't go through clean up, -  // but there isn't a simple way to check this property. +  // Check that the return doesn't go through the cleanup. +  extern void opaque(void); +  opaque(); + +  // CHECK: call void @opaque() +  // CHECK-NEXT: ret void +    @synchronized(({ return; }), a) {      return;    }  | 
