Closed
Description
Previous ID | SR-13129 |
Radar | rdar://problem/83423212 |
Original Reporter | MForster (JIRA User) |
Type | Bug |
Attachment: Download
Additional Detail from JIRA
Votes | 0 |
Component/s | Compiler |
Labels | Bug, CxxInterop, IRGen, Windows |
Assignee | None |
Priority | Medium |
md5: c3f23723106b510fdc433108dfead71b
Issue Description:
On Windows IRGen passes arguments to non-static C++ member functions in the wrong order if the result value is passed indirectly.
test.h
struct Result {};
struct MyStruct {
Result foo() { return Result{}; }
};
test.swift
import Test
public func bar(arg: inout MyStruct) -> Result { arg.foo() }
The C++ function expects the this pointer first and the result pointer second. Swift's C++ Interop, however, passes the result first and the this pointer second (after bitcasting them).
Look at the three lines starting from %3.
test.ll
define dllexport swiftcc void @"$s4test3bar3argSo6ResultVSo8MyStructVz_tF"(%TSo8MyStructV* nocapture dereferenceable(1) %0) #​0 {
entry:
%call.aggresult = alloca %TSo6ResultV, align 1
%1 = bitcast %TSo8MyStructV* %0 to %struct.MyStruct*
%2 = bitcast %TSo6ResultV* %call.aggresult to i8*
call void @llvm.lifetime.start.p0i8(i64 1, i8* %2)
%3 = bitcast %TSo6ResultV* %call.aggresult to %struct.MyStruct*
%4 = bitcast %struct.MyStruct* %1 to %struct.Result*
call void @"?foo@MyStruct@@QEAA?AUResult@@XZ"(%struct.MyStruct* noalias nocapture sret %3, %struct.Result* %4)
%5 = bitcast %TSo6ResultV* %call.aggresult to i8*
call void @llvm.lifetime.end.p0i8(i64 1, i8* %5)
ret void
}
; Function Attrs: noinline nounwind optnone uwtable
define linkonce_odr dso_local void @"?foo@MyStruct@@QEAA?AUResult@@XZ"(%struct.MyStruct* %this, %struct.Result* noalias sret align 1 %agg.result) #​1 comdat align 2 {