diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp index 30c1045773c7..e16d169d19f5 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp @@ -1252,9 +1252,8 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( return; } #endif - - AggValueSlot Dest = EnsureSlot(CGF.getLoc(ExprToVisit->getSourceRange()), - ExprToVisit->getType()); + const mlir::Location loc = CGF.getLoc(ExprToVisit->getSourceRange()); + AggValueSlot Dest = EnsureSlot(loc, ExprToVisit->getType()); LValue DestLV = CGF.makeAddrLValue(Dest.getAddress(), ExprToVisit->getType()); @@ -1294,8 +1293,20 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( if (auto *CXXRD = dyn_cast(record)) { assert(NumInitElements >= CXXRD->getNumBases() && "missing initializer for base class"); - for ([[maybe_unused]] auto &Base : CXXRD->bases()) { - llvm_unreachable("NYI"); + for (auto &Base : CXXRD->bases()) { + assert(!Base.isVirtual() && "should not see vbases here"); + auto *BaseRD = Base.getType()->getAsCXXRecordDecl(); + Address address = CGF.getAddressOfDirectBaseInCompleteClass( + loc, Dest.getAddress(), CXXRD, BaseRD, + /*isBaseVirtual*/ false); + AggValueSlot aggSlot = AggValueSlot::forAddr( + address, Qualifiers(), AggValueSlot::IsDestructed, + AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, + CGF.getOverlapForBaseInit(CXXRD, BaseRD, false)); + CGF.emitAggExpr(InitExprs[curInitIndex++], aggSlot); + if (QualType::DestructionKind dtorKind = + Base.getType().isDestructedType()) + CGF.pushDestroyAndDeferDeactivation(dtorKind, address, Base.getType()); } } @@ -1329,8 +1340,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( emitInitializationToLValue(InitExprs[0], FieldLoc); } else { // Default-initialize to null. - emitNullInitializationToLValue(CGF.getLoc(ExprToVisit->getSourceRange()), - FieldLoc); + emitNullInitializationToLValue(loc, FieldLoc); } return; diff --git a/clang/test/CIR/CodeGen/agg-init-inherit.cpp b/clang/test/CIR/CodeGen/agg-init-inherit.cpp new file mode 100644 index 000000000000..a770ea73363f --- /dev/null +++ b/clang/test/CIR/CodeGen/agg-init-inherit.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM + +struct A1 { + A1(); +}; + +class B : public A1 {}; + +void f1() { + B v{}; +} + +// CIR: cir.func dso_local @_Z2f1v() +// CIR: %0 = cir.alloca !rec_B, !cir.ptr, ["v", init] +// CIR: %1 = cir.base_class_addr %0 : !cir.ptr nonnull [0] -> !cir.ptr +// CIR: cir.call @_ZN2A1C2Ev(%1) : (!cir.ptr) -> () +// CIR: cir.return +// LLVM: define dso_local void @_Z2f1v() +// LLVM: %1 = alloca %class.B, i64 1, align 1 +// LLVM: call void @_ZN2A1C2Ev(ptr %1) +// LLVM: ret void + +struct A2 { + A2(); +}; +class C : public A1, public A2 {}; + +void f2() { + C v{}; +} + +// CIR: cir.func dso_local @_Z2f2v() +// CIR: %0 = cir.alloca !rec_C, !cir.ptr, ["v", init] +// CIR: %1 = cir.base_class_addr %0 : !cir.ptr nonnull [0] -> !cir.ptr +// CIR: cir.call @_ZN2A1C2Ev(%1) : (!cir.ptr) -> () +// CIR: %2 = cir.base_class_addr %0 : !cir.ptr nonnull [0] -> !cir.ptr +// CIR: cir.call @_ZN2A2C2Ev(%2) : (!cir.ptr) -> () +// CIR: cir.return +// LLVM: define dso_local void @_Z2f2v() +// LLVM: %1 = alloca %class.C, i64 1, align 1 +// LLVM: call void @_ZN2A1C2Ev(ptr %1) +// LLVM: call void @_ZN2A2C2Ev(ptr %1) +// LLVM: ret void + +struct A3 { + A3(); + ~A3(); +}; +class D : public A3 {}; + +void f3() { + D v{}; +} + +// CIR: cir.func dso_local @_Z2f3v() +// CIR: %0 = cir.alloca !rec_D, !cir.ptr, ["v", init] +// CIR: %1 = cir.base_class_addr %0 : !cir.ptr nonnull [0] -> !cir.ptr +// CIR: cir.call @_ZN2A3C2Ev(%1) : (!cir.ptr) -> () +// CIR: cir.call @_ZN1DD1Ev(%0) : (!cir.ptr) -> () +// CIR: cir.return +// LLVM: define dso_local void @_Z2f3v() +// LLVM: %1 = alloca %class.D, i64 1, align 1 +// LLVM: call void @_ZN2A3C2Ev(ptr %1) +// LLVM: call void @_ZN1DD1Ev(ptr %1) +// LLVM: ret void