Skip to content

Commit d0e81fc

Browse files
gitoleglanza
authored andcommitted
[CIR][CodeGen][Bugfix] Generate field index with respect to layout (#263)
There is a bug in the code generation: the field index for the `GetMemberOp` is taken from the `FieldDecl`, with no respect to the record layout. One of the manifestation of the bug is the wrong index generated for a field in a derived class that does not take into the account the instance of the base class (that has index 0). You can take a look at the example in `test/CIR/CodeGen/derived-to-base.cpp`, i.e. the current test is not the correct one ``` // CHECK-DAG: !ty_22C23A3ALayer22 = !cir.struct<class "C2::Layer" {!ty_22C13A3ALayer22, !cir.ptr<!ty_22C222> // CHECK-DAG: !ty_22C33A3ALayer22 = !cir.struct<struct "C3::Layer" {!ty_22C23A3ALayer22 // CHECK: cir.func @_ZN2C35Layer10InitializeEv // CHECK: cir.scope { // CHECK: %2 = cir.base_class_addr(%1 : cir.ptr <!ty_22C33A3ALayer22>) -> cir.ptr <!ty_22C23A3ALayer22> // CHECK: %3 = cir.get_member %2[0] {name = "m_C1"} : !cir.ptr<!ty_22C23A3ALayer22> -> !cir.ptr<!cir.ptr<!ty_22C222>> ``` As one can see, the result (of ptr type to `!ty_22C222` ) must have the index `1` in the corresponded struct `ty_22C23A3ALayer22`. Basically the same is done in the `clang/CodeGen/CGExpr.cpp`, so we don't invent something new here. Note, this fix doesn't affect anything related to the usage of `buildPreserveStructAccess` where the `field->getFieldIndex()` is used.
1 parent fbb4cd2 commit d0e81fc

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,9 @@ LValue CIRGenFunction::buildLValueForField(LValue base,
271271
if (!IsInPreservedAIRegion &&
272272
(!getDebugInfo() || !rec->hasAttr<BPFPreserveAccessIndexAttr>())) {
273273
llvm::StringRef fieldName = field->getName();
274-
unsigned fieldIndex = field->getFieldIndex();
274+
auto& layout = CGM.getTypes().getCIRGenRecordLayout(field->getParent());
275+
unsigned fieldIndex = layout.getCIRFieldNo(field);
276+
275277
if (CGM.LambdaFieldToName.count(field))
276278
fieldName = CGM.LambdaFieldToName[field];
277279
addr = buildAddrOfFieldStorage(*this, addr, field, fieldName, fieldIndex);

clang/test/CIR/CodeGen/derived-to-base.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ void C3::Layer::Initialize() {
8282

8383
// CHECK: cir.scope {
8484
// CHECK: %2 = cir.base_class_addr(%1 : cir.ptr <!ty_22C33A3ALayer22>) -> cir.ptr <!ty_22C23A3ALayer22>
85-
// CHECK: %3 = cir.get_member %2[0] {name = "m_C1"} : !cir.ptr<!ty_22C23A3ALayer22> -> !cir.ptr<!cir.ptr<!ty_22C222>>
85+
// CHECK: %3 = cir.get_member %2[1] {name = "m_C1"} : !cir.ptr<!ty_22C23A3ALayer22> -> !cir.ptr<!cir.ptr<!ty_22C222>>
8686
// CHECK: %4 = cir.load %3 : cir.ptr <!cir.ptr<!ty_22C222>>, !cir.ptr<!ty_22C222>
8787
// CHECK: %5 = cir.const(#cir.ptr<null> : !cir.ptr<!ty_22C222>) : !cir.ptr<!ty_22C222>
8888
// CHECK: %6 = cir.cmp(eq, %4, %5) : !cir.ptr<!ty_22C222>, !cir.bool

0 commit comments

Comments
 (0)