Skip to content

Commit 64cdd93

Browse files
committed
[cxx-interop] add a testcase to verify that 'borrowing' works with copyable C++ types
This lets us verify that our suggested pattern for calling unsafe functions is working as intended in Swift This also lets us verify that we can still pass borrowed C++ types to C++ functions that take in a const ref parameter Tests now fixed swiftlang#61454
1 parent 2b8a397 commit 64cdd93

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: %target-build-swift %t/test.swift -I %t -o %t/out -Xfrontend -enable-experimental-cxx-interop -O
4+
// RUN: %target-codesign %t/out
5+
// RUN: %target-run %t/out
6+
7+
// Verify that a non-const ref value parameter can't implicitly receive
8+
// aborrowed value.
9+
10+
// FIXME: new parser complains about `borrowing get` - rdar://112168704.
11+
// RN: %target-swift-frontend -DBORROW_PASS_TO_VALUE_PARAM -emit-ir -o /dev/null -I %t %t/test.swift -enable-experimental-cxx-interop -verify
12+
13+
//--- Inputs/module.modulemap
14+
module CxxTest {
15+
header "test.h"
16+
requires cplusplus
17+
}
18+
19+
//--- Inputs/test.h
20+
21+
inline int &getCopyCounter() {
22+
static int value = 0;
23+
return value;
24+
}
25+
26+
class BorrowMe {
27+
public:
28+
BorrowMe(): x_(11) {}
29+
BorrowMe(const BorrowMe &other): x_(other.x_) {
30+
++getCopyCounter();
31+
}
32+
33+
const int &x() const { return x_; }
34+
int &x() { return x_; }
35+
private:
36+
int x_;
37+
};
38+
39+
inline int takeBorrowConstRef(const BorrowMe &value) {
40+
return value.x();
41+
}
42+
43+
inline int takeBorrowByVal(BorrowMe value) {
44+
return value.x();
45+
}
46+
47+
//--- test.swift
48+
49+
import CxxTest
50+
51+
extension BorrowMe {
52+
borrowing func getX() -> CInt {
53+
__xUnsafe().pointee
54+
}
55+
56+
var x: CInt {
57+
borrowing get {
58+
getX()
59+
}
60+
}
61+
}
62+
63+
func testBorrowingParam(_ value: borrowing BorrowMe) {
64+
let x = takeBorrowConstRef(value)
65+
assert(x == 11)
66+
#if BORROW_PASS_TO_VALUE_PARAM
67+
takeBorrowByVal(value) // expected-error@-4 {{'value' is borrowed and cannot be consumed}} expected-note {{consumed here}}
68+
takeBorrowByVal(copy value) // ok
69+
#endif
70+
}
71+
72+
public func testBorrowingSafeReferenceUse() {
73+
let x: CInt
74+
do {
75+
let p = BorrowMe()
76+
x = p.x
77+
testBorrowingParam(p)
78+
}
79+
if x != 11 { fatalError("wrong value") }
80+
assert(getCopyCounter().pointee == 0)
81+
}
82+
83+
testBorrowingSafeReferenceUse()

0 commit comments

Comments
 (0)