xref: /llvm-project/clang/test/CodeGenObjC/synchronized.m (revision 9466b49171dc4b21f56a48594fc82b1e52f5358a)
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(
24void foo(id a) {
25  // CHECK: [[A:%.*]] = alloca ptr
26  // CHECK: [[SYNC:%.*]] = alloca ptr
27
28  // CHECK:      store ptr [[AVAL:%.*]], ptr [[A]]
29  // CHECK-NEXT: call i32 @objc_sync_enter(ptr [[AVAL]])
30  // CHECK-NEXT: store ptr [[AVAL]], ptr [[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"(ptr nonnull elementtype(ptr) [[A]], ptr nonnull elementtype(ptr) [[SYNC]]
36    // CHECK: call i32 @objc_sync_exit
37    // CHECK: call ptr @objc_exception_extract
38    // CHECK: call void @objc_exception_throw
39    // CHECK: unreachable
40
41    // CHECK:      call void @objc_exception_try_exit
42    // CHECK-NEXT: call i32 @objc_sync_exit
43    // CHECK: ret void
44    return;
45  }
46
47}
48
49// CHECK-LABEL: define{{.*}} i32 @f0(
50int f0(id a) {
51  // We can optimize the ret to a constant as we can figure out
52  // that x isn't stored to within the synchronized block.
53
54  // CHECK: [[X:%.*]] = alloca i32
55  // CHECK: store i32 1, ptr [[X]]
56  int x = 0;
57  @synchronized((x++, a)) {
58  }
59
60  // CHECK: ret i32 1
61  return x;
62}
63
64// CHECK-LABEL: define{{.*}} void @f1(
65void f1(id a) {
66  // Check that the return doesn't go through the cleanup.
67  extern void opaque(void);
68  opaque();
69
70  // CHECK: call void @opaque()
71  // CHECK-NEXT: ret void
72
73  @synchronized(({ return; }), a) {
74    return;
75  }
76}
77