[C++-Interop] C++ struct passed by value to an objc_msgSend is passed as a pointer type of ABIArgInfo::Direct instead of a Indirect byval #61929
Labels
bug
A deviation from expected or documented behavior. Also: expected but undesirable behavior.
c++ interop
Feature: Interoperability with C++
For the following ObjC implementation:
Any ObjC method call to this new method would pass the Container argument with a LLVM IR byval attribute, and the LLVM function define for this method includes the byval attribute:
The Swift ClangImporter in the presence of C++-Interop does not include this byval (
byval(%struct.Container)
) and at the callsite instead produces:where I think it could possibly instead produce:
I am still trying to understand why, but I believe it is because in the importer the ObjCMethodDecl is handled in a way where it is assumed that the argument is ABIArgInfo::Direct versus an ABIArgInfo::Indirect with a byval flag.
I have some example code that is affected by this behavior where on X86_64 (found with iOS Simulator) passing the mentioned C++ struct type by value results an a corruption in the parameter passing (often the resulting value is passed with some 8-16 bytes offset incorrectly.
The example code is as follows:
Implementation:
Header:
Swift:
Module Map (module.modulemap):
Compile and running should result in:
But instead result in the following which is offset and contains garbage (or possibly even a segfault):
I have attached a zip file that includes a run.sh file and the above sources to build and run all of this with a
./run.sh /path/to/toolchain/bin
cxx_interop_byval.zip
The text was updated successfully, but these errors were encountered: