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 | |