llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: None (adams381)
<details>
<summary>Changes</summary>
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`).
---
Full diff: https://github.com/llvm/llvm-project/pull/188092.diff
4 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+4-5)
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+8)
- (modified) clang/test/CIR/CodeGen/nonzeroinit-struct.cpp (+2-5)
- (modified) clang/test/CIR/CodeGen/pointer-to-data-member.cpp (+6)
``````````diff
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 %{{.*}})
``````````
</details>
https://github.com/llvm/llvm-project/pull/188092
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits