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
4struct 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
20void 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
32namespace 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.
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*);
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.
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*);
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