1*67e74705SXin Li// RUN: %clang_cc1 -emit-llvm -triple i686-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -o - %s -O2 | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li@interface MyClass 4*67e74705SXin Li{ 5*67e74705SXin Li} 6*67e74705SXin Li- (void)method; 7*67e74705SXin Li@end 8*67e74705SXin Li 9*67e74705SXin Li@implementation MyClass 10*67e74705SXin Li 11*67e74705SXin Li// CHECK: define internal void @"\01-[MyClass method]" 12*67e74705SXin Li- (void)method 13*67e74705SXin Li{ 14*67e74705SXin Li // CHECK: call i32 @objc_sync_enter 15*67e74705SXin Li // CHECK: call void @objc_exception_try_enter 16*67e74705SXin Li // CHECK: call i32 @_setjmp 17*67e74705SXin Li @synchronized(self) { 18*67e74705SXin Li } 19*67e74705SXin Li} 20*67e74705SXin Li 21*67e74705SXin Li@end 22*67e74705SXin Li 23*67e74705SXin Li// CHECK-LABEL: define void @foo( 24*67e74705SXin Livoid foo(id a) { 25*67e74705SXin Li // CHECK: [[A:%.*]] = alloca i8* 26*67e74705SXin Li // CHECK: [[SYNC:%.*]] = alloca i8* 27*67e74705SXin Li 28*67e74705SXin Li // CHECK: store i8* [[AVAL:%.*]], i8** [[A]] 29*67e74705SXin Li // CHECK-NEXT: call i32 @objc_sync_enter(i8* [[AVAL]]) 30*67e74705SXin Li // CHECK-NEXT: store i8* [[AVAL]], i8** [[SYNC]] 31*67e74705SXin Li // CHECK-NEXT: call void @objc_exception_try_enter 32*67e74705SXin Li // CHECK: call i32 @_setjmp 33*67e74705SXin Li @synchronized(a) { 34*67e74705SXin Li // This is unreachable, but the optimizers can't know that. 35*67e74705SXin Li // CHECK: call void asm sideeffect "", "=*m,=*m,=*m"(i8** nonnull [[A]], i8** nonnull [[SYNC]] 36*67e74705SXin Li // CHECK: call i32 @objc_sync_exit 37*67e74705SXin Li // CHECK: call i8* @objc_exception_extract 38*67e74705SXin Li // CHECK: call void @objc_exception_throw 39*67e74705SXin Li // CHECK: unreachable 40*67e74705SXin Li 41*67e74705SXin Li // CHECK: call void @objc_exception_try_exit 42*67e74705SXin Li // CHECK: [[T:%.*]] = load i8*, i8** [[SYNC]] 43*67e74705SXin Li // CHECK-NEXT: call i32 @objc_sync_exit 44*67e74705SXin Li // CHECK: ret void 45*67e74705SXin Li return; 46*67e74705SXin Li } 47*67e74705SXin Li 48*67e74705SXin Li} 49*67e74705SXin Li 50*67e74705SXin Li// CHECK-LABEL: define i32 @f0( 51*67e74705SXin Liint f0(id a) { 52*67e74705SXin Li // TODO: we can optimize the ret to a constant if we can figure out 53*67e74705SXin Li // either that x isn't stored to within the synchronized block or 54*67e74705SXin Li // that the synchronized block can't longjmp. 55*67e74705SXin Li 56*67e74705SXin Li // CHECK: [[X:%.*]] = alloca i32 57*67e74705SXin Li // CHECK: store i32 1, i32* [[X]] 58*67e74705SXin Li int x = 0; 59*67e74705SXin Li @synchronized((x++, a)) { 60*67e74705SXin Li } 61*67e74705SXin Li 62*67e74705SXin Li // CHECK: [[T:%.*]] = load i32, i32* [[X]] 63*67e74705SXin Li // CHECK: ret i32 [[T]] 64*67e74705SXin Li return x; 65*67e74705SXin Li} 66*67e74705SXin Li 67*67e74705SXin Li// CHECK-LABEL: define void @f1( 68*67e74705SXin Livoid f1(id a) { 69*67e74705SXin Li // Check that the return doesn't go through the cleanup. 70*67e74705SXin Li extern void opaque(void); 71*67e74705SXin Li opaque(); 72*67e74705SXin Li 73*67e74705SXin Li // CHECK: call void @opaque() 74*67e74705SXin Li // CHECK-NEXT: ret void 75*67e74705SXin Li 76*67e74705SXin Li @synchronized(({ return; }), a) { 77*67e74705SXin Li return; 78*67e74705SXin Li } 79*67e74705SXin Li} 80