[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGen / tbaa-class.cpp
blob0ac59085e634d0e8223239e448adfc3f0ac0e5d2
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
2 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH,OLD-PATH
3 // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -new-struct-path-tbaa -o - | FileCheck %s -check-prefixes=PATH,NEW-PATH
4 // Test TBAA metadata generated by front-end.
6 typedef unsigned char uint8_t;
7 typedef unsigned short uint16_t;
8 typedef unsigned int uint32_t;
9 typedef unsigned long long uint64_t;
10 class StructA
12 public:
13 uint16_t f16;
14 uint32_t f32;
15 uint16_t f16_2;
16 uint32_t f32_2;
18 class StructB
20 public:
21 uint16_t f16;
22 StructA a;
23 uint32_t f32;
25 class StructC
27 public:
28 uint16_t f16;
29 StructB b;
30 uint32_t f32;
32 class StructD
34 public:
35 uint16_t f16;
36 StructB b;
37 uint32_t f32;
38 uint8_t f8;
41 class StructS
43 public:
44 uint16_t f16;
45 uint32_t f32;
47 class StructS2 : public StructS
49 public:
50 uint16_t f16_2;
51 uint32_t f32_2;
54 class StructT {
55 public:
56 uint32_t f32_2;
57 void foo();
59 class StructM1 : public StructS, public StructT {
60 public:
61 uint16_t f16_2;
63 class StructDyn {
64 public:
65 uint32_t f32_2;
66 virtual void foo();
68 class StructM2 : public StructS, public StructDyn {
69 public:
70 uint16_t f16_2;
73 uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
74 // CHECK-LABEL: define{{.*}} i32 @_Z1g
75 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
76 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
77 // PATH-LABEL: define{{.*}} i32 @_Z1g
78 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
79 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]]
80 *s = 1;
81 A->f32 = 4;
82 return *s;
85 uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
86 // CHECK-LABEL: define{{.*}} i32 @_Z2g2
87 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
88 // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16:!.*]]
89 // PATH-LABEL: define{{.*}} i32 @_Z2g2
90 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
91 // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f16:!.*]]
92 *s = 1;
93 A->f16 = 4;
94 return *s;
97 uint32_t g3(StructA *A, StructB *B, uint64_t count) {
98 // CHECK-LABEL: define{{.*}} i32 @_Z2g3
99 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
100 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
101 // PATH-LABEL: define{{.*}} i32 @_Z2g3
102 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
103 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]]
104 A->f32 = 1;
105 B->a.f32 = 4;
106 return A->f32;
109 uint32_t g4(StructA *A, StructB *B, uint64_t count) {
110 // CHECK-LABEL: define{{.*}} i32 @_Z2g4
111 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
112 // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
113 // PATH-LABEL: define{{.*}} i32 @_Z2g4
114 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
115 // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f16:!.*]]
116 A->f32 = 1;
117 B->a.f16 = 4;
118 return A->f32;
121 uint32_t g5(StructA *A, StructB *B, uint64_t count) {
122 // CHECK-LABEL: define{{.*}} i32 @_Z2g5
123 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
124 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
125 // PATH-LABEL: define{{.*}} i32 @_Z2g5
126 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
127 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]]
128 A->f32 = 1;
129 B->f32 = 4;
130 return A->f32;
133 uint32_t g6(StructA *A, StructB *B, uint64_t count) {
134 // CHECK-LABEL: define{{.*}} i32 @_Z2g6
135 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
136 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
137 // PATH-LABEL: define{{.*}} i32 @_Z2g6
138 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
139 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]]
140 A->f32 = 1;
141 B->a.f32_2 = 4;
142 return A->f32;
145 uint32_t g7(StructA *A, StructS *S, uint64_t count) {
146 // CHECK-LABEL: define{{.*}} i32 @_Z2g7
147 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
148 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
149 // PATH-LABEL: define{{.*}} i32 @_Z2g7
150 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
151 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
152 A->f32 = 1;
153 S->f32 = 4;
154 return A->f32;
157 uint32_t g8(StructA *A, StructS *S, uint64_t count) {
158 // CHECK-LABEL: define{{.*}} i32 @_Z2g8
159 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
160 // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
161 // PATH-LABEL: define{{.*}} i32 @_Z2g8
162 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
163 // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f16:!.*]]
164 A->f32 = 1;
165 S->f16 = 4;
166 return A->f32;
169 uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
170 // CHECK-LABEL: define{{.*}} i32 @_Z2g9
171 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
172 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
173 // PATH-LABEL: define{{.*}} i32 @_Z2g9
174 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
175 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
176 S->f32 = 1;
177 S2->f32 = 4;
178 return S->f32;
181 uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
182 // CHECK-LABEL: define{{.*}} i32 @_Z3g10
183 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
184 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
185 // PATH-LABEL: define{{.*}} i32 @_Z3g10
186 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
187 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_S2_f32_2:!.*]]
188 S->f32 = 1;
189 S2->f32_2 = 4;
190 return S->f32;
193 uint32_t g11(StructC *C, StructD *D, uint64_t count) {
194 // CHECK-LABEL: define{{.*}} i32 @_Z3g11
195 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
196 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
197 // PATH-LABEL: define{{.*}} i32 @_Z3g11
198 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]]
199 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]]
200 C->b.a.f32 = 1;
201 D->b.a.f32 = 4;
202 return C->b.a.f32;
205 uint32_t g12(StructC *C, StructD *D, uint64_t count) {
206 // CHECK-LABEL: define{{.*}} i32 @_Z3g12
207 // CHECK: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
208 // CHECK: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
209 // TODO: differentiate the two accesses.
210 // PATH-LABEL: define{{.*}} i32 @_Z3g12
211 // PATH: store i32 1, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
212 // PATH: store i32 4, ptr %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
213 StructB *b1 = &(C->b);
214 StructB *b2 = &(D->b);
215 // b1, b2 have different context.
216 b1->a.f32 = 1;
217 b2->a.f32 = 4;
218 return b1->a.f32;
221 uint32_t g13(StructM1 *M, StructS *S) {
222 // CHECK-LABEL: define{{.*}} i32 @_Z3g13
223 // CHECK: store i16 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
224 // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
225 // PATH-LABEL: define{{.*}} i32 @_Z3g13
226 // PATH: store i16 1, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f16]]
227 // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_M1_f16_2:!.*]]
228 S->f16 = 1;
229 M->f16_2 = 4;
230 return S->f16;
233 uint32_t g14(StructM2 *M, StructS *S) {
234 // CHECK-LABEL: define{{.*}} i32 @_Z3g14
235 // CHECK: store i16 1, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
236 // CHECK: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_i16]]
237 // PATH-LABEL: define{{.*}} i32 @_Z3g14
238 // PATH: store i16 1, ptr %{{.*}}, align 4, !tbaa [[TAG_S_f16]]
239 // PATH: store i16 4, ptr %{{.*}}, align 4, !tbaa [[TAG_M2_f16_2:!.*]]
240 S->f16 = 1;
241 M->f16_2 = 4;
242 return S->f16;
245 // CHECK: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_cxx_tbaa:!.*]],
246 // CHECK: [[TAG_cxx_tbaa]] = !{!"Simple C++ TBAA"}
247 // CHECK: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0}
248 // CHECK: [[TYPE_i32]] = !{!"int", [[TYPE_char]],
249 // CHECK: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0}
250 // CHECK: [[TYPE_i16]] = !{!"short", [[TYPE_char]],
252 // OLD-PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", !
253 // OLD-PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0}
254 // OLD-PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]]
255 // OLD-PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4}
256 // OLD-PATH: [[TYPE_A]] = !{!"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12}
257 // OLD-PATH: [[TYPE_SHORT:!.*]] = !{!"short", [[TYPE_CHAR]]
258 // OLD-PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0}
259 // OLD-PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8}
260 // OLD-PATH: [[TYPE_B]] = !{!"_ZTS7StructB", [[TYPE_SHORT]], i64 0, [[TYPE_A]], i64 4, [[TYPE_INT]], i64 20}
261 // OLD-PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4}
262 // OLD-PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20}
263 // OLD-PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16}
264 // OLD-PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4}
265 // OLD-PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4}
266 // OLD-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0}
267 // OLD-PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12}
268 // OLD-PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_S]], i64 0, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12}
269 // OLD-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12}
270 // OLD-PATH: [[TYPE_C]] = !{!"_ZTS7StructC", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28}
271 // OLD-PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12}
272 // OLD-PATH: [[TYPE_D]] = !{!"_ZTS7StructD", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28, [[TYPE_CHAR]], i64 32}
273 // OLD-PATH: [[TAG_M1_f16_2]] = !{[[TYPE_M1:!.*]], [[TYPE_SHORT]], i64 12}
274 // OLD-PATH: [[TYPE_M1]] = !{!"_ZTS8StructM1", [[TYPE_S]], i64 0, [[TYPE_T:!.*]], i64 8, [[TYPE_SHORT]], i64 12}
275 // OLD_PATH: [[TYPE_T]] = !{!"_ZTS7StructT", [[TYPE_INT]], i64 0}
276 // OLD-PATH: [[TAG_M2_f16_2]] = !{[[TYPE_M2:!.*]], [[TYPE_SHORT]], i64 20}
277 // OLD-PATH: [[TYPE_M2]] = !{!"_ZTS8StructM2", [[TYPE_DYN:!.*]], i64 0, [[TYPE_S]], i64 12, [[TYPE_SHORT]], i64 20}
278 // OLD_PATH: [[TYPE_DYN]] = !{!"_ZTS9StructDyn", [[TYPE_INT]], i64 8}
280 // NEW-PATH: [[TYPE_CHAR:!.*]] = !{!{{.*}}, i64 1, !"omnipotent char"}
281 // NEW-PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0, i64 4}
282 // NEW-PATH: [[TYPE_INT]] = !{[[TYPE_CHAR]], i64 4, !"int"}
283 // NEW-PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4, i64 4}
284 // NEW-PATH: [[TYPE_A]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, i64 2, [[TYPE_INT]], i64 4, i64 4, [[TYPE_SHORT]], i64 8, i64 2, [[TYPE_INT]], i64 12, i64 4}
285 // NEW-PATH: [[TYPE_SHORT:!.*]] = !{[[TYPE_CHAR]], i64 2, !"short"}
286 // NEW-PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0, i64 2}
287 // NEW-PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8, i64 4}
288 // NEW-PATH: [[TYPE_B]] = !{[[TYPE_CHAR]], i64 24, !"_ZTS7StructB", [[TYPE_SHORT]], i64 0, i64 2, [[TYPE_A]], i64 4, i64 16, [[TYPE_INT]], i64 20, i64 4}
289 // NEW-PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4, i64 2}
290 // NEW-PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20, i64 4}
291 // NEW-PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16, i64 4}
292 // NEW-PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4, i64 4}
293 // NEW-PATH: [[TYPE_S]] = !{[[TYPE_CHAR]], i64 8, !"_ZTS7StructS", [[TYPE_SHORT]], i64 0, i64 2, [[TYPE_INT]], i64 4, i64 4}
294 // NEW-PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0, i64 2}
295 // NEW-PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12, i64 4}
296 // NEW-PATH: [[TYPE_S2]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS8StructS2", [[TYPE_S]], i64 0, i64 8, [[TYPE_SHORT]], i64 8, i64 2, [[TYPE_INT]], i64 12, i64 4}
297 // NEW-PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12, i64 4}
298 // NEW-PATH: [[TYPE_C]] = !{[[TYPE_CHAR]], i64 32, !"_ZTS7StructC", [[TYPE_SHORT]], i64 0, i64 2, [[TYPE_B]], i64 4, i64 24, [[TYPE_INT]], i64 28, i64 4}
299 // NEW-PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12, i64 4}
300 // NEW-PATH: [[TYPE_D]] = !{[[TYPE_CHAR]], i64 36, !"_ZTS7StructD", [[TYPE_SHORT]], i64 0, i64 2, [[TYPE_B]], i64 4, i64 24, [[TYPE_INT]], i64 28, i64 4, [[TYPE_CHAR]], i64 32, i64 1}
301 // NEW-PATH: [[TAG_M1_f16_2]] = !{[[TYPE_M1:!.*]], [[TYPE_SHORT]], i64 12, i64 2}
302 // NEW-PATH: [[TYPE_M1]] = !{[[TYPE_CHAR]], i64 16, !"_ZTS8StructM1", [[TYPE_S]], i64 0, i64 8, [[TYPE_T:!.*]], i64 8, i64 4, [[TYPE_SHORT]], i64 12, i64 2}
303 // NEW_PATH: [[TYPE_T]] = !{[[TYPE_CHAR]], i64 4, !"_ZTS7StructT", [[TYPE_INT]], i64 0, i64 4}
304 // NEW-PATH: [[TAG_M2_f16_2]] = !{[[TYPE_M2:!.*]], [[TYPE_SHORT]], i64 20, i64 2}
305 // NEW-PATH: [[TYPE_M2]] = !{[[TYPE_CHAR]], i64 24, !"_ZTS8StructM2", [[TYPE_DYN:!.*]], i64 0, i64 12, [[TYPE_S]], i64 12, i64 8, [[TYPE_SHORT]], i64 20, i64 2}
306 // NEW_PATH: [[TYPE_DYN]] = !{[[TYPE_CHAR]], i64 12, !"_ZTS9StructDyn", [[TYPE_INT]], i64 8, i64 4}