John McCall | 260611a | 2012-06-20 06:18:46 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - | FileCheck %s |
Fariborz Jahanian | 68af13f | 2011-03-30 16:11:20 +0000 | [diff] [blame] | 2 | // rdar://9208606 |
| 3 | |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 4 | struct MyStruct { |
| 5 | int x; |
| 6 | int y; |
| 7 | int z; |
Fariborz Jahanian | 68af13f | 2011-03-30 16:11:20 +0000 | [diff] [blame] | 8 | }; |
| 9 | |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 10 | @interface MyClass { |
| 11 | MyStruct _foo; |
Fariborz Jahanian | 68af13f | 2011-03-30 16:11:20 +0000 | [diff] [blame] | 12 | } |
| 13 | |
| 14 | @property (assign, readwrite) const MyStruct& foo; |
| 15 | |
| 16 | - (const MyStruct&) foo; |
| 17 | - (void) setFoo:(const MyStruct&)inFoo; |
| 18 | @end |
| 19 | |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 20 | void test0() { |
| 21 | MyClass* myClass; |
| 22 | MyStruct myStruct; |
Fariborz Jahanian | 68af13f | 2011-03-30 16:11:20 +0000 | [diff] [blame] | 23 | |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 24 | myClass.foo = myStruct; |
Fariborz Jahanian | 68af13f | 2011-03-30 16:11:20 +0000 | [diff] [blame] | 25 | |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 26 | const MyStruct& currentMyStruct = myClass.foo; |
Fariborz Jahanian | 68af13f | 2011-03-30 16:11:20 +0000 | [diff] [blame] | 27 | } |
| 28 | |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 29 | // CHECK: [[C:%.*]] = call dereferenceable({{[0-9]+}}) %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend |
Fariborz Jahanian | 68af13f | 2011-03-30 16:11:20 +0000 | [diff] [blame] | 30 | // CHECK: store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]] |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 31 | |
| 32 | namespace test1 { |
| 33 | struct A { A(); A(const A&); A&operator=(const A&); ~A(); }; |
| 34 | } |
| 35 | @interface Test1 { |
| 36 | test1::A ivar; |
| 37 | } |
Fariborz Jahanian | cd93b96 | 2012-01-06 22:33:54 +0000 | [diff] [blame] | 38 | @property (nonatomic) const test1::A &prop1; |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 39 | @end |
| 40 | @implementation Test1 |
| 41 | @synthesize prop1 = ivar; |
| 42 | @end |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 43 | // CHECK: define internal dereferenceable({{[0-9]+}}) [[A:%.*]]* @"\01-[Test1 prop1]"( |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 44 | // CHECK: [[SELF:%.*]] = alloca [[TEST1:%.*]]*, align 8 |
Pirama Arumuga Nainar | 3ea9e33 | 2015-04-08 08:57:32 -0700 | [diff] [blame] | 45 | // CHECK: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** [[SELF]] |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 46 | // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* |
Pirama Arumuga Nainar | 3ea9e33 | 2015-04-08 08:57:32 -0700 | [diff] [blame] | 47 | // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 0 |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 48 | // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* |
| 49 | // CHECK-NEXT: ret [[A]]* [[T3]] |
| 50 | |
| 51 | // CHECK: define internal void @"\01-[Test1 setProp1:]"( |
Stephen Hines | 176edba | 2014-12-01 14:53:08 -0800 | [diff] [blame] | 52 | // CHECK: call dereferenceable({{[0-9]+}}) [[A]]* @_ZN5test11AaSERKS0_( |
John McCall | 6c11f0b | 2011-09-13 06:00:03 +0000 | [diff] [blame] | 53 | // CHECK-NEXT: ret void |
| 54 | |
John McCall | 01e19be | 2011-11-30 04:42:31 +0000 | [diff] [blame] | 55 | // rdar://problem/10497174 |
| 56 | @interface Test2 |
| 57 | @property int prop; |
| 58 | @end |
| 59 | |
| 60 | // The fact that these are all non-dependent is critical. |
| 61 | template <class T> void test2(Test2 *a) { |
| 62 | int x = a.prop; |
| 63 | a.prop = x; |
| 64 | a.prop += x; |
| 65 | } |
| 66 | template void test2<int>(Test2*); |
Stephen Lin | 93ab6bf | 2013-08-15 06:47:53 +0000 | [diff] [blame] | 67 | // CHECK-LABEL: define weak_odr void @_Z5test2IiEvP5Test2( |
John McCall | 01e19be | 2011-11-30 04:42:31 +0000 | [diff] [blame] | 68 | // CHECK: [[X:%.*]] = alloca i32, |
| 69 | // CHECK: @objc_msgSend |
| 70 | // CHECK: store i32 {{%.*}}, i32* [[X]], |
Pirama Arumuga Nainar | 3ea9e33 | 2015-04-08 08:57:32 -0700 | [diff] [blame] | 71 | // CHECK: load i32, i32* [[X]], |
John McCall | 01e19be | 2011-11-30 04:42:31 +0000 | [diff] [blame] | 72 | // CHECK: @objc_msgSend |
| 73 | // CHECK: @objc_msgSend |
Pirama Arumuga Nainar | 3ea9e33 | 2015-04-08 08:57:32 -0700 | [diff] [blame] | 74 | // CHECK: load i32, i32* [[X]], |
John McCall | 01e19be | 2011-11-30 04:42:31 +0000 | [diff] [blame] | 75 | // CHECK-NEXT: add nsw |
| 76 | // CHECK: @objc_msgSend |
| 77 | // CHECK-NEXT: ret void |
| 78 | |
| 79 | // Same as the previous test, but instantiation-dependent. |
| 80 | template <class T> void test3(Test2 *a) { |
| 81 | int x = (sizeof(T), a).prop; |
| 82 | a.prop = (sizeof(T), x); |
| 83 | a.prop += (sizeof(T), x); |
| 84 | } |
| 85 | template void test3<int>(Test2*); |
Stephen Lin | 93ab6bf | 2013-08-15 06:47:53 +0000 | [diff] [blame] | 86 | // CHECK-LABEL: define weak_odr void @_Z5test3IiEvP5Test2( |
John McCall | 01e19be | 2011-11-30 04:42:31 +0000 | [diff] [blame] | 87 | // CHECK: [[X:%.*]] = alloca i32, |
| 88 | // CHECK: @objc_msgSend |
| 89 | // CHECK: store i32 {{%.*}}, i32* [[X]], |
Pirama Arumuga Nainar | 3ea9e33 | 2015-04-08 08:57:32 -0700 | [diff] [blame] | 90 | // CHECK: load i32, i32* [[X]], |
John McCall | 01e19be | 2011-11-30 04:42:31 +0000 | [diff] [blame] | 91 | // CHECK: @objc_msgSend |
| 92 | // CHECK: @objc_msgSend |
Pirama Arumuga Nainar | 3ea9e33 | 2015-04-08 08:57:32 -0700 | [diff] [blame] | 93 | // CHECK: load i32, i32* [[X]], |
John McCall | 01e19be | 2011-11-30 04:42:31 +0000 | [diff] [blame] | 94 | // CHECK-NEXT: add nsw |
| 95 | // CHECK: @objc_msgSend |
| 96 | // CHECK-NEXT: ret void |