blob: db7f5a62151a9d4c314900a9ce9ae3dabe5453d5 [file] [log] [blame]
John McCall260611a2012-06-20 06:18:46 +00001// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - | FileCheck %s
Fariborz Jahanian68af13f2011-03-30 16:11:20 +00002// rdar://9208606
3
John McCall6c11f0b2011-09-13 06:00:03 +00004struct MyStruct {
5 int x;
6 int y;
7 int z;
Fariborz Jahanian68af13f2011-03-30 16:11:20 +00008};
9
John McCall6c11f0b2011-09-13 06:00:03 +000010@interface MyClass {
11 MyStruct _foo;
Fariborz Jahanian68af13f2011-03-30 16:11:20 +000012}
13
14@property (assign, readwrite) const MyStruct& foo;
15
16- (const MyStruct&) foo;
17- (void) setFoo:(const MyStruct&)inFoo;
18@end
19
John McCall6c11f0b2011-09-13 06:00:03 +000020void test0() {
21 MyClass* myClass;
22 MyStruct myStruct;
Fariborz Jahanian68af13f2011-03-30 16:11:20 +000023
John McCall6c11f0b2011-09-13 06:00:03 +000024 myClass.foo = myStruct;
Fariborz Jahanian68af13f2011-03-30 16:11:20 +000025
John McCall6c11f0b2011-09-13 06:00:03 +000026 const MyStruct& currentMyStruct = myClass.foo;
Fariborz Jahanian68af13f2011-03-30 16:11:20 +000027}
28
Stephen Hines176edba2014-12-01 14:53:08 -080029// CHECK: [[C:%.*]] = call dereferenceable({{[0-9]+}}) %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
Fariborz Jahanian68af13f2011-03-30 16:11:20 +000030// CHECK: store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]]
John McCall6c11f0b2011-09-13 06:00:03 +000031
32namespace test1 {
33 struct A { A(); A(const A&); A&operator=(const A&); ~A(); };
34}
35@interface Test1 {
36 test1::A ivar;
37}
Fariborz Jahaniancd93b962012-01-06 22:33:54 +000038@property (nonatomic) const test1::A &prop1;
John McCall6c11f0b2011-09-13 06:00:03 +000039@end
40@implementation Test1
41@synthesize prop1 = ivar;
42@end
Stephen Hines176edba2014-12-01 14:53:08 -080043// CHECK: define internal dereferenceable({{[0-9]+}}) [[A:%.*]]* @"\01-[Test1 prop1]"(
John McCall6c11f0b2011-09-13 06:00:03 +000044// CHECK: [[SELF:%.*]] = alloca [[TEST1:%.*]]*, align 8
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070045// CHECK: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** [[SELF]]
John McCall6c11f0b2011-09-13 06:00:03 +000046// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070047// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 0
John McCall6c11f0b2011-09-13 06:00:03 +000048// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
49// CHECK-NEXT: ret [[A]]* [[T3]]
50
51// CHECK: define internal void @"\01-[Test1 setProp1:]"(
Stephen Hines176edba2014-12-01 14:53:08 -080052// CHECK: call dereferenceable({{[0-9]+}}) [[A]]* @_ZN5test11AaSERKS0_(
John McCall6c11f0b2011-09-13 06:00:03 +000053// CHECK-NEXT: ret void
54
John McCall01e19be2011-11-30 04:42:31 +000055// rdar://problem/10497174
56@interface Test2
57@property int prop;
58@end
59
60// The fact that these are all non-dependent is critical.
61template <class T> void test2(Test2 *a) {
62 int x = a.prop;
63 a.prop = x;
64 a.prop += x;
65}
66template void test2<int>(Test2*);
Stephen Lin93ab6bf2013-08-15 06:47:53 +000067// CHECK-LABEL: define weak_odr void @_Z5test2IiEvP5Test2(
John McCall01e19be2011-11-30 04:42:31 +000068// CHECK: [[X:%.*]] = alloca i32,
69// CHECK: @objc_msgSend
70// CHECK: store i32 {{%.*}}, i32* [[X]],
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070071// CHECK: load i32, i32* [[X]],
John McCall01e19be2011-11-30 04:42:31 +000072// CHECK: @objc_msgSend
73// CHECK: @objc_msgSend
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070074// CHECK: load i32, i32* [[X]],
John McCall01e19be2011-11-30 04:42:31 +000075// CHECK-NEXT: add nsw
76// CHECK: @objc_msgSend
77// CHECK-NEXT: ret void
78
79// Same as the previous test, but instantiation-dependent.
80template <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}
85template void test3<int>(Test2*);
Stephen Lin93ab6bf2013-08-15 06:47:53 +000086// CHECK-LABEL: define weak_odr void @_Z5test3IiEvP5Test2(
John McCall01e19be2011-11-30 04:42:31 +000087// CHECK: [[X:%.*]] = alloca i32,
88// CHECK: @objc_msgSend
89// CHECK: store i32 {{%.*}}, i32* [[X]],
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070090// CHECK: load i32, i32* [[X]],
John McCall01e19be2011-11-30 04:42:31 +000091// CHECK: @objc_msgSend
92// CHECK: @objc_msgSend
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070093// CHECK: load i32, i32* [[X]],
John McCall01e19be2011-11-30 04:42:31 +000094// CHECK-NEXT: add nsw
95// CHECK: @objc_msgSend
96// CHECK-NEXT: ret void