Skip to content

Commit 0cc114f

Browse files
authored
Merge pull request #80317 from swiftlang/fix-sort-and-bounds-checks
[Swiftify] Fix transformation sort, and dropped bounds checks
2 parents 783118e + 160bb41 commit 0cc114f

File tree

2 files changed

+63
-3
lines changed

2 files changed

+63
-3
lines changed

lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ struct CxxSpanThunkBuilder: ParamPointerBoundsThunkBuilder {
411411
let isSizedBy: Bool = false
412412

413413
func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item] {
414-
return []
414+
return try base.buildBoundsChecks()
415415
}
416416

417417
func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws
@@ -447,7 +447,7 @@ struct CxxSpanReturnThunkBuilder: BoundsCheckedThunkBuilder {
447447
public let node: SyntaxProtocol
448448

449449
func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item] {
450-
return []
450+
return try base.buildBoundsChecks()
451451
}
452452

453453
func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws
@@ -1142,7 +1142,13 @@ public struct SwiftifyImportMacro: PeerMacro {
11421142
parsedArgs.sort { a, b in
11431143
// make sure return value cast to Span happens last so that withUnsafeBufferPointer
11441144
// doesn't return a ~Escapable type
1145-
(a.pointerIndex != .return && b.pointerIndex == .return) || paramOrReturnIndex(a.pointerIndex) < paramOrReturnIndex(b.pointerIndex)
1145+
if a.pointerIndex != .return && b.pointerIndex == .return {
1146+
return true
1147+
}
1148+
if a.pointerIndex == .return && b.pointerIndex != .return {
1149+
return false
1150+
}
1151+
return paramOrReturnIndex(a.pointerIndex) < paramOrReturnIndex(b.pointerIndex)
11461152
}
11471153
let baseBuilder = FunctionCallBuilder(funcDecl)
11481154

test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,27 @@ struct X {
3232
func myFunc5() -> SpanOfInt {}
3333
}
3434

35+
@_SwiftifyImport(.lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy),
36+
.sizedBy(pointer: .param(2), size: "count * size"),
37+
.nonescaping(pointer: .param(2)),
38+
typeMappings: ["SpanOfInt" : "std.span<CInt>"])
39+
func myFunc6(_ span: SpanOfInt, _ ptr: UnsafeRawPointer, _ count: CInt, _ size: CInt) -> SpanOfInt {
40+
}
41+
42+
@_SwiftifyImport(.sizedBy(pointer: .param(2), size: "count * size"),
43+
.lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy),
44+
.nonescaping(pointer: .param(2)),
45+
typeMappings: ["SpanOfInt" : "std.span<CInt>"])
46+
func myFunc7(_ span: SpanOfInt, _ ptr: UnsafeRawPointer, _ count: CInt, _ size: CInt) -> SpanOfInt {
47+
}
48+
49+
@_SwiftifyImport(.sizedBy(pointer: .param(1), size: "count * size"),
50+
.nonescaping(pointer: .param(1)),
51+
.lifetimeDependence(dependsOn: .param(2), pointer: .return, type: .copy),
52+
typeMappings: ["SpanOfInt" : "std.span<CInt>"])
53+
func myFunc8(_ ptr: UnsafeRawPointer, _ span: SpanOfInt, _ count: CInt, _ size: CInt) -> SpanOfInt {
54+
}
55+
3556
// CHECK: @_alwaysEmitIntoClient @lifetime(copy span)
3657
// CHECK-NEXT: func myFunc(_ span: Span<CInt>) -> Span<CInt> {
3758
// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: myFunc(SpanOfInt(span))), copying: ())
@@ -56,3 +77,36 @@ struct X {
5677
// CHECK-NEXT: func myFunc5() -> Span<CInt> {
5778
// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: myFunc5()), copying: ())
5879
// CHECK-NEXT: }
80+
81+
// CHECK: @_alwaysEmitIntoClient @lifetime(copy span)
82+
// CHECK-NEXT: func myFunc6(_ span: Span<CInt>, _ ptr: RawSpan, _ count: CInt, _ size: CInt) -> Span<CInt> {
83+
// CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size
84+
// CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 {
85+
// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function")
86+
// CHECK-NEXT: }
87+
// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: ptr.withUnsafeBytes { _ptrPtr in
88+
// CHECK-NEXT: return unsafe myFunc6(SpanOfInt(span), _ptrPtr.baseAddress!, count, size)
89+
// CHECK-NEXT: }), copying: ())
90+
// CHECK-NEXT: }
91+
92+
// CHECK: @_alwaysEmitIntoClient @lifetime(copy span)
93+
// CHECK-NEXT: func myFunc7(_ span: Span<CInt>, _ ptr: RawSpan, _ count: CInt, _ size: CInt) -> Span<CInt> {
94+
// CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size
95+
// CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 {
96+
// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function")
97+
// CHECK-NEXT: }
98+
// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: ptr.withUnsafeBytes { _ptrPtr in
99+
// CHECK-NEXT: return unsafe myFunc7(SpanOfInt(span), _ptrPtr.baseAddress!, count, size)
100+
// CHECK-NEXT: }), copying: ())
101+
// CHECK-NEXT: }
102+
103+
// CHECK: @_alwaysEmitIntoClient @lifetime(copy span)
104+
// CHECK-NEXT: func myFunc8(_ ptr: RawSpan, _ span: Span<CInt>, _ count: CInt, _ size: CInt) -> Span<CInt> {
105+
// CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size
106+
// CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 {
107+
// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function")
108+
// CHECK-NEXT: }
109+
// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: ptr.withUnsafeBytes { _ptrPtr in
110+
// CHECK-NEXT: return unsafe myFunc8(_ptrPtr.baseAddress!, SpanOfInt(span), count, size)
111+
// CHECK-NEXT: }), copying: ())
112+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)