diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h index b82b744852f7..743348554a9f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h +++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h @@ -273,6 +273,11 @@ class CIRGenCXXABI { /// (in the C++ sense) with an LLVM zeroinitializer. virtual bool isZeroInitializable(const MemberPointerType *MPT); + /// Return whether or not a member pointers type is convertible to an IR type. + virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const { + return true; + } + /// Gets the offsets of all the virtual base pointers in a given class. virtual std::vector getVBPtrOffsets(const CXXRecordDecl *RD); diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 8fba1ec12718..0a50875fff09 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -313,7 +313,8 @@ mlir::Type CIRGenTypes::convertFunctionTypeInternal(QualType QFT) { bool CIRGenTypes::isFuncParamTypeConvertible(clang::QualType Ty) { // Some ABIs cannot have their member pointers represented in LLVM IR unless // certain circumstances have been reached. - assert(!Ty->getAs() && "NYI"); + if (const auto *mpt = Ty->getAs()) + return getCXXABI().isMemberPointerConvertible(mpt); // If this isn't a tagged type, we can convert it! const TagType *TT = Ty->getAs(); diff --git a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp index 3d9229da6b03..458339642932 100644 --- a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp +++ b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp @@ -232,3 +232,11 @@ Base2MemFunc derived_to_base(DerivedMemFunc ptr) { // LLVM-NEXT: %[[#adj:]] = extractvalue { i64, i64 } %[[#arg]], 1 // LLVM-NEXT: %[[#adj_adj:]] = sub i64 %[[#adj]], 16 // LLVM-NEXT: %{{.+}} = insertvalue { i64, i64 } %[[#arg]], i64 %[[#adj_adj]], 1 + +struct HasVTable { + virtual void test(void (Foo::*)()); +}; + +// Ensure that the vfunc pointer to the function involving a pointer-to-member- +// func could be emitted. +void HasVTable::test(void (Foo::*)()) {}