Skip to content

Conversation

@lanza
Copy link
Member

@lanza lanza commented Nov 24, 2025

Stack from ghstack (oldest at bottom):

This change implements APValue emission for member function pointers in
constexpr contexts, fixing crashes when encountering member function
pointers in constant expressions.

Problem:
Previously, attempting to emit a member function pointer in a constant
expression would hit an assertion at CIRGenExprConst.cpp:2075 with
"not implemented". This prevented compilation of valid C++ code that
uses member function pointers as compile-time constants.

Solution:
The implementation follows CodeGen's approach in CGExprConstant.cpp,
delegating to the CXX ABI for member pointer emission. Key changes:

  1. Extended MethodAttr to include an 'adjustment' field for the
    this-pointer adjustment needed for multiple inheritance and virtual
    base classes, per Itanium C++ ABI 2.3.2 (member function pointers are
    represented as struct { fnptr_t ptr; ptrdiff_t adj }).

  2. Added CIRGenCXXABI interface methods:

    • emitMemberPointer: Emit a member pointer from an APValue
    • buildMemberFunctionPointer: Build with method and adjustment
    • buildMemberDataPointer: Build data member pointer (currently NYI)
  3. Implemented these methods in CIRGenItaniumCXXABI:

    • Virtual methods: Store vtable offset + 1
    • Non-virtual methods: Store function pointer
    • Null pointers: Create null MethodAttr
    • All with proper this-pointer adjustments
  4. Updated ConstantEmitter::tryEmitPrivate to delegate member pointer
    emission to the ABI implementation, with proper llvm_unreachable
    guard for NYI derived-to-base conversions

  5. Updated lowering in ItaniumCXXABI.cpp to use the adjustment field
    when lowering MethodAttr to LLVM IR

  6. Added support in LowerToLLVM.cpp for lowering MethodAttr global
    initializers by delegating to the ABI layer (matching the pattern
    used for DataMemberAttr)

Testing (member-ptr-init.cpp):

  • CIR output: Validates #cir.method attributes for non-virtual, virtual,
    and null member function pointers
  • LLVM lowering: Validates correct { i64, i64 } struct layout matching
    Itanium ABI with function pointer/vtable offset and adjustment
  • OGCG comparison: Confirms CIR's LLVM output exactly matches original
    CodeGen for all test cases

All 385 existing CIR CodeGen tests continue to pass.

Implementation follows ClangIR conventions:

  • Copies CodeGen's delegation pattern to CXXABI
  • Has tests for CIR output, LLVM lowering, and OGCG comparison
  • All NYI code paths properly guarded with llvm_unreachable
  • Code formatted with clang-format

[ghstack-poisoned]
Copy link
Member

@bcardosolopes bcardosolopes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after nit

mlir::TypedAttr abiValue = lowerMod->getCXXABI().lowerMethodConstant(
methodAttr, layout, *typeConverter);
init = abiValue;
auto abiLlvmType = convertTypeForMemory(*getTypeConverter(), dataLayout,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*abiLLVMType

@lanza lanza reopened this Nov 24, 2025
@lanza lanza marked this pull request as draft November 24, 2025 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants