Skip to content

Commit c86f2c0

Browse files
committed
Add a simple borrow accessor end to end test
1 parent e4d1123 commit c86f2c0

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

include/swift/SIL/MemAccessUtils.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,9 +1811,11 @@ Result AccessUseDefChainVisitor<Impl, Result>::visit(SILValue sourceAddr) {
18111811
return asImpl().visitUnidentified(sourceAddr);
18121812

18131813
if (isGuaranteedAddressReturn(sourceAddr)) {
1814-
return asImpl().visitAccessProjection(
1815-
cast<ApplyInst>(sourceAddr),
1816-
&cast<ApplyInst>(sourceAddr)->getSelfArgumentOperand());
1814+
auto *selfOp = &cast<ApplyInst>(sourceAddr)->getSelfArgumentOperand();
1815+
if (selfOp->get()->getType().isObject()) {
1816+
return asImpl().visitUnidentified(sourceAddr);
1817+
}
1818+
return asImpl().visitAccessProjection(cast<ApplyInst>(sourceAddr), selfOp);
18171819
}
18181820

18191821
// Don't currently allow any other calls to return an accessed address.

test/SIL/borrow_accessor_e2e.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift %s -emit-executable -enable-experimental-feature BorrowAndMutateAccessors -o %t/a.out
3+
// RUN: %target-codesign %t/a.out
4+
// RUN: %target-run %t/a.out
5+
6+
// REQUIRES: swift_feature_BorrowAndMutateAccessors
7+
// REQUIRES: executable_test
8+
9+
public struct Container<Element: ~Copyable >: ~Copyable {
10+
var _storage: UnsafeBufferPointer<Element>
11+
var _count: Int
12+
13+
var first: Element {
14+
@_unsafeSelfDependentResult
15+
borrow {
16+
return _storage.baseAddress.unsafelyUnwrapped.pointee
17+
}
18+
}
19+
20+
public subscript(index: Int) -> Element {
21+
@_unsafeSelfDependentResult
22+
borrow {
23+
precondition(index >= 0 && index < _count, "Index out of bounds")
24+
return _storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee
25+
}
26+
}
27+
}
28+
29+
extension Container: Copyable where Element: Copyable {}
30+
31+
func test() {
32+
let n = 10_000
33+
let arr = Array(0...n)
34+
let sum = arr.withUnsafeBufferPointer { ubpointer in
35+
let container = Container(_storage: ubpointer, _count: arr.count)
36+
var sum = 0
37+
for i in 0..<container._count {
38+
sum &+= container[i]
39+
}
40+
return sum
41+
}
42+
let expectedSum = n * (n + 1) / 2
43+
assert(sum == expectedSum)
44+
}
45+
46+
test()
47+

0 commit comments

Comments
 (0)