https://github.com/erichkeane created 
https://github.com/llvm/llvm-project/pull/200305

For the purposes of zeroing out a type, we need to make sure that we handle 
vptrs.  While this seems like it is the wrong thing to do, we end up 
immediately initializing the vtable correctly in the constructor prologue, so 
this just ensures we do a memset/etc right before then.

Note that the original version of this function operates on a CXXRecordDecl, so 
skips this type, which we cannot do, since later logic determines whether we 
can/should zero-init this based on whether there is zero-attrs in the zero init.

>From 5f3ace1384dbdc43b0e6cf67109735bf0be6f54c Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Thu, 28 May 2026 16:55:33 -0700
Subject: [PATCH] [CIR] Handle vptr zero-init-

For the purposes of zeroing out a type, we need to make sure that we
handle vptrs.  While this seems like it is the wrong thing to do, we end
up immediately initializing the vtable correctly in the constructor
prologue, so this just ensures we do a memset/etc right before then.

Note that the original version of this function operates on a
CXXRecordDecl, so skips this type, which we cannot do, since later logic
determines whether we can/should zero-init this based on whether there
is zero-attrs in the zero init.
---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      |  3 ++
 clang/test/CIR/CodeGen/ctor-null-init.cpp     | 37 +++++++++++++++++++
 2 files changed, 40 insertions(+)

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index f5222accff154..f7616045fae96 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -127,9 +127,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
       return getNullDataMemberAttr(dataMemberTy);
     if (auto methodTy = mlir::dyn_cast<cir::MethodType>(ty))
       return getNullMethodAttr(methodTy);
+    if (auto vptrTy = mlir::dyn_cast<cir::VPtrType>(ty))
+      return cir::ZeroAttr::get(vptrTy);
     if (mlir::isa<cir::BoolType>(ty)) {
       return getFalseAttr();
     }
+
     llvm_unreachable("Zero initializer for given type is NYI");
   }
 
diff --git a/clang/test/CIR/CodeGen/ctor-null-init.cpp 
b/clang/test/CIR/CodeGen/ctor-null-init.cpp
index 6f31a46305ae8..6f99cfa084a55 100644
--- a/clang/test/CIR/CodeGen/ctor-null-init.cpp
+++ b/clang/test/CIR/CodeGen/ctor-null-init.cpp
@@ -89,3 +89,40 @@ void test_base_chain_null_init() {
 // OGCG:   %[[TMP:.*]] = alloca %struct.G
 // OGCG:   %[[BASE:.*]] = getelementptr inbounds i8, ptr %[[TMP]], i64 0
 // OGCG:   call void @llvm.memset.p0.i64(ptr{{.*}} %[[BASE]], i8 0, i64 4, i1 
false)
+
+struct VBase {
+  virtual ~VBase();
+};
+
+struct VDerived : VBase {
+  VDerived();
+};
+VDerived::VDerived() : VBase() {}
+
+// OGCG-LABEL: define {{.*}}@_ZN8VDerivedC2Ev
+// OGCG: %[[ADDR:.*]] = getelementptr inbounds i8, ptr %[[THIS:.*]],
+// OGCG: call void @llvm.memset.p0.i64(ptr align 8 %[[ADDR]], i8 0, i64 8, i1 
false)
+// OGCG: call void @_ZN5VBaseC2Ev(ptr noundef nonnull align 8 
dereferenceable(8) %[[THIS]])
+// OGCG: store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr 
@_ZTV8VDerived, i32 0, i32 0, i32 2), ptr %[[THIS]], align 8
+
+// CIR-LABEL: cir.func {{.*}}@_ZN5VBaseC2Ev
+// CIR: cir.vtable.address_point(@_ZTV5VBase
+// CIR: cir.vtable.get_vptr
+
+// LLVM-LABEL: define {{.*}}@_ZN5VBaseC2Ev
+// LLVM: store ptr getelementptr inbounds nuw (i8, ptr @_ZTV5VBase, i64 16), 
ptr %
+// OGCG-LABEL: define {{.*}}@_ZN5VBaseC2Ev
+// OGCG: store ptr getelementptr inbounds inrange(-16, 16) ({ [4 x ptr] }, ptr 
@_ZTV5VBase, i32 0, i32 0, i32 2), ptr %
+
+// CIR-LABEL: cir.func {{.*}}@_ZN8VDerivedC2Ev
+// CIR: %[[BASE:.*]] = cir.base_class_addr {{.*}} : !cir.ptr<!rec_VDerived> 
nonnull [0] -> !cir.ptr<!rec_VBase>
+// CIR: %[[ZERO:.*]] = cir.const #cir.const_record<{#cir.zero : !cir.vptr}> : 
!rec_VBase 
+// CIR: cir.store align(8) %[[ZERO]], %[[BASE]] : !rec_VBase, 
!cir.ptr<!rec_VBase>
+// CIR: cir.call @_ZN5VBaseC2Ev(%[[BASE]])
+// CIR: cir.vtable.address_point(@_ZTV8VDerived
+// CIR:  %5 = cir.vtable.get_vptr
+
+// LLVM-LABEL: define {{.*}}@_ZN8VDerivedC2Ev
+// LLVM: store %struct.VBase zeroinitializer, ptr %[[ADDR:.*]], align 8
+// LLVM: call void @_ZN5VBaseC2Ev(ptr {{.*}}%[[ADDR]])
+// LLVM: store ptr getelementptr inbounds nuw (i8, ptr @_ZTV8VDerived, i64 
16), ptr %[[ADDR]]

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to