Mercurial > hg > CbC > CbC_llvm
comparison clang/test/CodeGenObjC/arc-rv-attr.m @ 252:1f2b6ac9f198 llvm-original
LLVM16-1
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Aug 2023 09:04:13 +0900 |
parents | c4bab56944e8 |
children |
comparison
equal
deleted
inserted
replaced
237:c80f45b162ad | 252:1f2b6ac9f198 |
---|---|
1 // RUN: %clang_cc1 -no-opaque-pointers -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK | 1 // RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK |
2 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK | 2 // RUN: %clang_cc1 -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK |
3 | 3 |
4 @class A; | 4 @class A; |
5 | 5 |
6 A *makeA(void); | 6 A *makeA(void); |
7 | 7 |
8 void test_assign(void) { | 8 void test_assign(void) { |
9 __unsafe_unretained id x; | 9 __unsafe_unretained id x; |
10 x = makeA(); | 10 x = makeA(); |
11 } | 11 } |
12 // CHECK-LABEL: define{{.*}} void @test_assign() | 12 // CHECK-LABEL: define{{.*}} void @test_assign() |
13 // CHECK: [[X:%.*]] = alloca i8* | 13 // CHECK: [[X:%.*]] = alloca ptr |
14 // CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] | 14 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] |
15 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 15 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
16 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* | 16 // CHECK-NEXT: store ptr [[T0]], ptr [[X]] |
17 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] | |
18 // CHECK-NEXT: bitcast | |
19 // CHECK-NEXT: lifetime.end | 17 // CHECK-NEXT: lifetime.end |
20 // CHECK-NEXT: ret void | 18 // CHECK-NEXT: ret void |
21 | 19 |
22 void test_assign_assign(void) { | 20 void test_assign_assign(void) { |
23 __unsafe_unretained id x, y; | 21 __unsafe_unretained id x, y; |
24 x = y = makeA(); | 22 x = y = makeA(); |
25 } | 23 } |
26 // CHECK-LABEL: define{{.*}} void @test_assign_assign() | 24 // CHECK-LABEL: define{{.*}} void @test_assign_assign() |
27 // CHECK: [[X:%.*]] = alloca i8* | 25 // CHECK: [[X:%.*]] = alloca ptr |
28 // CHECK: [[Y:%.*]] = alloca i8* | 26 // CHECK: [[Y:%.*]] = alloca ptr |
29 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] | 27 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] |
30 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 28 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
31 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* | 29 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]] |
32 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] | 30 // CHECK-NEXT: store ptr [[T0]], ptr [[X]] |
33 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] | |
34 // CHECK-NEXT: bitcast | |
35 // CHECK-NEXT: lifetime.end | 31 // CHECK-NEXT: lifetime.end |
36 // CHECK-NEXT: bitcast | |
37 // CHECK-NEXT: lifetime.end | 32 // CHECK-NEXT: lifetime.end |
38 // CHECK-NEXT: ret void | 33 // CHECK-NEXT: ret void |
39 | 34 |
40 void test_strong_assign_assign(void) { | 35 void test_strong_assign_assign(void) { |
41 __strong id x; | 36 __strong id x; |
42 __unsafe_unretained id y; | 37 __unsafe_unretained id y; |
43 x = y = makeA(); | 38 x = y = makeA(); |
44 } | 39 } |
45 // CHECK-LABEL: define{{.*}} void @test_strong_assign_assign() | 40 // CHECK-LABEL: define{{.*}} void @test_strong_assign_assign() |
46 // CHECK: [[X:%.*]] = alloca i8* | 41 // CHECK: [[X:%.*]] = alloca ptr |
47 // CHECK: [[Y:%.*]] = alloca i8* | 42 // CHECK: [[Y:%.*]] = alloca ptr |
48 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] | 43 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] |
49 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 44 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
50 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* | 45 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]] |
51 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] | 46 // CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]] |
52 // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] | 47 // CHECK-NEXT: store ptr [[T0]], ptr [[X]] |
53 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] | 48 // CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]] |
54 // CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]] | |
55 // CHECK-NEXT: bitcast | |
56 // CHECK-NEXT: lifetime.end | 49 // CHECK-NEXT: lifetime.end |
57 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] | 50 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] |
58 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) | 51 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) |
59 // CHECK-NEXT: bitcast | |
60 // CHECK-NEXT: lifetime.end | 52 // CHECK-NEXT: lifetime.end |
61 // CHECK-NEXT: ret void | 53 // CHECK-NEXT: ret void |
62 | 54 |
63 void test_assign_strong_assign(void) { | 55 void test_assign_strong_assign(void) { |
64 __unsafe_unretained id x; | 56 __unsafe_unretained id x; |
65 __strong id y; | 57 __strong id y; |
66 x = y = makeA(); | 58 x = y = makeA(); |
67 } | 59 } |
68 // CHECK-LABEL: define{{.*}} void @test_assign_strong_assign() | 60 // CHECK-LABEL: define{{.*}} void @test_assign_strong_assign() |
69 // CHECK: [[X:%.*]] = alloca i8* | 61 // CHECK: [[X:%.*]] = alloca ptr |
70 // CHECK: [[Y:%.*]] = alloca i8* | 62 // CHECK: [[Y:%.*]] = alloca ptr |
71 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] | 63 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] |
72 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 64 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
73 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* | 65 // CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[Y]] |
74 // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]] | 66 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]] |
75 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] | 67 // CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]] |
76 // CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]] | 68 // CHECK-NEXT: store ptr [[T0]], ptr [[X]] |
77 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] | 69 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]] |
78 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] | 70 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) |
79 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) | |
80 // CHECK-NEXT: bitcast | |
81 // CHECK-NEXT: lifetime.end | 71 // CHECK-NEXT: lifetime.end |
82 // CHECK-NEXT: bitcast | |
83 // CHECK-NEXT: lifetime.end | 72 // CHECK-NEXT: lifetime.end |
84 // CHECK-NEXT: ret void | 73 // CHECK-NEXT: ret void |
85 | 74 |
86 void test_init(void) { | 75 void test_init(void) { |
87 __unsafe_unretained id x = makeA(); | 76 __unsafe_unretained id x = makeA(); |
88 } | 77 } |
89 // CHECK-LABEL: define{{.*}} void @test_init() | 78 // CHECK-LABEL: define{{.*}} void @test_init() |
90 // CHECK: [[X:%.*]] = alloca i8* | 79 // CHECK: [[X:%.*]] = alloca ptr |
91 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] | 80 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] |
92 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 81 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
93 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* | 82 // CHECK-NEXT: store ptr [[T0]], ptr [[X]] |
94 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] | |
95 // CHECK-NEXT: bitcast | |
96 // CHECK-NEXT: lifetime.end | 83 // CHECK-NEXT: lifetime.end |
97 // CHECK-NEXT: ret void | 84 // CHECK-NEXT: ret void |
98 | 85 |
99 void test_init_assignment(void) { | 86 void test_init_assignment(void) { |
100 __unsafe_unretained id x; | 87 __unsafe_unretained id x; |
101 __unsafe_unretained id y = x = makeA(); | 88 __unsafe_unretained id y = x = makeA(); |
102 } | 89 } |
103 // CHECK-LABEL: define{{.*}} void @test_init_assignment() | 90 // CHECK-LABEL: define{{.*}} void @test_init_assignment() |
104 // CHECK: [[X:%.*]] = alloca i8* | 91 // CHECK: [[X:%.*]] = alloca ptr |
105 // CHECK: [[Y:%.*]] = alloca i8* | 92 // CHECK: [[Y:%.*]] = alloca ptr |
106 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] | 93 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] |
107 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 94 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
108 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* | 95 // CHECK-NEXT: store ptr [[T0]], ptr [[X]] |
109 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] | 96 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]] |
110 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] | |
111 // CHECK-NEXT: bitcast | |
112 // CHECK-NEXT: lifetime.end | 97 // CHECK-NEXT: lifetime.end |
113 // CHECK-NEXT: bitcast | |
114 // CHECK-NEXT: lifetime.end | 98 // CHECK-NEXT: lifetime.end |
115 // CHECK-NEXT: ret void | 99 // CHECK-NEXT: ret void |
116 | 100 |
117 void test_strong_init_assignment(void) { | 101 void test_strong_init_assignment(void) { |
118 __unsafe_unretained id x; | 102 __unsafe_unretained id x; |
119 __strong id y = x = makeA(); | 103 __strong id y = x = makeA(); |
120 } | 104 } |
121 // CHECK-LABEL: define{{.*}} void @test_strong_init_assignment() | 105 // CHECK-LABEL: define{{.*}} void @test_strong_init_assignment() |
122 // CHECK: [[X:%.*]] = alloca i8* | 106 // CHECK: [[X:%.*]] = alloca ptr |
123 // CHECK: [[Y:%.*]] = alloca i8* | 107 // CHECK: [[Y:%.*]] = alloca ptr |
124 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] | 108 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] |
125 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 109 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
126 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* | 110 // CHECK-NEXT: store ptr [[T0]], ptr [[X]] |
127 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] | 111 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]] |
128 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] | 112 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[Y]] |
129 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]] | 113 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) |
130 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) | |
131 // CHECK-NEXT: bitcast | |
132 // CHECK-NEXT: lifetime.end | 114 // CHECK-NEXT: lifetime.end |
133 // CHECK-NEXT: bitcast | |
134 // CHECK-NEXT: lifetime.end | 115 // CHECK-NEXT: lifetime.end |
135 // CHECK-NEXT: ret void | 116 // CHECK-NEXT: ret void |
136 | 117 |
137 void test_init_strong_assignment(void) { | 118 void test_init_strong_assignment(void) { |
138 __strong id x; | 119 __strong id x; |
139 __unsafe_unretained id y = x = makeA(); | 120 __unsafe_unretained id y = x = makeA(); |
140 } | 121 } |
141 // CHECK-LABEL: define{{.*}} void @test_init_strong_assignment() | 122 // CHECK-LABEL: define{{.*}} void @test_init_strong_assignment() |
142 // CHECK: [[X:%.*]] = alloca i8* | 123 // CHECK: [[X:%.*]] = alloca ptr |
143 // CHECK: [[Y:%.*]] = alloca i8* | 124 // CHECK: [[Y:%.*]] = alloca ptr |
144 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] | 125 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.retainAutoreleasedReturnValue) ] |
145 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 126 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
146 // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* | 127 // CHECK-NEXT: [[OLD:%.*]] = load ptr, ptr [[X]] |
147 // CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]] | 128 // CHECK-NEXT: store ptr [[T0]], ptr [[X]] |
148 // CHECK-NEXT: store i8* [[T1]], i8** [[X]] | 129 // CHECK-NEXT: call void @llvm.objc.release(ptr [[OLD]]) |
149 // CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]]) | 130 // CHECK-NEXT: store ptr [[T0]], ptr [[Y]] |
150 // CHECK-NEXT: store i8* [[T1]], i8** [[Y]] | |
151 // CHECK-NEXT: bitcast | |
152 // CHECK-NEXT: lifetime.end | 131 // CHECK-NEXT: lifetime.end |
153 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]] | 132 // CHECK-NEXT: [[T0:%.*]] = load ptr, ptr [[X]] |
154 // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) | 133 // CHECK-NEXT: call void @llvm.objc.release(ptr [[T0]]) |
155 // CHECK-NEXT: bitcast | |
156 // CHECK-NEXT: lifetime.end | 134 // CHECK-NEXT: lifetime.end |
157 // CHECK-NEXT: ret void | 135 // CHECK-NEXT: ret void |
158 | 136 |
159 void test_ignored(void) { | 137 void test_ignored(void) { |
160 makeA(); | 138 makeA(); |
161 } | 139 } |
162 // CHECK-LABEL: define{{.*}} void @test_ignored() | 140 // CHECK-LABEL: define{{.*}} void @test_ignored() |
163 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] | 141 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] |
164 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 142 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
165 // CHECK-NEXT: ret void | 143 // CHECK-NEXT: ret void |
166 | 144 |
167 void test_cast_to_void(void) { | 145 void test_cast_to_void(void) { |
168 (void) makeA(); | 146 (void) makeA(); |
169 } | 147 } |
170 // CHECK-LABEL: define{{.*}} void @test_cast_to_void() | 148 // CHECK-LABEL: define{{.*}} void @test_cast_to_void() |
171 // CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] | 149 // CHECK: [[T0:%.*]] = call ptr @makeA() [ "clang.arc.attachedcall"(ptr @llvm.objc.unsafeClaimAutoreleasedReturnValue) ] |
172 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) | 150 // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]]) |
173 // CHECK-NEXT: ret void | 151 // CHECK-NEXT: ret void |
174 | 152 |
175 // This is always at the end of the module. | 153 // This is always at the end of the module. |
176 | 154 |