Skip to content

Commit f0885ce

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 #61454
1 parent 2b8a397 commit f0885ce

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
// RUN: %target-swift-frontend -DBORROW_PASS_TO_VALUE_PARAM -emit-ir -o /dev/null -I %t %t/test.swift -enable-experimental-cxx-interop -verify
10+
11+
//--- Inputs/module.modulemap
12+
module CxxTest {
13+
header "test.h"
14+
requires cplusplus
15+
}
16+
17+
//--- Inputs/test.h
18+
19+
inline int &getCopyCounter() {
20+
static int value = 0;
21+
return value;
22+
}
23+
24+
class BorrowMe {
25+
public:
26+
BorrowMe(): x_(11) {}
27+
BorrowMe(const BorrowMe &other): x_(other.x_) {
28+
++getCopyCounter();
29+
}
30+
31+
const int &x() const { return x_; }
32+
int &x() { return x_; }
33+
private:
34+
int x_;
35+
};
36+
37+
inline int takeBorrowConstRef(const BorrowMe &value) {
38+
return value.x();
39+
}
40+
41+
inline int takeBorrowByVal(BorrowMe value) {
42+
return value.x();
43+
}
44+
45+
//--- test.swift
46+
47+
import CxxTest
48+
49+
extension BorrowMe {
50+
borrowing func getX() -> CInt {
51+
__xUnsafe().pointee
52+
}
53+
54+
var x: CInt {
55+
borrowing get {
56+
getX()
57+
}
58+
}
59+
}
60+
61+
func testBorrowingParam(_ value: borrowing BorrowMe) {
62+
let x = takeBorrowConstRef(value)
63+
assert(x == 11)
64+
#if BORROW_PASS_TO_VALUE_PARAM
65+
takeBorrowByVal(value) // expected-error@-4 {{'value' is borrowed and cannot be consumed}} expected-note {{consumed here}}
66+
takeBorrowByVal(copy value) // ok
67+
#endif
68+
}
69+
70+
public func testBorrowingSafeReferenceUse() {
71+
let x: CInt
72+
do {
73+
let p = BorrowMe()
74+
x = p.x
75+
testBorrowingParam(p)
76+
}
77+
if x != 11 { fatalError("wrong value") }
78+
assert(getCopyCounter().pointee == 0)
79+
}
80+
81+
testBorrowingSafeReferenceUse()

0 commit comments

Comments
 (0)