Skip to content

Commit 57493e2

Browse files
author
Ivan A. Kosarev
committed
[CodeGen] Represent array members in new-format TBAA type descriptors
Now that in the new TBAA format we allow access types to be of any object types, including aggregate ones, it becomes critical to specify types of all sub-objects such aggregates comprise as their members. In order to meet this requirement, this patch enables generation of field descriptors for members of array types. Differential Revision: https://reviews.llvm.org/D41399 llvm-svn: 321352
1 parent d50b847 commit 57493e2

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

clang/lib/CodeGen/CodeGenTBAA.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
161161
if (Ty->isPointerType() || Ty->isReferenceType())
162162
return createScalarTypeNode("any pointer", getChar(), Size);
163163

164+
// Accesses to arrays are accesses to objects of their element types.
165+
if (CodeGenOpts.NewStructPathTBAA && Ty->isArrayType())
166+
return getTypeInfo(cast<ArrayType>(Ty)->getElementType());
167+
164168
// Enum types are distinct types. In C++ they have "underlying types",
165169
// however they aren't related for TBAA.
166170
if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) {

clang/test/CodeGen/tbaa-array.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,52 @@
11
// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
22
// RUN: -emit-llvm -o - | FileCheck %s
3+
// RUN: %clang_cc1 -triple x86_64-linux -O1 -disable-llvm-passes %s \
4+
// RUN: -new-struct-path-tbaa -emit-llvm -o - | \
5+
// RUN: FileCheck -check-prefix=CHECK-NEW %s
36
//
47
// Check that we generate correct TBAA information for accesses to array
58
// elements.
69

710
struct A { int i; };
811
struct B { A a[1]; };
12+
struct C { int i; int x[3]; };
913

1014
int foo(B *b) {
1115
// CHECK-LABEL: _Z3fooP1B
1216
// CHECK: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]]
17+
// CHECK-NEW-LABEL: _Z3fooP1B
18+
// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_A_i:!.*]]
1319
return b->a->i;
1420
}
1521

22+
// Check that members of array types are represented correctly.
23+
int bar(C *c) {
24+
// CHECK-NEW-LABEL: _Z3barP1C
25+
// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_C_i:!.*]]
26+
return c->i;
27+
}
28+
29+
int bar2(C *c) {
30+
// CHECK-NEW-LABEL: _Z4bar2P1C
31+
// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
32+
return c->x[2];
33+
}
34+
35+
int bar3(C *c, int j) {
36+
// CHECK-NEW-LABEL: _Z4bar3P1Ci
37+
// CHECK-NEW: load i32, {{.*}}, !tbaa [[TAG_int:!.*]]
38+
return c->x[j];
39+
}
40+
1641
// CHECK-DAG: [[TAG_A_i]] = !{[[TYPE_A:!.*]], [[TYPE_int:!.*]], i64 0}
1742
// CHECK-DAG: [[TYPE_A]] = !{!"_ZTS1A", !{{.*}}, i64 0}
1843
// CHECK-DAG: [[TYPE_int]] = !{!"int", !{{.*}}, i64 0}
44+
45+
// CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"}
46+
// CHECK-NEW-DAG: [[TYPE_int:!.*]] = !{[[TYPE_char]], i64 4, !"int"}
47+
// CHECK-NEW-DAG: [[TAG_int]] = !{[[TYPE_int]], [[TYPE_int]], i64 0, i64 4}
48+
// CHECK-NEW-DAG: [[TYPE_pointer:!.*]] = !{[[TYPE_char]], i64 8, !"any pointer"}
49+
// CHECK-NEW-DAG: [[TYPE_A:!.*]] = !{[[TYPE_char]], i64 4, !"_ZTS1A", [[TYPE_int]], i64 0, i64 4}
50+
// CHECK-NEW-DAG: [[TAG_A_i]] = !{[[TYPE_A]], [[TYPE_int]], i64 0, i64 4}
51+
// CHECK-NEW-DAG: [[TYPE_C:!.*]] = !{[[TYPE_char]], i64 16, !"_ZTS1C", [[TYPE_int]], i64 0, i64 4, [[TYPE_int]], i64 4, i64 12}
52+
// CHECK-NEW-DAG: [[TAG_C_i]] = !{[[TYPE_C:!.*]], [[TYPE_int:!.*]], i64 0, i64 4}

0 commit comments

Comments
 (0)