Skip to content

Commit bae041c

Browse files
authored
Merge pull request #84841 from hnrklssn/swiftify-return-opaque
[Swiftify] Cast OpaquePointer to UnsafeRawPointer before RawSpan
2 parents 95358e8 + 7d5fd7d commit bae041c

File tree

2 files changed

+128
-12
lines changed

2 files changed

+128
-12
lines changed

lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,16 @@ func transformType(
349349
return mainType
350350
}
351351

352+
func peelOptionalType(_ type: TypeSyntax) -> TypeSyntax {
353+
if let optType = type.as(OptionalTypeSyntax.self) {
354+
return optType.wrappedType
355+
}
356+
if let impOptType = type.as(ImplicitlyUnwrappedOptionalTypeSyntax.self) {
357+
return impOptType.wrappedType
358+
}
359+
return type
360+
}
361+
352362
func isMutablePointerType(_ type: TypeSyntax) -> Bool {
353363
if let optType = type.as(OptionalTypeSyntax.self) {
354364
return isMutablePointerType(optType.wrappedType)
@@ -757,21 +767,30 @@ struct CountedOrSizedReturnPointerThunkBuilder: PointerBoundsThunkBuilder {
757767
if unsafe _resultValue == nil {
758768
return nil
759769
} else {
760-
return unsafe _swiftifyOverrideLifetime(\(raw: cast)(\(raw: startLabel): _resultValue!, \(raw: countLabel): Int(\(countExpr))), copying: ())
770+
return unsafe _swiftifyOverrideLifetime(\(raw: cast)(\(raw: startLabel): \(raw: castOpaquePointerToRawPointer("_resultValue!")), \(raw: countLabel): Int(\(countExpr))), copying: ())
761771
}
762772
}()
763773
"""
764774
} else {
765775
expr =
766776
"""
767-
\(raw: cast)(\(raw: startLabel): \(call), \(raw: countLabel): Int(\(countExpr)))
777+
\(raw: cast)(\(raw: startLabel): \(castOpaquePointerToRawPointer(call)), \(raw: countLabel): Int(\(countExpr)))
768778
"""
769779
}
770780
if generateSpan {
771781
expr = "_swiftifyOverrideLifetime(\(expr), copying: ())"
772782
}
773783
return "unsafe \(expr)"
774784
}
785+
786+
func castOpaquePointerToRawPointer(_ expr: ExprSyntax) -> ExprSyntax {
787+
let type = peelOptionalType(oldType)
788+
if type.canRepresentBasicType(type: OpaquePointer.self) {
789+
return ExprSyntax("unsafe UnsafeRawPointer(\(expr))")
790+
}
791+
return expr
792+
}
793+
775794
}
776795

777796
struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBoundsThunkBuilder {
@@ -897,16 +916,6 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds
897916
return "_\(raw: name)Count"
898917
}
899918

900-
func peelOptionalType(_ type: TypeSyntax) -> TypeSyntax {
901-
if let optType = type.as(OptionalTypeSyntax.self) {
902-
return optType.wrappedType
903-
}
904-
if let impOptType = type.as(ImplicitlyUnwrappedOptionalTypeSyntax.self) {
905-
return impOptType.wrappedType
906-
}
907-
return type
908-
}
909-
910919
func castPointerToTargetType(_ baseAddress: ExprSyntax) throws -> ExprSyntax {
911920
let type = peelOptionalType(getParam(signature, index).type)
912921
if type.canRepresentBasicType(type: OpaquePointer.self) {
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// REQUIRES: swift_swift_parser
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: split-file %s %t
5+
// RUN: %target-swift-frontend %t/test.swift -typecheck -plugin-path %swift-plugin-dir -strict-memory-safety -verify
6+
// RUN: %target-swift-frontend %t/test.swift -typecheck -plugin-path %swift-plugin-dir -strict-memory-safety -dump-macro-expansions 2> %t/tmp.txt
7+
// RUN: %FileCheck --dry-run --ignore-runtime-warnings > %t/expansions.txt < %t/tmp.txt
8+
// RUN: diff --strip-trailing-cr %t/expansions.txt %t/expansions.txt.expected
9+
10+
//--- test.swift
11+
@_SwiftifyImport(.sizedBy(pointer: .return, size: "size"))
12+
public func nonnullUnsafeRawBufferPointer(_ size: CInt) -> OpaquePointer {}
13+
14+
@_SwiftifyImport(.sizedBy(pointer: .return, size: "size"))
15+
public func nullableUnsafeRawBufferPointer(_ size: CInt) -> OpaquePointer? {}
16+
17+
@_SwiftifyImport(.sizedBy(pointer: .return, size: "size"))
18+
public func impNullableUnsafeRawBufferPointer(_ size: CInt) -> OpaquePointer! {}
19+
20+
@_SwiftifyImport(.sizedBy(pointer: .return, size: "size"), .sizedBy(pointer: .param(1), size: "size"), .lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy))
21+
public func nonnullSpan(p: OpaquePointer, size: CInt) -> OpaquePointer {}
22+
23+
@_SwiftifyImport(.sizedBy(pointer: .return, size: "size"), .sizedBy(pointer: .param(1), size: "size"), .lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy))
24+
public func nullableSpan(p: OpaquePointer?, _ size: CInt) -> OpaquePointer? {}
25+
26+
@_SwiftifyImport(.sizedBy(pointer: .return, size: "size"), .sizedBy(pointer: .param(1), size: "size"), .lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy))
27+
public func impNullableSpan(p: OpaquePointer!, _ size: CInt) -> OpaquePointer! {}
28+
29+
//--- expansions.txt.expected
30+
@__swiftmacro_4test29nonnullUnsafeRawBufferPointer15_SwiftifyImportfMp_.swift
31+
------------------------------
32+
/// This is an auto-generated wrapper for safer interop
33+
@_alwaysEmitIntoClient @_disfavoredOverload
34+
public func nonnullUnsafeRawBufferPointer(_ size: CInt) -> UnsafeRawBufferPointer {
35+
return unsafe UnsafeRawBufferPointer(start: unsafe UnsafeRawPointer(unsafe nonnullUnsafeRawBufferPointer(size)), count: Int(size))
36+
}
37+
------------------------------
38+
@__swiftmacro_4test30nullableUnsafeRawBufferPointer15_SwiftifyImportfMp_.swift
39+
------------------------------
40+
/// This is an auto-generated wrapper for safer interop
41+
@_alwaysEmitIntoClient @_disfavoredOverload
42+
public func nullableUnsafeRawBufferPointer(_ size: CInt) -> UnsafeRawBufferPointer? {
43+
return unsafe { () in
44+
let _resultValue = unsafe nullableUnsafeRawBufferPointer(size)
45+
if unsafe _resultValue == nil {
46+
return nil
47+
} else {
48+
return unsafe _swiftifyOverrideLifetime(UnsafeRawBufferPointer(start: unsafe UnsafeRawPointer(_resultValue!), count: Int(size)), copying: ())
49+
}
50+
}()
51+
}
52+
------------------------------
53+
@__swiftmacro_4test33impNullableUnsafeRawBufferPointer15_SwiftifyImportfMp_.swift
54+
------------------------------
55+
/// This is an auto-generated wrapper for safer interop
56+
@_alwaysEmitIntoClient @_disfavoredOverload
57+
public func impNullableUnsafeRawBufferPointer(_ size: CInt) -> UnsafeRawBufferPointer {
58+
return unsafe UnsafeRawBufferPointer(start: unsafe UnsafeRawPointer(unsafe impNullableUnsafeRawBufferPointer(size)), count: Int(size))
59+
}
60+
------------------------------
61+
@__swiftmacro_4test11nonnullSpan15_SwiftifyImportfMp_.swift
62+
------------------------------
63+
/// This is an auto-generated wrapper for safer interop
64+
@_alwaysEmitIntoClient @_lifetime(copy p) @_disfavoredOverload
65+
public func nonnullSpan(p: RawSpan) -> RawSpan {
66+
let size = CInt(exactly: p.byteCount)!
67+
return unsafe _swiftifyOverrideLifetime(RawSpan(_unsafeStart: unsafe UnsafeRawPointer(unsafe p.withUnsafeBytes { _pPtr in
68+
return unsafe nonnullSpan(p: OpaquePointer(_pPtr.baseAddress!), size: size)
69+
}), byteCount: Int(size)), copying: ())
70+
}
71+
------------------------------
72+
@__swiftmacro_4test12nullableSpan15_SwiftifyImportfMp_.swift
73+
------------------------------
74+
/// This is an auto-generated wrapper for safer interop
75+
@_alwaysEmitIntoClient @_lifetime(copy p) @_disfavoredOverload
76+
public func nullableSpan(p: RawSpan?) -> RawSpan? {
77+
let size = CInt(exactly: p?.byteCount ?? 0)!
78+
return unsafe _swiftifyOverrideLifetime({ () in
79+
let _resultValue = { () in
80+
return if p == nil {
81+
unsafe nullableSpan(p: nil, size)
82+
} else {
83+
unsafe p!.withUnsafeBytes { _pPtr in
84+
return unsafe nullableSpan(p: OpaquePointer(_pPtr.baseAddress), size)
85+
}
86+
}
87+
}()
88+
if unsafe _resultValue == nil {
89+
return nil
90+
} else {
91+
return unsafe _swiftifyOverrideLifetime(RawSpan(_unsafeStart: unsafe UnsafeRawPointer(_resultValue!), byteCount: Int(size)), copying: ())
92+
}
93+
}(), copying: ())
94+
}
95+
------------------------------
96+
@__swiftmacro_4test15impNullableSpan15_SwiftifyImportfMp_.swift
97+
------------------------------
98+
/// This is an auto-generated wrapper for safer interop
99+
@_alwaysEmitIntoClient @_lifetime(copy p) @_disfavoredOverload
100+
public func impNullableSpan(p: RawSpan) -> RawSpan {
101+
let size = CInt(exactly: p.byteCount)!
102+
return unsafe _swiftifyOverrideLifetime(RawSpan(_unsafeStart: unsafe UnsafeRawPointer(unsafe p.withUnsafeBytes { _pPtr in
103+
return unsafe impNullableSpan(p: OpaquePointer(_pPtr.baseAddress!), size)
104+
}), byteCount: Int(size)), copying: ())
105+
}
106+
------------------------------
107+

0 commit comments

Comments
 (0)