1 // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - | FileCheck %s 2 // rdar://9208606 3 4 struct MyStruct { 5 int x; 6 int y; 7 int z; 8 }; 9 10 @interface MyClass { 11 MyStruct _foo; 12 } 13 14 @property (assign, readwrite) const MyStruct& foo; 15 16 - (const MyStruct&) foo; 17 - (void) setFoo:(const MyStruct&)inFoo; 18 @end 19 20 void test0() { 21 MyClass* myClass; 22 MyStruct myStruct; 23 24 myClass.foo = myStruct; 25 26 const MyStruct& currentMyStruct = myClass.foo; 27 } 28 29 // CHECK: [[C:%.*]] = call dereferenceable({{[0-9]+}}) %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend 30 // CHECK: store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]] 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 } 38 @property (nonatomic) const test1::A &prop1; 39 @end 40 @implementation Test1 41 @synthesize prop1 = ivar; 42 @end 43 // CHECK: define internal dereferenceable({{[0-9]+}}) [[A:%.*]]* @"\01-[Test1 prop1]"( 44 // CHECK: [[SELF:%.*]] = alloca [[TEST1:%.*]]*, align 8 45 // CHECK: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** [[SELF]] 46 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* 47 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 0 48 // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]* 49 // CHECK-NEXT: ret [[A]]* [[T3]] 50 51 // CHECK: define internal void @"\01-[Test1 setProp1:]"( 52 // CHECK: call dereferenceable({{[0-9]+}}) [[A]]* @_ZN5test11AaSERKS0_( 53 // CHECK-NEXT: ret void 54 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*); 67 // CHECK-LABEL: define weak_odr void @_Z5test2IiEvP5Test2( 68 // CHECK: [[X:%.*]] = alloca i32, 69 // CHECK: @objc_msgSend 70 // CHECK: store i32 {{%.*}}, i32* [[X]], 71 // CHECK: load i32, i32* [[X]], 72 // CHECK: @objc_msgSend 73 // CHECK: @objc_msgSend 74 // CHECK: load i32, i32* [[X]], 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*); 86 // CHECK-LABEL: define weak_odr void @_Z5test3IiEvP5Test2( 87 // CHECK: [[X:%.*]] = alloca i32, 88 // CHECK: @objc_msgSend 89 // CHECK: store i32 {{%.*}}, i32* [[X]], 90 // CHECK: load i32, i32* [[X]], 91 // CHECK: @objc_msgSend 92 // CHECK: @objc_msgSend 93 // CHECK: load i32, i32* [[X]], 94 // CHECK-NEXT: add nsw 95 // CHECK: @objc_msgSend 96 // CHECK-NEXT: ret void 97