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