Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-13129] [IRGen, Windows] Wrong argument order when calling C++ member functions with indirect return types #55575

Closed
swift-ci opened this issue Jul 1, 2020 · 2 comments · Fixed by #67268
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. c++ interop Feature: Interoperability with C++ compiler The Swift compiler in itself IRGen LLVM IR generation Windows Platform: Windows

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jul 1, 2020

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 {
@swift-ci
Copy link
Collaborator Author

swift-ci commented Jul 2, 2020

Comment by Michael Forster (JIRA)

I suspect that we need to add a new function calling convention for C++ member functions.

@zoecarver
Copy link
Collaborator

@swift-ci create

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@zoecarver zoecarver added c++ interop Feature: Interoperability with C++ and removed CxxInterop labels Apr 25, 2022
@hyp hyp linked a pull request Jul 20, 2023 that will close this issue
@hyp hyp self-assigned this Jul 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. c++ interop Feature: Interoperability with C++ compiler The Swift compiler in itself IRGen LLVM IR generation Windows Platform: Windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants