blob: 015e55b8f8af83661ce0f3721e614bdef04dd054 [file] [log] [blame]
John McCall260611a2012-06-20 06:18:46 +00001// RUN: %clang_cc1 -emit-llvm -triple i686-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -o - %s -O2 | FileCheck %s
Fariborz Jahanianb79e6612008-11-17 18:03:28 +00002
Fariborz Jahanianf2878e52008-11-21 19:21:53 +00003@interface MyClass
4{
5}
6- (void)method;
7@end
8
9@implementation MyClass
10
John McCall87bb5822010-07-31 23:20:56 +000011// CHECK: define internal void @"\01-[MyClass method]"
Fariborz Jahanianf2878e52008-11-21 19:21:53 +000012- (void)method
13{
Aaron Ballman2d234d732012-09-06 16:44:16 +000014 // CHECK: call i32 @objc_sync_enter
John McCall87bb5822010-07-31 23:20:56 +000015 // CHECK: call void @objc_exception_try_enter
16 // CHECK: call i32 @_setjmp
17 @synchronized(self) {
18 }
Fariborz Jahanianf2878e52008-11-21 19:21:53 +000019}
20
21@end
22
Stephen Lin93ab6bf2013-08-15 06:47:53 +000023// CHECK-LABEL: define void @foo(
Fariborz Jahanianb79e6612008-11-17 18:03:28 +000024void foo(id a) {
John McCall87bb5822010-07-31 23:20:56 +000025 // CHECK: [[A:%.*]] = alloca i8*
John McCall0b251722010-08-04 05:59:32 +000026 // CHECK: [[SYNC:%.*]] = alloca i8*
John McCall87bb5822010-07-31 23:20:56 +000027
John McCall0b251722010-08-04 05:59:32 +000028 // CHECK: store i8* [[AVAL:%.*]], i8** [[A]]
Aaron Ballman2d234d732012-09-06 16:44:16 +000029 // CHECK-NEXT: call i32 @objc_sync_enter(i8* [[AVAL]])
John McCall0b251722010-08-04 05:59:32 +000030 // CHECK-NEXT: store i8* [[AVAL]], i8** [[SYNC]]
31 // CHECK-NEXT: call void @objc_exception_try_enter
32 // CHECK: call i32 @_setjmp
Fariborz Jahanianb79e6612008-11-17 18:03:28 +000033 @synchronized(a) {
John McCall0b251722010-08-04 05:59:32 +000034 // This is unreachable, but the optimizers can't know that.
35 // CHECK: call void asm sideeffect "", "=*m,=*m,=*m"(i8** [[A]], i8** [[SYNC]]
Aaron Ballman2d234d732012-09-06 16:44:16 +000036 // CHECK: call i32 @objc_sync_exit
John McCall0b251722010-08-04 05:59:32 +000037 // 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]]
Aaron Ballman2d234d732012-09-06 16:44:16 +000043 // CHECK-NEXT: call i32 @objc_sync_exit
John McCall87bb5822010-07-31 23:20:56 +000044 // CHECK: ret void
Fariborz Jahanianb79e6612008-11-17 18:03:28 +000045 return;
46 }
John McCall87bb5822010-07-31 23:20:56 +000047
Fariborz Jahanianb79e6612008-11-17 18:03:28 +000048}
49
Stephen Lin93ab6bf2013-08-15 06:47:53 +000050// CHECK-LABEL: define i32 @f0(
Daniel Dunbar1c566672009-02-24 01:43:46 +000051int f0(id a) {
John McCall87bb5822010-07-31 23:20:56 +000052 // 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]]
Daniel Dunbar1c566672009-02-24 01:43:46 +000058 int x = 0;
59 @synchronized((x++, a)) {
60 }
John McCall87bb5822010-07-31 23:20:56 +000061
62 // CHECK: [[T:%.*]] = load i32* [[X]]
63 // CHECK: ret i32 [[T]]
64 return x;
Daniel Dunbar1c566672009-02-24 01:43:46 +000065}
Fariborz Jahanianf2878e52008-11-21 19:21:53 +000066
Stephen Lin93ab6bf2013-08-15 06:47:53 +000067// CHECK-LABEL: define void @f1(
Daniel Dunbar1c566672009-02-24 01:43:46 +000068void f1(id a) {
John McCall87bb5822010-07-31 23:20:56 +000069 // 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
Daniel Dunbar1c566672009-02-24 01:43:46 +000076 @synchronized(({ return; }), a) {
77 return;
78 }
79}