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