https://github.com/adams381 created 
https://github.com/llvm/llvm-project/pull/188092

Add LLVM type converter entries for `DataMemberType` (→ `i64`) and `MethodType` 
(→ `{i64, i64}`) so that structs containing member pointers don't crash during 
CIR-to-LLVM lowering.

Also fix `isZeroInitializable` for `MemberPointerType`.  The old code 
unconditionally emitted `errorNYI`.  In the Itanium ABI, member function 
pointers are zero-initializable (null is `{0, 0}`), but member data pointers 
are not (null is `-1`).


>From 90cc52f68b5ec11038004393eca151276a994971 Mon Sep 17 00:00:00 2001
From: Adam Smith <[email protected]>
Date: Mon, 23 Mar 2026 10:49:45 -0700
Subject: [PATCH] [CIR][ABI] Add member pointer type lowering and fix
 isZeroInitializable

Implement LLVM type conversions for DataMemberType (to i64) and
MethodType (to {i64, i64}) so that structs containing member pointers
can be lowered to LLVM IR.

Fix isZeroInitializable for MemberPointerType: member function
pointers are zero-initializable (null = {0, 0}), but member data
pointers are not (null = -1 in Itanium ABI).

Made-with: Cursor
---
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp               | 9 ++++-----
 clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 8 ++++++++
 clang/test/CIR/CodeGen/nonzeroinit-struct.cpp       | 7 ++-----
 clang/test/CIR/CodeGen/pointer-to-data-member.cpp   | 6 ++++++
 4 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 2092964bac065..89004577e0570 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -652,11 +652,10 @@ bool CIRGenTypes::isZeroInitializable(clang::QualType t) {
   if (const auto *rd = t->getAsRecordDecl())
     return isZeroInitializable(rd);
 
-  if (t->getAs<MemberPointerType>()) {
-    cgm.errorNYI(SourceLocation(), "isZeroInitializable for MemberPointerType",
-                 t);
-    return false;
-  }
+  // Itanium ABI: member function pointers are zero-initializable
+  // (null = {0, 0}), but member data pointers are not (null = -1).
+  if (const auto *mpt = t->getAs<MemberPointerType>())
+    return mpt->isMemberFunctionPointer();
 
   return true;
 }
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 9fa0e720e1591..7e4d2d74ce713 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -3454,6 +3454,14 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter 
&converter,
   converter.addConversion([&](cir::VoidType type) -> mlir::Type {
     return mlir::LLVM::LLVMVoidType::get(type.getContext());
   });
+  converter.addConversion([&](cir::DataMemberType type) -> mlir::Type {
+    return mlir::IntegerType::get(type.getContext(), 64);
+  });
+  converter.addConversion([&](cir::MethodType type) -> mlir::Type {
+    auto i64 = mlir::IntegerType::get(type.getContext(), 64);
+    return mlir::LLVM::LLVMStructType::getLiteral(type.getContext(),
+                                                  {i64, i64});
+  });
 }
 
 static void buildCtorDtorList(
diff --git a/clang/test/CIR/CodeGen/nonzeroinit-struct.cpp 
b/clang/test/CIR/CodeGen/nonzeroinit-struct.cpp
index 871a028901947..d6dcc91004752 100644
--- a/clang/test/CIR/CodeGen/nonzeroinit-struct.cpp
+++ b/clang/test/CIR/CodeGen/nonzeroinit-struct.cpp
@@ -10,11 +10,8 @@ struct Trivial {
     decltype(&Other::x) ptr;
 };
 
-// This case has a trivial default constructor, but can't be zero-initialized.
+// This case has a trivial default constructor, but can't be zero-initialized
+// because it contains a data member pointer (null = -1 in Itanium ABI).
 Trivial t;
 
-// Since the case above isn't handled yet, we want a test that verifies that
-// we're failing for the right reason.
-
-// expected-error@*:* {{ClangIR code gen Not Yet Implemented: 
isZeroInitializable for MemberPointerType}}
 // expected-error@*:* {{ClangIR code gen Not Yet Implemented: 
tryEmitPrivateForVarInit: non-zero-initializable cxx record}}
diff --git a/clang/test/CIR/CodeGen/pointer-to-data-member.cpp 
b/clang/test/CIR/CodeGen/pointer-to-data-member.cpp
index 3d88b989d23cb..0251f33528b60 100644
--- a/clang/test/CIR/CodeGen/pointer-to-data-member.cpp
+++ b/clang/test/CIR/CodeGen/pointer-to-data-member.cpp
@@ -349,3 +349,9 @@ auto test_null_incomplete() -> int Incomplete::* {
 
 // OGCG: define {{.*}} i64 @_Z20test_null_incompletev()
 // OGCG:   ret i64 -1
+
+// Struct containing a member data pointer can be lowered.
+struct StructWithMDP { char *a; int Point::* b; };
+void take_struct_mdp(StructWithMDP s) { (void)s; }
+// LLVM: define {{.*}} void 
@_Z15take_struct_mdp13StructWithMDP(%struct.StructWithMDP %{{.*}})
+// OGCG: define {{.*}} void @_Z15take_struct_mdp13StructWithMDP(ptr %{{.*}}, 
i64 %{{.*}})

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

Reply via email to