1 | // RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -emit-llvm -o - | FileCheck %s -check-prefixes=CHECK,OLD-PATH |
2 | // RUN: %clang_cc1 -triple x86_64-linux-gnu -O1 %s -emit-llvm -new-struct-path-tbaa -o - | FileCheck %s -check-prefixes=CHECK,NEW-PATH |
3 | // |
4 | // Test generating of TBAA metadata for accesses to members of base classes. |
5 | |
6 | struct A { |
7 | int x, y, z; |
8 | }; |
9 | |
10 | struct B : A { |
11 | int i; |
12 | }; |
13 | |
14 | struct C { |
15 | int i; |
16 | B b; |
17 | int j; |
18 | }; |
19 | |
20 | int f1(B *b) { |
21 | // CHECK-LABEL: _Z2f1P1B |
22 | // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y:!.*]] |
23 | return b->y; |
24 | } |
25 | |
26 | int f2(C *c) { |
27 | // CHECK-LABEL: _Z2f2P1C |
28 | // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] |
29 | return (&(c->b))->y; |
30 | } |
31 | |
32 | struct D : virtual A |
33 | {}; |
34 | |
35 | struct E { |
36 | D d; |
37 | }; |
38 | |
39 | int f3(D *d) { |
40 | // CHECK-LABEL: _Z2f3P1D |
41 | // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] |
42 | return d->y; |
43 | } |
44 | |
45 | int f4(E *e) { |
46 | // CHECK-LABEL: _Z2f4P1E |
47 | // CHECK: load i32, {{.*}}, !tbaa [[TAG_A_y]] |
48 | return (&(e->d))->y; |
49 | } |
50 | |
51 | // OLD-PATH-DAG: [[TYPE_char:!.*]] = !{!"omnipotent char", {{.*}}, i64 0} |
52 | // OLD-PATH-DAG: [[TYPE_int:!.*]] = !{!"int", [[TYPE_char]], i64 0} |
53 | // OLD-PATH-DAG: [[TYPE_A:!.*]] = !{!"_ZTS1A", [[TYPE_int]], i64 0, [[TYPE_int]], i64 4, [[TYPE_int]], i64 8} |
54 | // OLD-PATH-DAG: [[TAG_A_y]] = !{[[TYPE_A]], [[TYPE_int]], i64 4} |
55 | // NEW-PATH-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} |
56 | // NEW-PATH-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"} |
57 | // NEW-PATH-DAG: [[TYPE_A:!.*]] = !{[[TYPE_char]], i64 12, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4, [[TYPE_int]], i64 4, i64 4, [[TYPE_int]], i64 8, i64 4} |
58 | // NEW-PATH-DAG: [[TAG_A_y]] = !{[[TYPE_A]], [[TYPE_int]], i64 4, i64 4} |
59 | |