As reported in https://github.com/llvm/llvm-project/issues/58929,
Clang's handling of empty structs in the case of small structs that may
be eligible to be passed using the hard FP calling convention doesn't
match g++. In general, C++ record fields are never empty unless
[[no_unique_address]] is used, but the RISC-V FP ABI overrides this.
After this patch, fields of structs that contain empty records will be
ignored, even in C++, when considering eligibility for the FP calling
convention ('flattening'). It isn't explicitly noted in the RISC-V
psABI, but arrays of empty records will disqualify a struct for
consideration of using the FP calling convention in g++. This patch
matches that behaviour. The psABI issue
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/358 seeks
to clarify this.
I've observed (based on manually added tracing) that we may return true here with Field1Ty == nullptr and Field2Ty == nullptr.
Then RISCVABIInfo::coerceAndExpandFPCCEligibleStruct receives these two types and appends Field1Ty it into UnpaddedCoerceElts and then if Field2Ty == nullptr it calls ABIArgInfo::getCoerceAndExpand (around line 280 of clang/lib/CodeGen/Targets/RISCV.cpp) which then tries to do a dyn_cast on a null value and then an assertion fires (around line 256 of clang/include/clang/CodeGen/CGFunctionInfo.h)
I can reproduce this with the llvm-testsuite. Apologies that I have not managed to create a small reproducer yet.