1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s
2f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-optzns %s -emit-llvm -o - | FileCheck %s -check-prefix=PATH
3f4a2713aSLionel Sambuc // Test TBAA metadata generated by front-end.
4f4a2713aSLionel Sambuc
5f4a2713aSLionel Sambuc typedef unsigned char uint8_t;
6f4a2713aSLionel Sambuc typedef unsigned short uint16_t;
7f4a2713aSLionel Sambuc typedef unsigned int uint32_t;
8f4a2713aSLionel Sambuc typedef unsigned long long uint64_t;
9f4a2713aSLionel Sambuc class StructA
10f4a2713aSLionel Sambuc {
11f4a2713aSLionel Sambuc public:
12f4a2713aSLionel Sambuc uint16_t f16;
13f4a2713aSLionel Sambuc uint32_t f32;
14f4a2713aSLionel Sambuc uint16_t f16_2;
15f4a2713aSLionel Sambuc uint32_t f32_2;
16f4a2713aSLionel Sambuc };
17f4a2713aSLionel Sambuc class StructB
18f4a2713aSLionel Sambuc {
19f4a2713aSLionel Sambuc public:
20f4a2713aSLionel Sambuc uint16_t f16;
21f4a2713aSLionel Sambuc StructA a;
22f4a2713aSLionel Sambuc uint32_t f32;
23f4a2713aSLionel Sambuc };
24f4a2713aSLionel Sambuc class StructC
25f4a2713aSLionel Sambuc {
26f4a2713aSLionel Sambuc public:
27f4a2713aSLionel Sambuc uint16_t f16;
28f4a2713aSLionel Sambuc StructB b;
29f4a2713aSLionel Sambuc uint32_t f32;
30f4a2713aSLionel Sambuc };
31f4a2713aSLionel Sambuc class StructD
32f4a2713aSLionel Sambuc {
33f4a2713aSLionel Sambuc public:
34f4a2713aSLionel Sambuc uint16_t f16;
35f4a2713aSLionel Sambuc StructB b;
36f4a2713aSLionel Sambuc uint32_t f32;
37f4a2713aSLionel Sambuc uint8_t f8;
38f4a2713aSLionel Sambuc };
39f4a2713aSLionel Sambuc
40f4a2713aSLionel Sambuc class StructS
41f4a2713aSLionel Sambuc {
42f4a2713aSLionel Sambuc public:
43f4a2713aSLionel Sambuc uint16_t f16;
44f4a2713aSLionel Sambuc uint32_t f32;
45f4a2713aSLionel Sambuc };
46f4a2713aSLionel Sambuc class StructS2 : public StructS
47f4a2713aSLionel Sambuc {
48f4a2713aSLionel Sambuc public:
49f4a2713aSLionel Sambuc uint16_t f16_2;
50f4a2713aSLionel Sambuc uint32_t f32_2;
51f4a2713aSLionel Sambuc };
52f4a2713aSLionel Sambuc
g(uint32_t * s,StructA * A,uint64_t count)53f4a2713aSLionel Sambuc uint32_t g(uint32_t *s, StructA *A, uint64_t count) {
54f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
55f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
56f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
57f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
58f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
59f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32:!.*]]
60f4a2713aSLionel Sambuc *s = 1;
61f4a2713aSLionel Sambuc A->f32 = 4;
62f4a2713aSLionel Sambuc return *s;
63f4a2713aSLionel Sambuc }
64f4a2713aSLionel Sambuc
g2(uint32_t * s,StructA * A,uint64_t count)65f4a2713aSLionel Sambuc uint32_t g2(uint32_t *s, StructA *A, uint64_t count) {
66f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
67f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
68f4a2713aSLionel Sambuc // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_i16:!.*]]
69f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
70f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
71f4a2713aSLionel Sambuc // PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_A_f16:!.*]]
72f4a2713aSLionel Sambuc *s = 1;
73f4a2713aSLionel Sambuc A->f16 = 4;
74f4a2713aSLionel Sambuc return *s;
75f4a2713aSLionel Sambuc }
76f4a2713aSLionel Sambuc
g3(StructA * A,StructB * B,uint64_t count)77f4a2713aSLionel Sambuc uint32_t g3(StructA *A, StructB *B, uint64_t count) {
78f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
79f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
80f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
81f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
82f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
83f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32:!.*]]
84f4a2713aSLionel Sambuc A->f32 = 1;
85f4a2713aSLionel Sambuc B->a.f32 = 4;
86f4a2713aSLionel Sambuc return A->f32;
87f4a2713aSLionel Sambuc }
88f4a2713aSLionel Sambuc
g4(StructA * A,StructB * B,uint64_t count)89f4a2713aSLionel Sambuc uint32_t g4(StructA *A, StructB *B, uint64_t count) {
90f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
91f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
92f4a2713aSLionel Sambuc // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_i16]]
93f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
94f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
95f4a2713aSLionel Sambuc // PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_B_a_f16:!.*]]
96f4a2713aSLionel Sambuc A->f32 = 1;
97f4a2713aSLionel Sambuc B->a.f16 = 4;
98f4a2713aSLionel Sambuc return A->f32;
99f4a2713aSLionel Sambuc }
100f4a2713aSLionel Sambuc
g5(StructA * A,StructB * B,uint64_t count)101f4a2713aSLionel Sambuc uint32_t g5(StructA *A, StructB *B, uint64_t count) {
102f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
103f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
104f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
105f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
106f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
107f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_f32:!.*]]
108f4a2713aSLionel Sambuc A->f32 = 1;
109f4a2713aSLionel Sambuc B->f32 = 4;
110f4a2713aSLionel Sambuc return A->f32;
111f4a2713aSLionel Sambuc }
112f4a2713aSLionel Sambuc
g6(StructA * A,StructB * B,uint64_t count)113f4a2713aSLionel Sambuc uint32_t g6(StructA *A, StructB *B, uint64_t count) {
114f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
115f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
116f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
117f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
118f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
119f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32_2:!.*]]
120f4a2713aSLionel Sambuc A->f32 = 1;
121f4a2713aSLionel Sambuc B->a.f32_2 = 4;
122f4a2713aSLionel Sambuc return A->f32;
123f4a2713aSLionel Sambuc }
124f4a2713aSLionel Sambuc
g7(StructA * A,StructS * S,uint64_t count)125f4a2713aSLionel Sambuc uint32_t g7(StructA *A, StructS *S, uint64_t count) {
126f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
127f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
128f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
129f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
130f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
131f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
132f4a2713aSLionel Sambuc A->f32 = 1;
133f4a2713aSLionel Sambuc S->f32 = 4;
134f4a2713aSLionel Sambuc return A->f32;
135f4a2713aSLionel Sambuc }
136f4a2713aSLionel Sambuc
g8(StructA * A,StructS * S,uint64_t count)137f4a2713aSLionel Sambuc uint32_t g8(StructA *A, StructS *S, uint64_t count) {
138f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
139f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
140f4a2713aSLionel Sambuc // CHECK: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_i16]]
141f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
142f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_A_f32]]
143f4a2713aSLionel Sambuc // PATH: store i16 4, i16* %{{.*}}, align 2, !tbaa [[TAG_S_f16:!.*]]
144f4a2713aSLionel Sambuc A->f32 = 1;
145f4a2713aSLionel Sambuc S->f16 = 4;
146f4a2713aSLionel Sambuc return A->f32;
147f4a2713aSLionel Sambuc }
148f4a2713aSLionel Sambuc
g9(StructS * S,StructS2 * S2,uint64_t count)149f4a2713aSLionel Sambuc uint32_t g9(StructS *S, StructS2 *S2, uint64_t count) {
150f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
151f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
152f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
153f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
154f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
155f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32:!.*]]
156f4a2713aSLionel Sambuc S->f32 = 1;
157f4a2713aSLionel Sambuc S2->f32 = 4;
158f4a2713aSLionel Sambuc return S->f32;
159f4a2713aSLionel Sambuc }
160f4a2713aSLionel Sambuc
g10(StructS * S,StructS2 * S2,uint64_t count)161f4a2713aSLionel Sambuc uint32_t g10(StructS *S, StructS2 *S2, uint64_t count) {
162f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
163f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
164f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
165f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
166f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_S_f32]]
167f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_S2_f32_2:!.*]]
168f4a2713aSLionel Sambuc S->f32 = 1;
169f4a2713aSLionel Sambuc S2->f32_2 = 4;
170f4a2713aSLionel Sambuc return S->f32;
171f4a2713aSLionel Sambuc }
172f4a2713aSLionel Sambuc
g11(StructC * C,StructD * D,uint64_t count)173f4a2713aSLionel Sambuc uint32_t g11(StructC *C, StructD *D, uint64_t count) {
174f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
175f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
176f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
177f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
178f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_C_b_a_f32:!.*]]
179f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_D_b_a_f32:!.*]]
180f4a2713aSLionel Sambuc C->b.a.f32 = 1;
181f4a2713aSLionel Sambuc D->b.a.f32 = 4;
182f4a2713aSLionel Sambuc return C->b.a.f32;
183f4a2713aSLionel Sambuc }
184f4a2713aSLionel Sambuc
g12(StructC * C,StructD * D,uint64_t count)185f4a2713aSLionel Sambuc uint32_t g12(StructC *C, StructD *D, uint64_t count) {
186f4a2713aSLionel Sambuc // CHECK: define i32 @{{.*}}(
187f4a2713aSLionel Sambuc // CHECK: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
188f4a2713aSLionel Sambuc // CHECK: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_i32]]
189f4a2713aSLionel Sambuc // TODO: differentiate the two accesses.
190f4a2713aSLionel Sambuc // PATH: define i32 @{{.*}}(
191f4a2713aSLionel Sambuc // PATH: store i32 1, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
192f4a2713aSLionel Sambuc // PATH: store i32 4, i32* %{{.*}}, align 4, !tbaa [[TAG_B_a_f32]]
193f4a2713aSLionel Sambuc StructB *b1 = &(C->b);
194f4a2713aSLionel Sambuc StructB *b2 = &(D->b);
195f4a2713aSLionel Sambuc // b1, b2 have different context.
196f4a2713aSLionel Sambuc b1->a.f32 = 1;
197f4a2713aSLionel Sambuc b2->a.f32 = 4;
198f4a2713aSLionel Sambuc return b1->a.f32;
199f4a2713aSLionel Sambuc }
200f4a2713aSLionel Sambuc
201*0a6a1f1dSLionel Sambuc // CHECK: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_cxx_tbaa:!.*]],
202*0a6a1f1dSLionel Sambuc // CHECK: [[TAG_cxx_tbaa]] = !{!"Simple C/C++ TBAA"}
203*0a6a1f1dSLionel Sambuc // CHECK: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0}
204*0a6a1f1dSLionel Sambuc // CHECK: [[TYPE_i32]] = !{!"int", [[TYPE_char]],
205*0a6a1f1dSLionel Sambuc // CHECK: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0}
206*0a6a1f1dSLionel Sambuc // CHECK: [[TYPE_i16]] = !{!"short", [[TYPE_char]],
207f4a2713aSLionel Sambuc
208*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_CHAR:!.*]] = !{!"omnipotent char", !
209*0a6a1f1dSLionel Sambuc // PATH: [[TAG_i32]] = !{[[TYPE_INT:!.*]], [[TYPE_INT]], i64 0}
210*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_INT]] = !{!"int", [[TYPE_CHAR]]
211*0a6a1f1dSLionel Sambuc // PATH: [[TAG_A_f32]] = !{[[TYPE_A:!.*]], [[TYPE_INT]], i64 4}
212*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_A]] = !{!"_ZTS7StructA", [[TYPE_SHORT:!.*]], i64 0, [[TYPE_INT]], i64 4, [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12}
213*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_SHORT:!.*]] = !{!"short", [[TYPE_CHAR]]
214*0a6a1f1dSLionel Sambuc // PATH: [[TAG_A_f16]] = !{[[TYPE_A]], [[TYPE_SHORT]], i64 0}
215*0a6a1f1dSLionel Sambuc // PATH: [[TAG_B_a_f32]] = !{[[TYPE_B:!.*]], [[TYPE_INT]], i64 8}
216*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_B]] = !{!"_ZTS7StructB", [[TYPE_SHORT]], i64 0, [[TYPE_A]], i64 4, [[TYPE_INT]], i64 20}
217*0a6a1f1dSLionel Sambuc // PATH: [[TAG_B_a_f16]] = !{[[TYPE_B]], [[TYPE_SHORT]], i64 4}
218*0a6a1f1dSLionel Sambuc // PATH: [[TAG_B_f32]] = !{[[TYPE_B]], [[TYPE_INT]], i64 20}
219*0a6a1f1dSLionel Sambuc // PATH: [[TAG_B_a_f32_2]] = !{[[TYPE_B]], [[TYPE_INT]], i64 16}
220*0a6a1f1dSLionel Sambuc // PATH: [[TAG_S_f32]] = !{[[TYPE_S:!.*]], [[TYPE_INT]], i64 4}
221*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_S]] = !{!"_ZTS7StructS", [[TYPE_SHORT]], i64 0, [[TYPE_INT]], i64 4}
222*0a6a1f1dSLionel Sambuc // PATH: [[TAG_S_f16]] = !{[[TYPE_S]], [[TYPE_SHORT]], i64 0}
223*0a6a1f1dSLionel Sambuc // PATH: [[TAG_S2_f32_2]] = !{[[TYPE_S2:!.*]], [[TYPE_INT]], i64 12}
224*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_S2]] = !{!"_ZTS8StructS2", [[TYPE_SHORT]], i64 8, [[TYPE_INT]], i64 12}
225*0a6a1f1dSLionel Sambuc // PATH: [[TAG_C_b_a_f32]] = !{[[TYPE_C:!.*]], [[TYPE_INT]], i64 12}
226*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_C]] = !{!"_ZTS7StructC", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28}
227*0a6a1f1dSLionel Sambuc // PATH: [[TAG_D_b_a_f32]] = !{[[TYPE_D:!.*]], [[TYPE_INT]], i64 12}
228*0a6a1f1dSLionel Sambuc // PATH: [[TYPE_D]] = !{!"_ZTS7StructD", [[TYPE_SHORT]], i64 0, [[TYPE_B]], i64 4, [[TYPE_INT]], i64 28, [[TYPE_CHAR]], i64 32}
229