blob: 2bd21c31b4f488ff329dd0335e4cd40e2e72001b [file] [log] [blame]
Stephen Hines176edba2014-12-01 14:53:08 -08001// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s
John McCallf85e1932011-06-15 23:02:42 +00002
Douglas Gregord7b23162011-06-22 16:12:01 +00003@interface A
4@end
5
John McCallf85e1932011-06-15 23:02:42 +00006id getObject();
7void callee();
8
9// Lifetime extension for binding a reference to an rvalue
Stephen Lin93ab6bf2013-08-15 06:47:53 +000010// CHECK-LABEL: define void @_Z5test0v()
John McCallf85e1932011-06-15 23:02:42 +000011void test0() {
12 // CHECK: call i8* @_Z9getObjectv
Benjamin Kramer3ba02522012-09-18 20:59:03 +000013 // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
John McCallf85e1932011-06-15 23:02:42 +000014 const __strong id &ref1 = getObject();
15 // CHECK: call void @_Z6calleev
16 callee();
17 // CHECK: call i8* @_Z9getObjectv
18 // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
19 // CHECK-NEXT: call i8* @objc_autorelease
20 const __autoreleasing id &ref2 = getObject();
21 // CHECK: call void @_Z6calleev
22 callee();
23 // CHECK: call void @objc_release
24 // CHECK-NEXT: ret
25}
26
27// No lifetime extension when we're binding a reference to an lvalue.
Stephen Lin93ab6bf2013-08-15 06:47:53 +000028// CHECK-LABEL: define void @_Z5test1RU8__strongP11objc_objectRU6__weakS0_
John McCallf85e1932011-06-15 23:02:42 +000029void test1(__strong id &x, __weak id &y) {
30 // CHECK-NOT: release
31 const __strong id &ref1 = x;
32 const __autoreleasing id &ref2 = x;
33 const __weak id &ref3 = y;
34 // CHECK: ret void
35}
36
37typedef __strong id strong_id;
38
39//CHECK: define void @_Z5test3v
40void test3() {
41 // CHECK: call i8* @objc_initWeak
42 // CHECK-NEXT: store i8**
43 const __weak id &ref = strong_id();
44 // CHECK-NEXT: call void @_Z6calleev()
45 callee();
46 // CHECK-NEXT: call void @objc_destroyWeak
47 // CHECK-NEXT: ret void
48}
49
Stephen Lin93ab6bf2013-08-15 06:47:53 +000050// CHECK-LABEL: define void @_Z5test4RU8__strongP11objc_object
Douglas Gregord7b23162011-06-22 16:12:01 +000051void test4(__strong id &x) {
52 // CHECK: call i8* @objc_retain
53 __strong A* const &ar = x;
54 // CHECK: store i32 17, i32*
55 int i = 17;
56 // CHECK: call void @objc_release(
57 // CHECK: ret void
58}
59
60void sink(__strong A* &&);
61
Stephen Lin93ab6bf2013-08-15 06:47:53 +000062// CHECK-LABEL: define void @_Z5test5RU8__strongP11objc_object
Douglas Gregord7b23162011-06-22 16:12:01 +000063void test5(__strong id &x) {
John McCallcec52f02011-08-26 21:08:13 +000064 // CHECK: [[REFTMP:%.*]] = alloca {{%.*}}*, align 8
65 // CHECK: [[OBJ_ID:%.*]] = call i8* @objc_retain(
66 // CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]*
Douglas Gregord7b23162011-06-22 16:12:01 +000067 // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]]
68 // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A
69 sink(x);
Pirama Arumuga Nainar3ea9e332015-04-08 08:57:32 -070070 // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]*, [[A]]** [[REFTMP]]
Douglas Gregord7b23162011-06-22 16:12:01 +000071 // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8*
72 // CHECK-NEXT: call void @objc_release
73 // CHECK-NEXT: store i32 17, i32
74 int i = 17;
75 // CHECK-NEXT: ret void
76}
77
Stephen Lin93ab6bf2013-08-15 06:47:53 +000078// CHECK-LABEL: define internal void @__cxx_global_var_init(
John McCallf85e1932011-06-15 23:02:42 +000079// CHECK: call i8* @_Z9getObjectv
80// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
81const __strong id &global_ref = getObject();
82
83// Note: we intentionally don't release the object.
84