swift
[cxx-interop] Fix calling rvalue ref of a trivial type
#80568
Merged

[cxx-interop] Fix calling rvalue ref of a trivial type #80568

Xazax-hun merged 1 commit into main from gaborh/rvalue-ref-calling-conv
Xazax-hun
Xazax-hun94 days ago

The Swift compiler used to generate a direct call to functions taking rvalue references to trivial types even though they expected an indirect calling conventions. This PR changes the calling convention on the Swift side to match C++.

rdar://148585343

[cxx-interop] Fix calling rvalue ref of a trivial type
6b863f95
Xazax-hun Xazax-hun added c++ interop
Xazax-hun Xazax-hun requested a review from zoecarver zoecarver 94 days ago
Xazax-hun Xazax-hun requested a review from egorzhdan egorzhdan 94 days ago
Xazax-hun Xazax-hun requested a review from j-hui j-hui 94 days ago
Xazax-hun Xazax-hun requested a review from fahadnayyar fahadnayyar 94 days ago
Xazax-hun Xazax-hun requested a review from susmonteiro susmonteiro 94 days ago
Xazax-hun Xazax-hun requested a review from hnrklssn hnrklssn 94 days ago
Xazax-hun Xazax-hun requested a review from jckarter jckarter 94 days ago
Xazax-hun
Xazax-hun94 days ago

@swift-ci please smoke test

j-hui
j-hui approved these changes on 2025-04-06
test/Interop/Cxx/reference/reference.swift
105105
106ReferenceTestSuite.test("rvalue reference of trivial type") {
107 setStaticIntRvalueRef(consuming: 2)
108
expectEqual(2, getStaticInt())
j-hui94 days ago

Just curious, how would this test have failed prior to your change?

Xazax-hun94 days ago

It crashed with bad memory access. We passed 2 directly as if it was the address of the value.

fahadnayyar
fahadnayyar commented on 2025-04-06
test/Interop/Cxx/reference/reference.swift
103103 expectEqual(53, ref.pointee)
104104}
105105
106
ReferenceTestSuite.test("rvalue reference of trivial type") {
fahadnayyar94 days ago

I was seeing similar crashing in case C++ value types taking rvalue ref inside ctors in these 3 patterns:

// C++

struct cxxValTy {
public:
  int val;
  cxxValTy() {};
  cxxValTy(int x) { val = x; }
};

struct RValRefCtor {
public:
  cxxValTy val;
  RValRefCtor(cxxValTy &&x) {
    val = std::move(x); // <-- 1.) This crashing at runtime
    // val = x; // <-- 2.) This is also crashing at runtime
  }
  // RValRefCtor(cxxValTy &&x) : val(std::move(x)) {} // <-- 3.) This is also crashing at runtime
};

// Swift

let x11 = cxxValTy(5);
let y11 = RValRefCtor(consuming:x11)
expectEqual(y11.val.val, 5)

Should we add test cases for these as well in thie PR to verify that the problem is fixed in these patterns?

Xazax-hun93 days ago

I ended up merging this to make sure this is fixed as soon as possible. I think it is always valuable to have more test cases. Since you already have very similar tests in your PR, I think your PR will cover this as well. Or in case you end up not adding a similar test to your foreign reference constructor work let me know and I can open a follow-up.

fahadnayyar
fahadnayyar commented on 2025-04-06
lib/SIL/IR/SILFunctionType.cpp
15431543
if (importer::isCxxConstReferenceType(clangTy))
fahadnayyar94 days ago

I was reading rdar://89647503, I was wondering should we plan working on importing const ref param in C++ APIs as :borrowing . Does Swift now support immutable borrowed params?

Xazax-hun93 days ago (edited 93 days ago)

I think we have everything in place to always import const references as borrowing. But this could potentially be a big change so we should make this switch when we have the bandwidth to thoroughly test it to make sure it does not break existing code. Making the change itself should be relatively straightforward.

Xazax-hun Xazax-hun enabled auto-merge 94 days ago
Xazax-hun Xazax-hun merged 5ef33db9 into main 94 days ago
Xazax-hun Xazax-hun deleted the gaborh/rvalue-ref-calling-conv branch 94 days ago

Login to write a write a comment.

Login via GitHub

Assignees
No one assigned
Labels
Milestone