]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGenObjC/synchronized.m
Vendor import of clang trunk r161861:
[FreeBSD/FreeBSD.git] / test / CodeGenObjC / synchronized.m
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 void @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: 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 void @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** [[A]], i8** [[SYNC]]
36     // CHECK: call void @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** [[SYNC]]
43     // CHECK-NEXT: call void @objc_sync_exit
44     // CHECK: ret void
45     return;
46   }
47
48 }
49
50 // CHECK: 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* [[X]]
63   // CHECK: ret i32 [[T]]
64   return x;
65 }
66
67 // CHECK: 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 }