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