From 23c8f00ada1aaa59a84665cc726d57ab8e23d4e9 Mon Sep 17 00:00:00 2001 From: Amr Hesham Date: Sat, 1 Nov 2025 14:30:06 +0100 Subject: [PATCH 1/2] [CIR] Prepare a 'this' for CXXDefaultInitExprs --- clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 3 +++ clang/test/CIR/CodeGen/struct-init.cpp | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index 3d3030ca87e2a..94221ec24102b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -826,6 +826,9 @@ void AggExprEmitter::visitCXXParenListOrInitListExpr( } } + // Prepare a 'this' for CXXDefaultInitExprs. + CIRGenFunction::FieldConstructionScope fcScope(cgf, dest.getAddress()); + LValue destLV = cgf.makeAddrLValue(dest.getAddress(), e->getType()); if (record->isUnion()) { diff --git a/clang/test/CIR/CodeGen/struct-init.cpp b/clang/test/CIR/CodeGen/struct-init.cpp index 79886190616b9..05bb9fca6c54d 100644 --- a/clang/test/CIR/CodeGen/struct-init.cpp +++ b/clang/test/CIR/CodeGen/struct-init.cpp @@ -230,3 +230,28 @@ void init_expr(int a, int b, int c) { // OGCG: %[[C_PLUS_THREE:.*]] = add nsw i32 %[[C]], 3 // OGCG: store i32 %[[C_PLUS_THREE]], ptr %[[S_C]] // OGCG: ret void + +void cxx_default_init_with_struct_field() { + struct Parent { + struct { + int a; + } child; + }; + Parent p = Parent{}; +} + +// CIR: %[[P_ADDR:.*]] = cir.alloca !rec_Parent, !cir.ptr, ["p", init] +// CIR: %[[P_ELEM_0_PTR:.*]] = cir.get_member %[[P_ADDR]][0] {name = "child"} : !cir.ptr -> !cir.ptr +// CIR: %[[CHILD_ELEM_0_PTR:.*]] = cir.get_member %[[P_ELEM_0_PTR]][0] {name = "a"} : !cir.ptr -> !cir.ptr +// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i +// CIR: cir.store{{.*}} %3, %[[CHILD_ELEM_0_PTR]] : !s32i, !cir.ptr + +// TODO(cir): zero-initialize the padding + +// LLVM: %[[P_ADDR:.*]] = alloca %struct.Parent, i64 1, align 4 +// LLVM: %[[P_ELEM_0_PTR:.*]] = getelementptr %struct.Parent, ptr %[[P_ADDR]], i32 0, i32 0 +// LLVM: %[[CHILD_ELEM_0_PTR:.*]] = getelementptr %struct.anon.0, ptr %[[P_ELEM_0_PTR]], i32 0, i32 0 +// LLVM: store i32 0, ptr %[[CHILD_ELEM_0_PTR]], align 4 + +// OGCG: %[[P_ADDR:.*]] = alloca %struct.Parent, align 4 +// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[P_ADDR]], i8 0, i64 4, i1 false) From e09b218191fdd60a2e9913130285e4e573ec7350 Mon Sep 17 00:00:00 2001 From: Amr Hesham Date: Tue, 4 Nov 2025 19:45:00 +0100 Subject: [PATCH 2/2] Address code review comments --- clang/test/CIR/CodeGen/struct-init.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/clang/test/CIR/CodeGen/struct-init.cpp b/clang/test/CIR/CodeGen/struct-init.cpp index 05bb9fca6c54d..831e245530a96 100644 --- a/clang/test/CIR/CodeGen/struct-init.cpp +++ b/clang/test/CIR/CodeGen/struct-init.cpp @@ -233,25 +233,23 @@ void init_expr(int a, int b, int c) { void cxx_default_init_with_struct_field() { struct Parent { - struct { - int a; - } child; + int getA(); + int a = getA(); }; Parent p = Parent{}; } // CIR: %[[P_ADDR:.*]] = cir.alloca !rec_Parent, !cir.ptr, ["p", init] -// CIR: %[[P_ELEM_0_PTR:.*]] = cir.get_member %[[P_ADDR]][0] {name = "child"} : !cir.ptr -> !cir.ptr -// CIR: %[[CHILD_ELEM_0_PTR:.*]] = cir.get_member %[[P_ELEM_0_PTR]][0] {name = "a"} : !cir.ptr -> !cir.ptr -// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i -// CIR: cir.store{{.*}} %3, %[[CHILD_ELEM_0_PTR]] : !s32i, !cir.ptr - -// TODO(cir): zero-initialize the padding +// CIR: %[[P_ELEM_0_PTR:.*]] = cir.get_member %[[P_ADDR]][0] {name = "a"} : !cir.ptr -> !cir.ptr +// CIR: %[[METHOD_CALL:.*]] = cir.call @_ZZ34cxx_default_init_with_struct_fieldvEN6Parent4getAEv(%[[P_ADDR]]) : (!cir.ptr) -> !s32i +// CIR: cir.store{{.*}} %[[METHOD_CALL]], %[[P_ELEM_0_PTR]] : !s32i, !cir.ptr // LLVM: %[[P_ADDR:.*]] = alloca %struct.Parent, i64 1, align 4 // LLVM: %[[P_ELEM_0_PTR:.*]] = getelementptr %struct.Parent, ptr %[[P_ADDR]], i32 0, i32 0 -// LLVM: %[[CHILD_ELEM_0_PTR:.*]] = getelementptr %struct.anon.0, ptr %[[P_ELEM_0_PTR]], i32 0, i32 0 -// LLVM: store i32 0, ptr %[[CHILD_ELEM_0_PTR]], align 4 +// LLVM: %[[METHOD_CALL:.*]] = call i32 @_ZZ34cxx_default_init_with_struct_fieldvEN6Parent4getAEv(ptr %[[P_ADDR]]) +// LLVM: store i32 %[[METHOD_CALL]], ptr %[[P_ELEM_0_PTR]], align 4 // OGCG: %[[P_ADDR:.*]] = alloca %struct.Parent, align 4 -// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[P_ADDR]], i8 0, i64 4, i1 false) +// OGCG: %[[P_ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.Parent, ptr %[[P_ADDR]], i32 0, i32 0 +// OGCG: %[[METHOD_CALL:.*]] = call noundef i32 @_ZZ34cxx_default_init_with_struct_fieldvEN6Parent4getAEv(ptr {{.*}} %[[P_ADDR]]) +// OGCG: store i32 %[[METHOD_CALL]], ptr %[[P_ELEM_0_PTR]], align 4