From 9e943fd37ec2b4aff8ab011ec15c96faef86e0c5 Mon Sep 17 00:00:00 2001 From: "Henrik G. Olsson" Date: Sat, 17 May 2025 02:25:30 -0700 Subject: [PATCH 1/2] [Swiftify] Always remove count parameters when possible Previously we did not remove count parameters if any count parameters were shared between count expressions, or if any count expression contained operations. Buffer sizes were also just checked to be larger than or equal than the given count. We now extract the count from Spans/BufferPointers whenever possible, and store that value in a variable at the start of the function. If multiple parameters share the same count, a bounds check is emitted to make sure that they have the same size. Subspans can be used if one span is larger than necessary. The message in the bounds check is changed so that it includes the expected and actual value, to aid in debugging. This patch also fixes some incorrect indentation, and adds the Whitespace.swift test case to act as a regression test in case the indentation changes, since the other test cases don't use significant whitespace. rdar://151488820 rdar://151511090 rdar://146333006 rdar://147715799 --- .../SwiftMacros/SwiftifyImportMacro.swift | 219 +++++++++--------- .../counted-by-lifetimebound.swift | 8 +- .../swiftify-import/counted-by-noescape.swift | 4 +- .../C/swiftify-import/counted-by.swift | 6 +- .../sized-by-lifetimebound.swift | 8 +- .../C/swiftify-import/sized-by-noescape.swift | 6 +- test/Interop/C/swiftify-import/sized-by.swift | 4 +- .../SwiftifyImport/CountedBy/Anonymous.swift | 20 +- .../SwiftifyImport/CountedBy/CountExpr.swift | 6 +- .../CountedBy/MultipleParams.swift | 4 +- .../SwiftifyImport/CountedBy/Mutable.swift | 3 +- .../CountedBy/MutableSpan.swift | 3 +- .../CountedBy/NamedParams.swift | 18 +- .../SwiftifyImport/CountedBy/Nullable.swift | 25 +- .../CountedBy/PointerReturn.swift | 10 +- .../CountedBy/QualifiedTypes.swift | 6 +- .../SwiftifyImport/CountedBy/Return.swift | 3 +- .../CountedBy/SharedCount.swift | 71 +++++- .../CountedBy/SimpleCount.swift | 3 +- .../SwiftifyImport/CountedBy/SimpleSpan.swift | 3 +- .../CountedBy/SimpleSpanWithReturn.swift | 3 +- .../CountedBy/SpanAndUnsafeBuffer.swift | 4 +- .../SwiftifyImport/CountedBy/Unwrapped.swift | 3 +- .../SwiftifyImport/CountedBy/Whitespace.swift | 49 ++++ .../CxxSpan/LifetimeboundSpan.swift | 34 +-- .../SizedBy/MultipleParams.swift | 4 +- .../SwiftifyImport/SizedBy/Mutable.swift | 3 +- .../SizedBy/MutableRawSpan.swift | 3 +- .../SwiftifyImport/SizedBy/Nullable.swift | 81 +++---- .../SwiftifyImport/SizedBy/Opaque.swift | 25 +- .../SizedBy/PointerReturn.swift | 12 +- .../SwiftifyImport/SizedBy/Return.swift | 3 +- .../SwiftifyImport/SizedBy/SharedCount.swift | 12 +- .../SizedBy/SimpleRawSpan.swift | 3 +- .../SizedBy/SimpleRawSpanWithReturn.swift | 3 +- .../SwiftifyImport/SizedBy/SimpleSize.swift | 3 +- .../SwiftifyImport/SizedBy/SizeExpr.swift | 6 +- .../SwiftifyImport/SizedBy/Unwrapped.swift | 3 +- 38 files changed, 419 insertions(+), 265 deletions(-) create mode 100644 test/Macros/SwiftifyImport/CountedBy/Whitespace.swift diff --git a/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift b/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift index bd0762d3732eb..5be714860742a 100644 --- a/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift +++ b/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift @@ -40,8 +40,7 @@ protocol ParamInfo: CustomStringConvertible { var dependencies: [LifetimeDependence] { get set } func getBoundsCheckedThunkBuilder( - _ base: BoundsCheckedThunkBuilder, _ funcDecl: FunctionDeclSyntax, - _ skipTrivialCount: Bool + _ base: BoundsCheckedThunkBuilder, _ funcDecl: FunctionDeclSyntax ) -> BoundsCheckedThunkBuilder } @@ -80,20 +79,19 @@ struct CxxSpan: ParamInfo { } func getBoundsCheckedThunkBuilder( - _ base: BoundsCheckedThunkBuilder, _ funcDecl: FunctionDeclSyntax, - _ skipTrivialCount: Bool + _ base: BoundsCheckedThunkBuilder, _ funcDecl: FunctionDeclSyntax ) -> BoundsCheckedThunkBuilder { switch pointerIndex { case .param(let i): return CxxSpanThunkBuilder( - base: base, index: i - 1, signature: funcDecl.signature, + base: base, index: i - 1, funcDecl: funcDecl, typeMappings: typeMappings, node: original, nonescaping: nonescaping) case .return: if dependencies.isEmpty { return base } return CxxSpanReturnThunkBuilder( - base: base, signature: funcDecl.signature, + base: base, funcDecl: funcDecl, typeMappings: typeMappings, node: original) case .self: return base @@ -117,19 +115,18 @@ struct CountedBy: ParamInfo { } func getBoundsCheckedThunkBuilder( - _ base: BoundsCheckedThunkBuilder, _ funcDecl: FunctionDeclSyntax, - _ skipTrivialCount: Bool + _ base: BoundsCheckedThunkBuilder, _ funcDecl: FunctionDeclSyntax ) -> BoundsCheckedThunkBuilder { switch pointerIndex { case .param(let i): return CountedOrSizedPointerThunkBuilder( base: base, index: i - 1, countExpr: count, - signature: funcDecl.signature, - nonescaping: nonescaping, isSizedBy: sizedBy, skipTrivialCount: skipTrivialCount) + funcDecl: funcDecl, + nonescaping: nonescaping, isSizedBy: sizedBy) case .return: return CountedOrSizedReturnPointerThunkBuilder( base: base, countExpr: count, - signature: funcDecl.signature, + funcDecl: funcDecl, nonescaping: nonescaping, isSizedBy: sizedBy, dependencies: dependencies) case .self: return base @@ -380,7 +377,16 @@ func isMutablePointerType(_ type: TypeSyntax) -> Bool { protocol BoundsCheckedThunkBuilder { func buildFunctionCall(_ pointerArgs: [Int: ExprSyntax]) throws -> ExprSyntax - func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item] + // buildBasicBoundsChecks creates a variable with the same name as the parameter it replaced, + // or if that variable already exists (because another pointer has the same count), checks that + // the values match. + func buildBasicBoundsChecks(_ extractedCountArgs: inout Set) throws -> [CodeBlockItemSyntax.Item] + // buildCompoundBoundsChecks performs bounds checks of count expressions that contain operations. + // It may refer to names constructed in buildBasicBoundsChecks (in the case of shared variables), + // so those must come before this in the function body. + func buildCompoundBoundsChecks() throws -> [CodeBlockItemSyntax.Item] + // The second component of the return value is true when only the return type of the + // function signature was changed. func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws -> FunctionSignatureSyntax } @@ -405,7 +411,10 @@ struct FunctionCallBuilder: BoundsCheckedThunkBuilder { base = function } - func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { + func buildBasicBoundsChecks(_ extractedCountArgs: inout Set) throws -> [CodeBlockItemSyntax.Item] { + return [] + } + func buildCompoundBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { return [] } @@ -465,15 +474,18 @@ struct FunctionCallBuilder: BoundsCheckedThunkBuilder { struct CxxSpanThunkBuilder: SpanBoundsThunkBuilder, ParamBoundsThunkBuilder { public let base: BoundsCheckedThunkBuilder public let index: Int - public let signature: FunctionSignatureSyntax + public let funcDecl: FunctionDeclSyntax public let typeMappings: [String: String] public let node: SyntaxProtocol public let nonescaping: Bool let isSizedBy: Bool = false let isParameter: Bool = true - func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { - return try base.buildBoundsChecks() + func buildBasicBoundsChecks(_ extractedCountArgs: inout Set) throws -> [CodeBlockItemSyntax.Item] { + return try base.buildBasicBoundsChecks(&extractedCountArgs) + } + func buildCompoundBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { + return try base.buildCompoundBoundsChecks() } func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws @@ -502,9 +514,9 @@ struct CxxSpanThunkBuilder: SpanBoundsThunkBuilder, ParamBoundsThunkBuilder { // so unwrap it to an UnsafeMutableBufferPointer that we can cast let unwrappedCall = ExprSyntax( """ - unsafe \(name).withUnsafeMutableBufferPointer { \(unwrappedName) in - return \(call) - } + unsafe \(name).withUnsafeMutableBufferPointer { \(unwrappedName) in + return \(call) + } """) return unwrappedCall } @@ -513,7 +525,7 @@ struct CxxSpanThunkBuilder: SpanBoundsThunkBuilder, ParamBoundsThunkBuilder { struct CxxSpanReturnThunkBuilder: SpanBoundsThunkBuilder { public let base: BoundsCheckedThunkBuilder - public let signature: FunctionSignatureSyntax + public let funcDecl: FunctionDeclSyntax public let typeMappings: [String: String] public let node: SyntaxProtocol let isParameter: Bool = false @@ -522,8 +534,11 @@ struct CxxSpanReturnThunkBuilder: SpanBoundsThunkBuilder { return signature.returnClause!.type } - func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { - return try base.buildBoundsChecks() + func buildBasicBoundsChecks(_ extractedCountArgs: inout Set) throws -> [CodeBlockItemSyntax.Item] { + return try base.buildBasicBoundsChecks(&extractedCountArgs) + } + func buildCompoundBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { + return try base.buildCompoundBoundsChecks() } func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws @@ -549,7 +564,13 @@ struct CxxSpanReturnThunkBuilder: SpanBoundsThunkBuilder { protocol BoundsThunkBuilder: BoundsCheckedThunkBuilder { var oldType: TypeSyntax { get } var newType: TypeSyntax { get throws } - var signature: FunctionSignatureSyntax { get } + var funcDecl: FunctionDeclSyntax { get } +} + +extension BoundsThunkBuilder { + var signature: FunctionSignatureSyntax { + funcDecl.signature + } } protocol SpanBoundsThunkBuilder: BoundsThunkBuilder { @@ -654,7 +675,7 @@ extension ParamBoundsThunkBuilder { struct CountedOrSizedReturnPointerThunkBuilder: PointerBoundsThunkBuilder { public let base: BoundsCheckedThunkBuilder public let countExpr: ExprSyntax - public let signature: FunctionSignatureSyntax + public let funcDecl: FunctionDeclSyntax public let nonescaping: Bool public let isSizedBy: Bool public let dependencies: [LifetimeDependence] @@ -673,8 +694,11 @@ struct CountedOrSizedReturnPointerThunkBuilder: PointerBoundsThunkBuilder { return try base.buildFunctionSignature(argTypes, newType) } - func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { - return try base.buildBoundsChecks() + func buildBasicBoundsChecks(_ extractedCountArgs: inout Set) throws -> [CodeBlockItemSyntax.Item] { + return try base.buildBasicBoundsChecks(&extractedCountArgs) + } + func buildCompoundBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { + return try base.buildCompoundBoundsChecks() } func buildFunctionCall(_ pointerArgs: [Int: ExprSyntax]) throws -> ExprSyntax { @@ -719,10 +743,9 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds public let base: BoundsCheckedThunkBuilder public let index: Int public let countExpr: ExprSyntax - public let signature: FunctionSignatureSyntax + public let funcDecl: FunctionDeclSyntax public let nonescaping: Bool public let isSizedBy: Bool - public let skipTrivialCount: Bool let isParameter: Bool = true var generateSpan: Bool { nonescaping } @@ -732,29 +755,48 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds { var types = argTypes types[index] = try newType - if skipTrivialCount { - if let countVar = countExpr.as(DeclReferenceExprSyntax.self) { - let i = try getParameterIndexForDeclRef(signature.parameterClause.parameters, countVar) - types[i] = nil as TypeSyntax? - } + if let countVar = countExpr.as(DeclReferenceExprSyntax.self) { + let i = try getParameterIndexForDeclRef(signature.parameterClause.parameters, countVar) + types[i] = nil as TypeSyntax? } return try base.buildFunctionSignature(types, returnType) } - func buildBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { - var res = try base.buildBoundsChecks() - let countName: TokenSyntax = "_\(raw: name)Count" - let count: VariableDeclSyntax = try VariableDeclSyntax( - "let \(countName): some BinaryInteger = \(countExpr)") - res.append(CodeBlockItemSyntax.Item(count)) - - let countCheck = ExprSyntax( + func checkBound(countName spanCount: ExprSyntax) -> StmtSyntax { + return """ - if \(getCount()) < \(countName) || \(countName) < 0 { - fatalError("bounds check failure when calling unsafe function") - } - """) - res.append(CodeBlockItemSyntax.Item(countCheck)) + if \(spanCount) != \(countExpr) { + fatalError("bounds check failure in \(funcDecl.name): expected \\(\(countExpr)) but got \\(\(spanCount))") + } + """ + } + + func buildBasicBoundsChecks(_ extractedCountArgs: inout Set) throws -> [CodeBlockItemSyntax.Item] { + var res = try base.buildBasicBoundsChecks(&extractedCountArgs) + if let countVar = countExpr.as(DeclReferenceExprSyntax.self) { + let i = try getParameterIndexForDeclRef(signature.parameterClause.parameters, countVar) + if extractedCountArgs.contains(i) { + res.append(CodeBlockItemSyntax.Item(checkBound(countName: makeCount()))) + } else { + // this is the first parameter with this count parameter, nothing to compare against + let count = castIntToTargetType(expr: makeCount(), type: getParam(signature, i).type) + res.append(CodeBlockItemSyntax.Item(try VariableDeclSyntax( + "let \(countVar.baseName) = \(count)"))) + extractedCountArgs.insert(i) + } + } + return res + } + func buildCompoundBoundsChecks() throws -> [CodeBlockItemSyntax.Item] { + var res = try base.buildCompoundBoundsChecks() + + if !countExpr.is(DeclReferenceExprSyntax.self) { + let countName = ExprSyntax("_\(name)Count") + let count: VariableDeclSyntax = try VariableDeclSyntax( + "let \(countName) = \(makeCount())") + res.append(CodeBlockItemSyntax.Item(count)) + res.append(CodeBlockItemSyntax.Item(checkBound(countName: countName))) + } return res } @@ -785,13 +827,6 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds let argExpr = ExprSyntax("\(unwrappedName).baseAddress") assert(args[index] == nil) args[index] = try castPointerToOpaquePointer(unwrapIfNonnullable(argExpr)) - if skipTrivialCount { - if let countVar = countExpr.as(DeclReferenceExprSyntax.self) { - let i = try getParameterIndexForDeclRef(signature.parameterClause.parameters, countVar) - args[i] = castIntToTargetType( - expr: "\(unwrappedName).count", type: getParam(signature, i).type) - } - } let call = try base.buildFunctionCall(args) let ptrRef = unwrapIfNullable("\(name)") @@ -804,18 +839,26 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds } let unwrappedCall = ExprSyntax( """ - unsafe \(ptrRef).\(raw: funcName) { \(unwrappedName) in - return \(call) - } + unsafe \(ptrRef).\(raw: funcName) { \(unwrappedName) in + return \(call) + } """) return unwrappedCall } - func getCount() -> ExprSyntax { + func makeCount() -> ExprSyntax { + let unsafeKw = generateSpan ? "" : "unsafe " if nullable { - return ExprSyntax("\(name)?.\(raw: countLabel) ?? 0") + return ExprSyntax("\(raw: unsafeKw)\(name)?.\(raw: countLabel) ?? 0") + } + return ExprSyntax("\(raw: unsafeKw)\(name).\(raw: countLabel)") + } + + func getCountName() -> TokenSyntax { + if let countVar = countExpr.as(DeclReferenceExprSyntax.self) { + return countVar.baseName } - return ExprSyntax("\(name).\(raw: countLabel)") + return "_\(raw: name)Count" } func peelOptionalType(_ type: TypeSyntax) -> TypeSyntax { @@ -845,15 +888,6 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds func buildFunctionCall(_ argOverrides: [Int: ExprSyntax]) throws -> ExprSyntax { var args = argOverrides - if skipTrivialCount { - assert( - countExpr.is(DeclReferenceExprSyntax.self) || countExpr.is(IntegerLiteralExprSyntax.self)) - if let countVar = countExpr.as(DeclReferenceExprSyntax.self) { - let i = try getParameterIndexForDeclRef(signature.parameterClause.parameters, countVar) - assert(args[i] == nil) - args[i] = castIntToTargetType(expr: getCount(), type: getParam(signature, i).type) - } - } assert(args[index] == nil) if generateSpan { assert(nonescaping) @@ -863,11 +897,11 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds nullArgs[index] = ExprSyntax(NilLiteralExprSyntax(nilKeyword: .keyword(.nil))) return ExprSyntax( """ - { () in return if \(name) == nil { - \(try base.buildFunctionCall(nullArgs)) - } else { - \(unwrappedCall) - } }() + { () in return if \(name) == nil { + \(try base.buildFunctionCall(nullArgs)) + } else { + \(unwrappedCall) + } }() """) } return unwrappedCall @@ -1203,29 +1237,6 @@ func parseMacroParam( } } -func hasTrivialCountVariants(_ parsedArgs: [ParamInfo]) -> Bool { - let countExprs = parsedArgs.compactMap { - switch $0 { - case let c as CountedBy: return c.count - default: return nil - } - } - let trivialCounts = countExprs.filter { - $0.is(DeclReferenceExprSyntax.self) || $0.is(IntegerLiteralExprSyntax.self) - } - // don't generate trivial count variants if there are any non-trivial counts - if trivialCounts.count < countExprs.count { - return false - } - let countVars = trivialCounts.filter { $0.is(DeclReferenceExprSyntax.self) } - let distinctCountVars = Set( - countVars.map { - return $0.as(DeclReferenceExprSyntax.self)!.baseName.text - }) - // don't generate trivial count variants if two count expressions refer to the same parameter - return countVars.count == distinctCountVars.count -} - func checkArgs(_ args: [ParamInfo], _ funcDecl: FunctionDeclSyntax) throws { var argByIndex: [Int: ParamInfo] = [:] var ret: ParamInfo? = nil @@ -1557,20 +1568,18 @@ public struct SwiftifyImportMacro: PeerMacro { } let baseBuilder = FunctionCallBuilder(funcDecl) - let skipTrivialCount = hasTrivialCountVariants(parsedArgs) - let builder: BoundsCheckedThunkBuilder = parsedArgs.reduce( baseBuilder, { (prev, parsedArg) in - parsedArg.getBoundsCheckedThunkBuilder(prev, funcDecl, skipTrivialCount) + parsedArg.getBoundsCheckedThunkBuilder(prev, funcDecl) }) let newSignature = try builder.buildFunctionSignature([:], nil) - let checks = - skipTrivialCount - ? [] as [CodeBlockItemSyntax] - : try builder.buildBoundsChecks().map { e in - CodeBlockItemSyntax(leadingTrivia: "\n", item: e) - } + var eliminatedArgs = Set() + let basicChecks = try builder.buildBasicBoundsChecks(&eliminatedArgs) + let compoundChecks = try builder.buildCompoundBoundsChecks() + let checks = (basicChecks + compoundChecks).map { e in + CodeBlockItemSyntax(leadingTrivia: "\n", item: e) + } let call = CodeBlockItemSyntax( item: CodeBlockItemSyntax.Item( ReturnStmtSyntax( diff --git a/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift b/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift index 208717655e25e..81ce8e34afa95 100644 --- a/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift +++ b/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift @@ -15,7 +15,7 @@ import CountedByLifetimeboundClang // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int32, _ offset: Int32, _ len2: Int32, _ p: inout MutableSpan) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int32, _ offset: Int32, _ p: inout MutableSpan) -> MutableSpan // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -44,7 +44,7 @@ import CountedByLifetimeboundClang // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ len: Int32, _ p: inout MutableSpan) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ p: inout MutableSpan) -> MutableSpan // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -56,7 +56,7 @@ import CountedByLifetimeboundClang @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @inlinable public func callComplexExpr(_ p: inout MutableSpan) { - let _: MutableSpan = complexExpr(73, 37, 42, &p) + let _: MutableSpan = complexExpr(73, 37, &p) } @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -80,7 +80,7 @@ public func callNullable(_ p: inout MutableSpan?) { @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @inlinable public func callShared(_ p: inout MutableSpan) { - let _: MutableSpan = shared(CInt(p.count), &p) + let _: MutableSpan = shared(&p) } @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) diff --git a/test/Interop/C/swiftify-import/counted-by-noescape.swift b/test/Interop/C/swiftify-import/counted-by-noescape.swift index 6cf69df60294c..617dfeb33cefc 100644 --- a/test/Interop/C/swiftify-import/counted-by-noescape.swift +++ b/test/Interop/C/swiftify-import/counted-by-noescape.swift @@ -106,7 +106,7 @@ import CountedByNoEscapeClang // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) // CHECK-NEXT: @lifetime(p1: copy p1) // CHECK-NEXT: @lifetime(p2: copy p2) -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ len: Int32, _ p1: inout MutableSpan, _ p2: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ p1: inout MutableSpan, _ p2: inout MutableSpan) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -165,7 +165,7 @@ public func callReturnPointer() { @lifetime(p2: copy p2) @inlinable public func callShared(_ p: inout MutableSpan, _ p2: inout MutableSpan) { - shared(CInt(p.count), &p, &p2) + shared(&p, &p2) } @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) diff --git a/test/Interop/C/swiftify-import/counted-by.swift b/test/Interop/C/swiftify-import/counted-by.swift index 684f4c15dac95..2b092419b2284 100644 --- a/test/Interop/C/swiftify-import/counted-by.swift +++ b/test/Interop/C/swiftify-import/counted-by.swift @@ -48,7 +48,7 @@ import CountedByClang // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func scalar(_ m: Int32, _ n: Int32, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ len: Int{{.*}}, _ p1: UnsafeMutableBufferPointer, _ p2: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ p1: UnsafeMutableBufferPointer, _ p2: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simple(_ p: UnsafeMutableBufferPointer) @@ -108,7 +108,7 @@ public func callScalar(_ p: UnsafeMutableBufferPointer) { @inlinable public func callShared(_ p: UnsafeMutableBufferPointer, _ p2: UnsafeMutableBufferPointer) { - shared(CInt(p.count), p, p2) + shared(p, p2) } @inlinable @@ -136,4 +136,4 @@ public func callSimpleFlipped(_ p: UnsafeMutableBufferPointer) { @inlinable public func callSwiftAttr(_ p: UnsafeMutableBufferPointer) { swiftAttr(p) -} \ No newline at end of file +} diff --git a/test/Interop/C/swiftify-import/sized-by-lifetimebound.swift b/test/Interop/C/swiftify-import/sized-by-lifetimebound.swift index 9040592898e29..49ab16b36d1b7 100644 --- a/test/Interop/C/swiftify-import/sized-by-lifetimebound.swift +++ b/test/Interop/C/swiftify-import/sized-by-lifetimebound.swift @@ -14,7 +14,7 @@ import SizedByLifetimeboundClang // CHECK: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) // CHECK-NEXT: @lifetime(copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int32, _ offset: Int32, _ len2: Int32, _ p: RawSpan) -> RawSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int32, _ offset: Int32, _ p: RawSpan) -> RawSpan // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -44,7 +44,7 @@ import SizedByLifetimeboundClang // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) // CHECK-NEXT: @lifetime(copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ len: Int32, _ p: RawSpan) -> RawSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ p: RawSpan) -> RawSpan // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -55,7 +55,7 @@ import SizedByLifetimeboundClang @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @inlinable public func callComplexExpr(_ p: RawSpan) { - let _: RawSpan = complexExpr(73, 37, 42, p) + let _: RawSpan = complexExpr(73, 37, p) } @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -79,7 +79,7 @@ public func callNullable(_ p: RawSpan?) { @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @inlinable public func callShared(_ p: RawSpan) { - let _: RawSpan = shared(CInt(p.byteCount), p) + let _: RawSpan = shared(p) } @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) diff --git a/test/Interop/C/swiftify-import/sized-by-noescape.swift b/test/Interop/C/swiftify-import/sized-by-noescape.swift index 3fc7278c113bb..f672a4da1bccd 100644 --- a/test/Interop/C/swiftify-import/sized-by-noescape.swift +++ b/test/Interop/C/swiftify-import/sized-by-noescape.swift @@ -35,7 +35,7 @@ import SizedByNoEscapeClang // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ len: Int{{.*}}, _ p1: RawSpan, _ p2: RawSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ p1: RawSpan, _ p2: RawSpan) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -79,7 +79,7 @@ public func callReturnPointer() { @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @inlinable public func callShared(_ p: RawSpan, _ p2: RawSpan) { - shared(CInt(p.byteCount), p, p2) + shared(p, p2) } @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @@ -92,4 +92,4 @@ public func callSimple(_ p: RawSpan) { @inlinable public func callSwiftAttr(_ p: RawSpan) { swiftAttr(p) -} \ No newline at end of file +} diff --git a/test/Interop/C/swiftify-import/sized-by.swift b/test/Interop/C/swiftify-import/sized-by.swift index 53fcc5ed518b9..1643dd27069c8 100644 --- a/test/Interop/C/swiftify-import/sized-by.swift +++ b/test/Interop/C/swiftify-import/sized-by.swift @@ -29,7 +29,7 @@ import SizedByClang // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableRawBufferPointer // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ len: Int{{.*}}, _ p1: UnsafeMutableRawBufferPointer, _ p2: UnsafeMutableRawBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func shared(_ p1: UnsafeMutableRawBufferPointer, _ p2: UnsafeMutableRawBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simple(_ p: UnsafeMutableRawBufferPointer) @@ -70,7 +70,7 @@ public func callReturnPointer() { @inlinable public func callShared(_ p: UnsafeMutableRawBufferPointer, _ p2: UnsafeMutableRawBufferPointer) { - shared(CInt(p.count), p, p2) + shared(p, p2) } @inlinable diff --git a/test/Macros/SwiftifyImport/CountedBy/Anonymous.swift b/test/Macros/SwiftifyImport/CountedBy/Anonymous.swift index e21181da6243d..165ca31d5a4d2 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Anonymous.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Anonymous.swift @@ -20,24 +20,28 @@ public func myFunc4(_: UnsafeMutablePointer, _ len: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: public func myFunc(_ _myFunc_param0: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(_myFunc_param0.baseAddress!, CInt(exactly: _myFunc_param0.count)!) +// CHECK-NEXT: let _myFunc_param1 = CInt(exactly: unsafe _myFunc_param0.count)! +// CHECK-NEXT: return unsafe myFunc(_myFunc_param0.baseAddress!, _myFunc_param1) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: public func myFunc2(_ _myFunc2_param0: UnsafeBufferPointer, _ _myFunc2_param2: CInt) { -// CHECK-NEXT: return unsafe myFunc2(_myFunc2_param0.baseAddress!, CInt(exactly: _myFunc2_param0.count)!, _myFunc2_param2) +// CHECK-NEXT: let _myFunc2_param1 = CInt(exactly: unsafe _myFunc2_param0.count)! +// CHECK-NEXT: return unsafe myFunc2(_myFunc2_param0.baseAddress!, _myFunc2_param1, _myFunc2_param2) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: public func myFunc3(_ _myFunc3_param0: Span) { -// CHECK-NEXT: return unsafe _myFunc3_param0.withUnsafeBufferPointer { __myFunc3_param0Ptr in -// CHECK-NEXT: return unsafe myFunc3(__myFunc3_param0Ptr.baseAddress!, CInt(exactly: __myFunc3_param0Ptr.count)!) -// CHECK-NEXT: } +// CHECK-NEXT: let _myFunc3_param1 = CInt(exactly: _myFunc3_param0.count)! +// CHECK-NEXT: return unsafe _myFunc3_param0.withUnsafeBufferPointer { __myFunc3_param0Ptr in +// CHECK-NEXT: return unsafe myFunc3(__myFunc3_param0Ptr.baseAddress!, _myFunc3_param1) +// CHECK-NEXT: } // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(_myFunc4_param0: copy _myFunc4_param0) @_disfavoredOverload // CHECK-NEXT: public func myFunc4(_ _myFunc4_param0: inout MutableSpan) { -// CHECK-NEXT: return unsafe _myFunc4_param0.withUnsafeMutableBufferPointer { __myFunc4_param0Ptr in -// CHECK-NEXT: return unsafe myFunc4(__myFunc4_param0Ptr.baseAddress!, CInt(exactly: __myFunc4_param0Ptr.count)!) -// CHECK-NEXT: } +// CHECK-NEXT: let _myFunc4_param1 = CInt(exactly: _myFunc4_param0.count)! +// CHECK-NEXT: return unsafe _myFunc4_param0.withUnsafeMutableBufferPointer { __myFunc4_param0Ptr in +// CHECK-NEXT: return unsafe myFunc4(__myFunc4_param0Ptr.baseAddress!, _myFunc4_param1) +// CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift b/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift index 6543e1b7e7ab1..8bc4018956683 100644 --- a/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift +++ b/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift @@ -8,9 +8,9 @@ func myFunc(_ ptr: UnsafePointer, _ size: CInt, _ count: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer, _ size: CInt, _ count: CInt) { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = size * count -// CHECK-NEXT: if ptr.count < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: let _ptrCount = unsafe ptr.count +// CHECK-NEXT: if _ptrCount != size * count { +// CHECK-NEXT: fatalError("bounds check failure in myFunc: expected \(size * count) but got \(_ptrCount)") // CHECK-NEXT: } // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, size, count) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift b/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift index 884456407fd13..8f0ac6f8d09f1 100644 --- a/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift +++ b/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift @@ -8,5 +8,7 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt, _ ptr2: UnsafePointer // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!, ptr2.baseAddress!, CInt(exactly: ptr2.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: let len2 = CInt(exactly: unsafe ptr2.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, len, ptr2.baseAddress!, len2) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Mutable.swift b/test/Macros/SwiftifyImport/CountedBy/Mutable.swift index a0881ec771a66..bb1b1f615026a 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Mutable.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Mutable.swift @@ -8,5 +8,6 @@ func myFunc(_ ptr: UnsafeMutablePointer, _ len: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeMutableBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, len) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift b/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift index fb10a687fd5b1..eb0327f812768 100644 --- a/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift +++ b/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift @@ -9,7 +9,8 @@ func myFunc(_ ptr: UnsafeMutablePointer, _ len: CInt) { // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: inout MutableSpan) { +// CHECK-NEXT: let len = CInt(exactly: ptr.count)! // CHECK-NEXT: return unsafe ptr.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, len) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift b/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift index 7e8674c5c5034..d75240dafec34 100644 --- a/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift +++ b/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift @@ -28,30 +28,36 @@ func allNamedOther(buf ptr: UnsafePointer, count len: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func ptrNamed(ptr: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe ptrNamed(ptr: ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe ptrNamed(ptr: ptr.baseAddress!, len) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func ptrNamedOther(buf ptr: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe ptrNamedOther(buf: ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe ptrNamedOther(buf: ptr.baseAddress!, len) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func lenNamed(_ ptr: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe lenNamed(ptr.baseAddress!, len: CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe lenNamed(ptr.baseAddress!, len: len) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func lenNamedOther(_ ptr: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe lenNamedOther(ptr.baseAddress!, count: CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe lenNamedOther(ptr.baseAddress!, count: len) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func allNamed(ptr: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe allNamed(ptr: ptr.baseAddress!, len: CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe allNamed(ptr: ptr.baseAddress!, len: len) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func allNamedOther(buf ptr: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe allNamedOther(buf: ptr.baseAddress!, count: CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe allNamedOther(buf: ptr.baseAddress!, count: len) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Nullable.swift b/test/Macros/SwiftifyImport/CountedBy/Nullable.swift index dd22f85051711..240f61ad9a5c8 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Nullable.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Nullable.swift @@ -20,17 +20,19 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer?) { -// CHECK-NEXT: return unsafe myFunc(ptr?.baseAddress, CInt(exactly: ptr?.count ?? 0)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr?.count ?? 0)! +// CHECK-NEXT: return unsafe myFunc(ptr?.baseAddress, len) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @_disfavoredOverload // CHECK-NEXT: func myFunc2(_ ptr: inout MutableSpan?) { +// CHECK-NEXT: let len = CInt(exactly: ptr?.count ?? 0)! // CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe myFunc2(nil, CInt(exactly: ptr?.count ?? 0)!) +// CHECK-NEXT: unsafe myFunc2(nil, len) // CHECK-NEXT: } else { // CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc2(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe myFunc2(_ptrPtr.baseAddress, len) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: }() @@ -38,14 +40,16 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @lifetime(ptr2: copy ptr2) @_disfavoredOverload // CHECK-NEXT: func myFunc3(_ ptr: inout MutableSpan?, _ ptr2: inout MutableSpan?) { +// CHECK-NEXT: let len = CInt(exactly: ptr?.count ?? 0)! +// CHECK-NEXT: let len2 = CInt(exactly: ptr2?.count ?? 0)! // CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr2 == nil { // CHECK-NEXT: { () in // CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe myFunc3(nil, CInt(exactly: ptr?.count ?? 0)!, nil, CInt(exactly: ptr2?.count ?? 0)!) +// CHECK-NEXT: unsafe myFunc3(nil, len, nil, len2) // CHECK-NEXT: } else { // CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!, nil, CInt(exactly: ptr2?.count ?? 0)!) +// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, len, nil, len2) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: }() @@ -53,10 +57,10 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo // CHECK-NEXT: unsafe ptr2!.withUnsafeMutableBufferPointer { _ptr2Ptr in // CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe myFunc3(nil, CInt(exactly: ptr?.count ?? 0)!, _ptr2Ptr.baseAddress, CInt(exactly: _ptr2Ptr.count)!) +// CHECK-NEXT: unsafe myFunc3(nil, len, _ptr2Ptr.baseAddress, len2) // CHECK-NEXT: } else { // CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!, _ptr2Ptr.baseAddress, CInt(exactly: _ptr2Ptr.count)!) +// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, len, _ptr2Ptr.baseAddress, len2) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: }() @@ -66,11 +70,8 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) @_disfavoredOverload -// CHECK-NEXT: func myFunc4(_ ptr: inout MutableSpan?, _ len: CInt) -> MutableSpan? { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = len -// CHECK-NEXT: if ptr?.count ?? 0 < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") -// CHECK-NEXT: } +// CHECK-NEXT: func myFunc4(_ ptr: inout MutableSpan?) -> MutableSpan? { +// CHECK-NEXT: let len = CInt(exactly: ptr?.count ?? 0)! // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime({ () in // CHECK-NEXT: let _resultValue = { () in // CHECK-NEXT: return if ptr == nil { diff --git a/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift b/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift index 0ee665bec16aa..42572608723b3 100644 --- a/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift +++ b/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift @@ -30,12 +30,14 @@ func lifetimeDependentBorrow(_ p: borrowing UnsafePointer, _ len1: CInt, _ // CHECK: @_alwaysEmitIntoClient @lifetime(copy p) @_disfavoredOverload // CHECK-NEXT: func lifetimeDependentCopy(_ p: Span, _ len2: CInt) -> Span { -// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span (_unsafeStart: unsafe p.withUnsafeBufferPointer { _pPtr in -// CHECK-NEXT: return unsafe lifetimeDependentCopy(_pPtr.baseAddress!, CInt(exactly: _pPtr.count)!, len2) -// CHECK-NEXT: }, count: Int(len2)), copying: ()) +// CHECK-NEXT: let len1 = CInt(exactly: p.count)! +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span (_unsafeStart: unsafe p.withUnsafeBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe lifetimeDependentCopy(_pPtr.baseAddress!, len1, len2) +// CHECK-NEXT: }, count: Int(len2)), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(borrow p) @_disfavoredOverload // CHECK-NEXT: func lifetimeDependentBorrow(_ p: borrowing UnsafeBufferPointer, _ len2: CInt) -> Span { -// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span (_unsafeStart: unsafe lifetimeDependentBorrow(p.baseAddress!, CInt(exactly: p.count)!, len2), count: Int(len2)), copying: ()) +// CHECK-NEXT: let len1 = CInt(exactly: unsafe p.count)! +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span (_unsafeStart: unsafe lifetimeDependentBorrow(p.baseAddress!, len1, len2), count: Int(len2)), copying: ()) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift b/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift index 9689f738bef22..a8efdd51e25ab 100644 --- a/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift +++ b/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift @@ -12,10 +12,12 @@ func bar(_ ptr: Swift.UnsafePointer, _ len: Swift.Int) -> () { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func foo(_ ptr: Swift.UnsafeBufferPointer) -> Swift.Void { -// CHECK-NEXT: return unsafe foo(ptr.baseAddress!, ptr.count) +// CHECK-NEXT: let len = unsafe ptr.count +// CHECK-NEXT: return unsafe foo(ptr.baseAddress!, len) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func bar(_ ptr: Swift.UnsafeBufferPointer) -> () { -// CHECK-NEXT: return unsafe bar(ptr.baseAddress!, ptr.count) +// CHECK-NEXT: let len = unsafe ptr.count +// CHECK-NEXT: return unsafe bar(ptr.baseAddress!, len) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Return.swift b/test/Macros/SwiftifyImport/CountedBy/Return.swift index f2925528696ac..dab352b4cc686 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Return.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Return.swift @@ -8,5 +8,6 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) -> CInt { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer) -> CInt { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, len) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SharedCount.swift b/test/Macros/SwiftifyImport/CountedBy/SharedCount.swift index 8e4e7f459b1ed..3821d0e7c660b 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SharedCount.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SharedCount.swift @@ -6,15 +6,70 @@ func myFunc(_ ptr: UnsafePointer, _ ptr2: UnsafePointer, _ len: CInt) { } +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "len"), .countedBy(pointer: .param(2), count: "len * size")) +func myFunc2(_ ptr: UnsafePointer, _ ptr2: UnsafePointer, _ len: CInt, _ size: CInt) { +} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "len"), .countedBy(pointer: .param(2), count: "size"), .countedBy(pointer: .param(3), count: "len * size")) +func myFunc3(_ ptr: UnsafePointer, _ ptr2: UnsafePointer, _ ptr3: UnsafePointer, _ len: CInt, _ size: CInt) { +} + +@_SwiftifyImport(.countedBy(pointer: .param(3), count: "len"), .countedBy(pointer: .param(2), count: "size"), .countedBy(pointer: .param(1), count: "len * size")) +func myFunc4(_ ptr: UnsafePointer, _ ptr2: UnsafePointer, _ ptr3: UnsafePointer, _ len: CInt, _ size: CInt) { +} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "len * size"), .countedBy(pointer: .param(3), count: "len"), .countedBy(pointer: .param(2), count: "size")) +func myFunc5(_ ptr: UnsafePointer, _ ptr2: UnsafePointer, _ ptr3: UnsafePointer, _ len: CInt, _ size: CInt) { +} + // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer, _ len: CInt) { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = len -// CHECK-NEXT: if ptr.count < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") -// CHECK-NEXT: } -// CHECK-NEXT: let _ptr2Count: some BinaryInteger = len -// CHECK-NEXT: if ptr2.count < _ptr2Count || _ptr2Count < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer) { +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: if unsafe ptr2.count != len { +// CHECK-NEXT: fatalError("bounds check failure in myFunc: expected \(len) but got \(unsafe ptr2.count)") // CHECK-NEXT: } // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, ptr2.baseAddress!, len) // CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func myFunc2(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer, _ size: CInt) { +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: let _ptr2Count = unsafe ptr2.count +// CHECK-NEXT: if _ptr2Count != len * size { +// CHECK-NEXT: fatalError("bounds check failure in myFunc2: expected \(len * size) but got \(_ptr2Count)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe myFunc2(ptr.baseAddress!, ptr2.baseAddress!, len, size) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func myFunc3(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer, _ ptr3: UnsafeBufferPointer) { +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr2.count)! +// CHECK-NEXT: let _ptr3Count = unsafe ptr3.count +// CHECK-NEXT: if _ptr3Count != len * size { +// CHECK-NEXT: fatalError("bounds check failure in myFunc3: expected \(len * size) but got \(_ptr3Count)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe myFunc3(ptr.baseAddress!, ptr2.baseAddress!, ptr3.baseAddress!, len, size) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func myFunc4(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer, _ ptr3: UnsafeBufferPointer) { +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr2.count)! +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr3.count)! +// CHECK-NEXT: let _ptrCount = unsafe ptr.count +// CHECK-NEXT: if _ptrCount != len * size { +// CHECK-NEXT: fatalError("bounds check failure in myFunc4: expected \(len * size) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe myFunc4(ptr.baseAddress!, ptr2.baseAddress!, ptr3.baseAddress!, len, size) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func myFunc5(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer, _ ptr3: UnsafeBufferPointer) { +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr2.count)! +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr3.count)! +// CHECK-NEXT: let _ptrCount = unsafe ptr.count +// CHECK-NEXT: if _ptrCount != len * size { +// CHECK-NEXT: fatalError("bounds check failure in myFunc5: expected \(len * size) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe myFunc5(ptr.baseAddress!, ptr2.baseAddress!, ptr3.baseAddress!, len, size) +// CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift b/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift index 66ae52203f0b9..c5727fb0b0e34 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift @@ -8,5 +8,6 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, len) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift b/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift index a0a3b310bf7da..c6f99fa5bad85 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift @@ -9,7 +9,8 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: Span) { +// CHECK-NEXT: let len = CInt(exactly: ptr.count)! // CHECK-NEXT: return unsafe ptr.withUnsafeBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, len) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift b/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift index c9ac1c88d48e9..ac8bc628c427b 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift @@ -9,7 +9,8 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) -> CInt { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: Span) -> CInt { +// CHECK-NEXT: let len = CInt(exactly: ptr.count)! // CHECK-NEXT: return unsafe ptr.withUnsafeBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, len) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift b/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift index dbb06b6ed5f27..1823fa3edca56 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift @@ -10,7 +10,9 @@ func myFunc(_ ptr1: UnsafePointer, _ len1: CInt, _ ptr2: UnsafePointer, _ ptr2: UnsafeBufferPointer) { +// CHECK-NEXT: let len1 = CInt(exactly: ptr1.count)! +// CHECK-NEXT: let len2 = CInt(exactly: unsafe ptr2.count)! // CHECK-NEXT: return unsafe ptr1.withUnsafeBufferPointer { _ptr1Ptr in -// CHECK-NEXT: return unsafe myFunc(_ptr1Ptr.baseAddress!, CInt(exactly: _ptr1Ptr.count)!, ptr2.baseAddress!, CInt(exactly: ptr2.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptr1Ptr.baseAddress!, len1, ptr2.baseAddress!, len2) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift b/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift index e7e8ec6a65423..3e220c1726473 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift @@ -8,5 +8,6 @@ func myFunc(_ ptr: UnsafePointer!, _ len: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, len) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Whitespace.swift b/test/Macros/SwiftifyImport/CountedBy/Whitespace.swift new file mode 100644 index 0000000000000..22fee6820ecb9 --- /dev/null +++ b/test/Macros/SwiftifyImport/CountedBy/Whitespace.swift @@ -0,0 +1,49 @@ +@_SwiftifyImport(.countedBy(pointer: .return, count: "len"), .lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy), .countedBy(pointer: .param(1), count: "len"), .nonescaping(pointer: .param(1)), .countedBy(pointer: .param(3), count: "len2"), .nonescaping(pointer: .param(3))) +func myFunc(_ ptr: UnsafeMutablePointer?, _ len: CInt, _ ptr2: UnsafeMutablePointer?, _ len2: CInt) -> UnsafeMutablePointer? {} + +// REQUIRES: swift_swift_parser + +// RUN: %target-swift-frontend %s -swift-version 5 -module-name main -disable-availability-checking -typecheck -plugin-path %swift-plugin-dir -strict-memory-safety -warnings-as-errors -dump-macro-expansions 2>&1 | %FileCheck --match-full-lines --strict-whitespace %s + +// This test is meant to act as an alarm bell to unintended changes in whitespace + +// CHECK:------------------------------ +// CHECK-NEXT:/// This is an auto-generated wrapper for safer interop +// CHECK-NEXT:@_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) @lifetime(ptr2: copy ptr2) @_disfavoredOverload +// CHECK-NEXT:func myFunc(_ ptr: inout MutableSpan?, _ ptr2: inout MutableSpan?) -> MutableSpan? { +// CHECK-NEXT: let len = CInt(exactly: ptr?.count ?? 0)! +// CHECK-NEXT: let len2 = CInt(exactly: ptr2?.count ?? 0)! +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime({ () in +// CHECK-NEXT: let _resultValue = { () in +// CHECK-NEXT: return if ptr2 == nil { +// CHECK-NEXT: { () in +// CHECK-NEXT: return if ptr == nil { +// CHECK-NEXT: unsafe myFunc(nil, len, nil, len2) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress, len, nil, len2) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr2!.withUnsafeMutableBufferPointer { _ptr2Ptr in +// CHECK-NEXT: return { () in +// CHECK-NEXT: return if ptr == nil { +// CHECK-NEXT: unsafe myFunc(nil, len, _ptr2Ptr.baseAddress, len2) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress, len, _ptr2Ptr.baseAddress, len2) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: if unsafe _resultValue == nil { +// CHECK-NEXT: return nil +// CHECK-NEXT: } else { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableSpan(_unsafeStart: _resultValue!, count: Int(len)), copying: ()) +// CHECK-NEXT: } +// CHECK-NEXT: }(), copying: ()) +// CHECK-NEXT:} +// CHECK-NEXT:------------------------------ diff --git a/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift b/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift index 3a42ff01db42c..5a75578ae7866 100644 --- a/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift +++ b/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift @@ -88,42 +88,42 @@ func myFunc10(_ self: MutableSpanOfInt) -> MutableSpanOfInt { // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) @_disfavoredOverload // CHECK-NEXT: func myFunc6(_ span: Span, _ ptr: RawSpan, _ count: CInt, _ size: CInt) -> Span { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size -// CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: let _ptrCount = ptr.byteCount +// CHECK-NEXT: if _ptrCount != count * size { +// CHECK-NEXT: fatalError("bounds check failure in myFunc6: expected \(count * size) but got \(_ptrCount)") // CHECK-NEXT: } // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc6(SpanOfInt(span), _ptrPtr.baseAddress!, count, size) -// CHECK-NEXT: }), copying: ()) +// CHECK-NEXT: return unsafe myFunc6(SpanOfInt(span), _ptrPtr.baseAddress!, count, size) +// CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) @_disfavoredOverload // CHECK-NEXT: func myFunc7(_ span: Span, _ ptr: RawSpan, _ count: CInt, _ size: CInt) -> Span { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size -// CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: let _ptrCount = ptr.byteCount +// CHECK-NEXT: if _ptrCount != count * size { +// CHECK-NEXT: fatalError("bounds check failure in myFunc7: expected \(count * size) but got \(_ptrCount)") // CHECK-NEXT: } // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc7(SpanOfInt(span), _ptrPtr.baseAddress!, count, size) -// CHECK-NEXT: }), copying: ()) +// CHECK-NEXT: return unsafe myFunc7(SpanOfInt(span), _ptrPtr.baseAddress!, count, size) +// CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) @_disfavoredOverload // CHECK-NEXT: func myFunc8(_ ptr: RawSpan, _ span: Span, _ count: CInt, _ size: CInt) -> Span { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size -// CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: let _ptrCount = ptr.byteCount +// CHECK-NEXT: if _ptrCount != count * size { +// CHECK-NEXT: fatalError("bounds check failure in myFunc8: expected \(count * size) but got \(_ptrCount)") // CHECK-NEXT: } // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc8(_ptrPtr.baseAddress!, SpanOfInt(span), count, size) -// CHECK-NEXT: }), copying: ()) +// CHECK-NEXT: return unsafe myFunc8(_ptrPtr.baseAddress!, SpanOfInt(span), count, size) +// CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) @lifetime(span: copy span) @_disfavoredOverload // CHECK-NEXT: func myFunc9(_ span: inout MutableSpan) -> MutableSpan { // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableSpan(_unsafeCxxSpan: unsafe span.withUnsafeMutableBufferPointer { _spanPtr in -// CHECK-NEXT: return unsafe myFunc9(MutableSpanOfInt(_spanPtr)) -// CHECK-NEXT: }), copying: ()) +// CHECK-NEXT: return unsafe myFunc9(MutableSpanOfInt(_spanPtr)) +// CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy `self`) @lifetime(`self`: copy `self`) @_disfavoredOverload diff --git a/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift b/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift index b11e50781599e..dbf142efcfe87 100644 --- a/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift +++ b/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift @@ -8,5 +8,7 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt, _ ptr2: UnsafeRawPointer, _ s // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer, _ ptr2: UnsafeRawBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!, ptr2.baseAddress!, CInt(exactly: ptr2.count)!) +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: let size2 = CInt(exactly: unsafe ptr2.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, size, ptr2.baseAddress!, size2) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/Mutable.swift b/test/Macros/SwiftifyImport/SizedBy/Mutable.swift index 89f08d8626143..7cb497c206587 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Mutable.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Mutable.swift @@ -8,5 +8,6 @@ func myFunc(_ ptr: UnsafeMutableRawPointer, _ size: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeMutableRawBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, size) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift b/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift index 5314f3f9f5d5d..1e194e9ee9493 100644 --- a/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift +++ b/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift @@ -9,7 +9,8 @@ func myFunc(_ ptr: UnsafeMutableRawPointer, _ size: CInt) { // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: inout MutableRawSpan) { +// CHECK-NEXT: let size = CInt(exactly: ptr.byteCount)! // CHECK-NEXT: return unsafe ptr.withUnsafeMutableBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, size) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/Nullable.swift b/test/Macros/SwiftifyImport/SizedBy/Nullable.swift index 1c476b8ab10cb..337d805b84af9 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Nullable.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Nullable.swift @@ -20,66 +20,67 @@ func myFunc4(_ ptr: UnsafeMutableRawPointer?, _ len: CInt) -> UnsafeMutableRawPo // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer?) { -// CHECK-NEXT: return unsafe myFunc(ptr?.baseAddress, CInt(exactly: ptr?.count ?? 0)!) +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr?.count ?? 0)! +// CHECK-NEXT: return unsafe myFunc(ptr?.baseAddress, size) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @_disfavoredOverload // CHECK-NEXT: func myFunc2(_ ptr: inout MutableRawSpan?) { -// CHECK-NEXT: return { () in +// CHECK-NEXT: let len = CInt(exactly: ptr?.byteCount ?? 0)! +// CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe myFunc2(nil, CInt(exactly: ptr?.byteCount ?? 0)!) -// CHECK-NEXT: } else { -// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc2(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!) -// CHECK-NEXT: } +// CHECK-NEXT: unsafe myFunc2(nil, len) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBytes { _ptrPtr in +// CHECK-NEXT: return unsafe myFunc2(_ptrPtr.baseAddress, len) // CHECK-NEXT: } +// CHECK-NEXT: } // CHECK-NEXT: }() // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @lifetime(ptr2: copy ptr2) @_disfavoredOverload // CHECK-NEXT: func myFunc3(_ ptr: inout MutableRawSpan?, _ ptr2: inout MutableRawSpan?) { -// CHECK-NEXT: return { () in +// CHECK-NEXT: let len = CInt(exactly: ptr?.byteCount ?? 0)! +// CHECK-NEXT: let len2 = CInt(exactly: ptr2?.byteCount ?? 0)! +// CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr2 == nil { -// CHECK-NEXT: { () in -// CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe myFunc3(nil, CInt(exactly: ptr?.byteCount ?? 0)!, nil, CInt(exactly: ptr2?.byteCount ?? 0)!) -// CHECK-NEXT: } else { -// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!, nil, CInt(exactly: ptr2?.byteCount ?? 0)!) -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: }() -// CHECK-NEXT: } else { -// CHECK-NEXT: unsafe ptr2!.withUnsafeMutableBytes { _ptr2Ptr in -// CHECK-NEXT: return { () in -// CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe myFunc3(nil, CInt(exactly: ptr?.byteCount ?? 0)!, _ptr2Ptr.baseAddress, CInt(exactly: _ptr2Ptr.count)!) -// CHECK-NEXT: } else { -// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!, _ptr2Ptr.baseAddress, CInt(exactly: _ptr2Ptr.count)!) -// CHECK-NEXT: } -// CHECK-NEXT: } -// CHECK-NEXT: }() -// CHECK-NEXT: } +// CHECK-NEXT: { () in +// CHECK-NEXT: return if ptr == nil { +// CHECK-NEXT: unsafe myFunc3(nil, len, nil, len2) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBytes { _ptrPtr in +// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, len, nil, len2) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr2!.withUnsafeMutableBytes { _ptr2Ptr in +// CHECK-NEXT: return { () in +// CHECK-NEXT: return if ptr == nil { +// CHECK-NEXT: unsafe myFunc3(nil, len, _ptr2Ptr.baseAddress, len2) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBytes { _ptrPtr in +// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, len, _ptr2Ptr.baseAddress, len2) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() // CHECK-NEXT: } +// CHECK-NEXT: } // CHECK-NEXT: }() // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) @_disfavoredOverload -// CHECK-NEXT: func myFunc4(_ ptr: inout MutableRawSpan?, _ len: CInt) -> MutableRawSpan? { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = len -// CHECK-NEXT: if ptr?.byteCount ?? 0 < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") -// CHECK-NEXT: } +// CHECK-NEXT: func myFunc4(_ ptr: inout MutableRawSpan?) -> MutableRawSpan? { +// CHECK-NEXT: let len = CInt(exactly: ptr?.byteCount ?? 0)! // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime({ () in -// CHECK-NEXT: let _resultValue = { () in +// CHECK-NEXT: let _resultValue = { () in // CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe myFunc4(nil, len) -// CHECK-NEXT: } else { -// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc4(_ptrPtr.baseAddress, len) -// CHECK-NEXT: } +// CHECK-NEXT: unsafe myFunc4(nil, len) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBytes { _ptrPtr in +// CHECK-NEXT: return unsafe myFunc4(_ptrPtr.baseAddress, len) // CHECK-NEXT: } +// CHECK-NEXT: } // CHECK-NEXT: }() // CHECK-NEXT: if unsafe _resultValue == nil { // CHECK-NEXT: return nil diff --git a/test/Macros/SwiftifyImport/SizedBy/Opaque.swift b/test/Macros/SwiftifyImport/SizedBy/Opaque.swift index 1b433f900f2fb..72bf7ba8e7a96 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Opaque.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Opaque.swift @@ -28,42 +28,47 @@ func impNullableSpan(_ ptr: OpaquePointer!, _ size: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func nonnullUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer) { -// CHECK-NEXT: return unsafe nonnullUnsafeRawBufferPointer(OpaquePointer(ptr.baseAddress!), CInt(exactly: ptr.count)!) -// CHECK-NEXT: } +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe nonnullUnsafeRawBufferPointer(OpaquePointer(ptr.baseAddress!), size) // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func nullableUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer?) { -// CHECK-NEXT: return unsafe nullableUnsafeRawBufferPointer(OpaquePointer(ptr?.baseAddress), CInt(exactly: ptr?.count ?? 0)!) +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr?.count ?? 0)! +// CHECK-NEXT: return unsafe nullableUnsafeRawBufferPointer(OpaquePointer(ptr?.baseAddress), size) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func impNullableUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer) { -// CHECK-NEXT: return unsafe impNullableUnsafeRawBufferPointer(OpaquePointer(ptr.baseAddress!), CInt(exactly: ptr.count)!) +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe impNullableUnsafeRawBufferPointer(OpaquePointer(ptr.baseAddress!), size) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func nonnullSpan(_ ptr: RawSpan) { +// CHECK-NEXT: let size = CInt(exactly: ptr.byteCount)! // CHECK-NEXT: return unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe nonnullSpan(OpaquePointer(_ptrPtr.baseAddress!), CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe nonnullSpan(OpaquePointer(_ptrPtr.baseAddress!), size) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func nullableSpan(_ ptr: RawSpan?) { +// CHECK-NEXT: let size = CInt(exactly: ptr?.byteCount ?? 0)! // CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe nullableSpan(nil, CInt(exactly: ptr?.byteCount ?? 0)!) -// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe nullableSpan(nil, size) +// CHECK-NEXT: } else { // CHECK-NEXT: unsafe ptr!.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe nullableSpan(OpaquePointer(_ptrPtr.baseAddress), CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe nullableSpan(OpaquePointer(_ptrPtr.baseAddress), size) // CHECK-NEXT: } -// CHECK-NEXT: } +// CHECK-NEXT: } // CHECK-NEXT: }() // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func impNullableSpan(_ ptr: RawSpan) { +// CHECK-NEXT: let size = CInt(exactly: ptr.byteCount)! // CHECK-NEXT: return unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe impNullableSpan(OpaquePointer(_ptrPtr.baseAddress!), CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe impNullableSpan(OpaquePointer(_ptrPtr.baseAddress!), size) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/PointerReturn.swift b/test/Macros/SwiftifyImport/SizedBy/PointerReturn.swift index 7c7e8cef6e0f3..1e0b000becf95 100644 --- a/test/Macros/SwiftifyImport/SizedBy/PointerReturn.swift +++ b/test/Macros/SwiftifyImport/SizedBy/PointerReturn.swift @@ -39,24 +39,28 @@ func lifetimeDependentBorrowMut(_ p: borrowing UnsafeMutableRawPointer, _ len1: // CHECK: @_alwaysEmitIntoClient @lifetime(copy p) @_disfavoredOverload // CHECK-NEXT: func lifetimeDependentCopy(_ p: RawSpan, _ len2: CInt) -> RawSpan { +// CHECK-NEXT: let len1 = CInt(exactly: p.byteCount)! // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(RawSpan(_unsafeStart: unsafe p.withUnsafeBytes { _pPtr in -// CHECK-NEXT: return unsafe lifetimeDependentCopy(_pPtr.baseAddress!, CInt(exactly: _pPtr.count)!, len2) +// CHECK-NEXT: return unsafe lifetimeDependentCopy(_pPtr.baseAddress!, len1, len2) // CHECK-NEXT: }, byteCount: Int(len2)), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(borrow p) @_disfavoredOverload // CHECK-NEXT: func lifetimeDependentBorrow(_ p: borrowing UnsafeRawBufferPointer, _ len2: CInt) -> RawSpan { -// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(RawSpan(_unsafeStart: unsafe lifetimeDependentBorrow(p.baseAddress!, CInt(exactly: p.count)!, len2), byteCount: Int(len2)), copying: ()) +// CHECK-NEXT: let len1 = CInt(exactly: unsafe p.count)! +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(RawSpan(_unsafeStart: unsafe lifetimeDependentBorrow(p.baseAddress!, len1, len2), byteCount: Int(len2)), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy p) @lifetime(p: copy p) @_disfavoredOverload // CHECK-NEXT: func lifetimeDependentCopyMut(_ p: inout MutableRawSpan, _ len2: CInt) -> MutableRawSpan { +// CHECK-NEXT: let len1 = CInt(exactly: p.byteCount)! // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableRawSpan(_unsafeStart: unsafe p.withUnsafeMutableBytes { _pPtr in -// CHECK-NEXT: return unsafe lifetimeDependentCopyMut(_pPtr.baseAddress!, CInt(exactly: _pPtr.count)!, len2) +// CHECK-NEXT: return unsafe lifetimeDependentCopyMut(_pPtr.baseAddress!, len1, len2) // CHECK-NEXT: }, byteCount: Int(len2)), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(borrow p) @_disfavoredOverload // CHECK-NEXT: func lifetimeDependentBorrowMut(_ p: borrowing UnsafeMutableRawBufferPointer, _ len2: CInt) -> MutableRawSpan { -// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableRawSpan(_unsafeStart: unsafe lifetimeDependentBorrowMut(p.baseAddress!, CInt(exactly: p.count)!, len2), byteCount: Int(len2)), copying: ()) +// CHECK-NEXT: let len1 = CInt(exactly: unsafe p.count)! +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableRawSpan(_unsafeStart: unsafe lifetimeDependentBorrowMut(p.baseAddress!, len1, len2), byteCount: Int(len2)), copying: ()) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/Return.swift b/test/Macros/SwiftifyImport/SizedBy/Return.swift index b4e0f4f386986..346a1835f77a8 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Return.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Return.swift @@ -8,5 +8,6 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) -> CInt { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer) -> CInt { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, size) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift b/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift index f69093bfeed54..524e901b8ae5f 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift @@ -7,14 +7,10 @@ func myFunc(_ ptr: UnsafeRawPointer, _ ptr2: UnsafeRawPointer, _ size: CInt) { } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload -// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer, _ ptr2: UnsafeRawBufferPointer, _ size: CInt) { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = size -// CHECK-NEXT: if ptr.count < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") -// CHECK-NEXT: } -// CHECK-NEXT: let _ptr2Count: some BinaryInteger = size -// CHECK-NEXT: if ptr2.count < _ptr2Count || _ptr2Count < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer, _ ptr2: UnsafeRawBufferPointer) { +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: if unsafe ptr2.count != size { +// CHECK-NEXT: fatalError("bounds check failure in myFunc: expected \(size) but got \(unsafe ptr2.count)") // CHECK-NEXT: } // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, ptr2.baseAddress!, size) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift index 4d9c122d136c4..bb53ff31997c5 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift @@ -9,7 +9,8 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: RawSpan) { +// CHECK-NEXT: let size = CInt(exactly: ptr.byteCount)! // CHECK-NEXT: return unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, size) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift index 1142f1c403627..418290c939ab4 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift @@ -9,7 +9,8 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) -> CInt { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: RawSpan) -> CInt { +// CHECK-NEXT: let size = CInt(exactly: ptr.byteCount)! // CHECK-NEXT: return unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, size) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift b/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift index 6bbe4b5fedab3..580ec4298bc52 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift @@ -8,5 +8,6 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let size = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, size) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift b/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift index 2e26ad824acf0..76c9bb716007e 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift @@ -8,9 +8,9 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt, _ count: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer, _ size: CInt, _ count: CInt) { -// CHECK-NEXT: let _ptrCount: some BinaryInteger = size * count -// CHECK-NEXT: if ptr.count < _ptrCount || _ptrCount < 0 { -// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: let _ptrCount = unsafe ptr.count +// CHECK-NEXT: if _ptrCount != size * count { +// CHECK-NEXT: fatalError("bounds check failure in myFunc: expected \(size * count) but got \(_ptrCount)") // CHECK-NEXT: } // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, size, count) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift b/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift index 0d4a797852d2f..15ba4616a586f 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift @@ -8,5 +8,6 @@ func myFunc(_ ptr: UnsafeRawPointer!, _ len: CInt) { // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: let len = CInt(exactly: unsafe ptr.count)! +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, len) // CHECK-NEXT: } From 085553a2668d1e3e2b695189b55fd4d42a72dc86 Mon Sep 17 00:00:00 2001 From: "Henrik G. Olsson" Date: Fri, 23 May 2025 21:13:50 -0700 Subject: [PATCH 2/2] [Swiftify] Add tests that verify __counted_by with constant count (NFC) We used to not emit bounds checks for things like `__counted_by(4)`, but we do now - likely fixed by https://github.com/swiftlang/swift/pull/81585 These regression tests verify that behaviour. rdar://151038254 --- .../Inputs/counted-by-lifetimebound.h | 2 + .../counted-by-lifetimebound.swift | 12 + .../CountedBy/ConstantCount.swift | 236 ++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 test/Macros/SwiftifyImport/CountedBy/ConstantCount.swift diff --git a/test/Interop/C/swiftify-import/Inputs/counted-by-lifetimebound.h b/test/Interop/C/swiftify-import/Inputs/counted-by-lifetimebound.h index d5f9f6059c9f5..574bcccd0d57f 100644 --- a/test/Interop/C/swiftify-import/Inputs/counted-by-lifetimebound.h +++ b/test/Interop/C/swiftify-import/Inputs/counted-by-lifetimebound.h @@ -19,3 +19,5 @@ typedef struct foo opaque_t; opaque_t * __counted_by(len) opaque(int len, int len2, opaque_t * __counted_by(len2) __lifetimebound p); int * __counted_by(len) noncountedLifetime(int len, int * __lifetimebound p); + +int * __counted_by(13) _Nullable constant(int * __counted_by(13) __lifetimebound _Nullable p); diff --git a/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift b/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift index 81ce8e34afa95..2c46096b5edee 100644 --- a/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift +++ b/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift @@ -17,6 +17,12 @@ import CountedByLifetimeboundClang // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int32, _ offset: Int32, _ p: inout MutableSpan) -> MutableSpan +// CHECK: /// This is an auto-generated wrapper for safer interop +// CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +// CHECK-NEXT: @lifetime(copy p) +// CHECK-NEXT: @lifetime(p: copy p) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func constant(_ p: inout MutableSpan?) -> MutableSpan? + // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) // CHECK-NEXT: @lifetime(borrow p) @@ -94,3 +100,9 @@ public func callSimple(_ p: inout MutableSpan) { public func callNoncountedLifetime(_ p: UnsafeMutablePointer) { let _: MutableSpan = noncountedLifetime(73, p) } + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@inlinable +public func callConstant(_ p: inout MutableSpan?) { + let _: MutableSpan? = constant(&p) +} diff --git a/test/Macros/SwiftifyImport/CountedBy/ConstantCount.swift b/test/Macros/SwiftifyImport/CountedBy/ConstantCount.swift new file mode 100644 index 0000000000000..cef50c0c5d467 --- /dev/null +++ b/test/Macros/SwiftifyImport/CountedBy/ConstantCount.swift @@ -0,0 +1,236 @@ +// REQUIRES: swift_swift_parser + +// RUN: %target-swift-frontend %s -swift-version 5 -module-name main -disable-availability-checking -typecheck -plugin-path %swift-plugin-dir -strict-memory-safety -warnings-as-errors -dump-macro-expansions 2>&1 | %FileCheck --match-full-lines %s + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37")) +func plain(_ ptr: UnsafePointer) {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37")) +func opt(_ ptr: UnsafePointer?) {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37")) +func mut(_ ptr: UnsafeMutablePointer) {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37")) +func mutOpt(_ ptr: UnsafeMutablePointer?) {} + + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37"), .nonescaping(pointer: .param(1))) +func noescape(_ ptr: UnsafePointer) {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37"), .nonescaping(pointer: .param(1))) +func noescapeOpt(_ ptr: UnsafePointer?) {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37"), .nonescaping(pointer: .param(1))) +func noescapeMut(_ ptr: UnsafeMutablePointer) {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37"), .nonescaping(pointer: .param(1))) +func noescapeMutOpt(_ ptr: UnsafeMutablePointer?) {} + + +@_SwiftifyImport(.countedBy(pointer: .return, count: "37")) +func plainReturn() -> UnsafePointer {} + +@_SwiftifyImport(.countedBy(pointer: .return, count: "37")) +func optReturn() -> UnsafePointer? {} + +@_SwiftifyImport(.countedBy(pointer: .return, count: "37")) +func mutReturn() -> UnsafeMutablePointer {} + +@_SwiftifyImport(.countedBy(pointer: .return, count: "37")) +func mutOptReturn() -> UnsafeMutablePointer? {} + + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37"), .lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy)) +func noescape(_ ptr: UnsafePointer) -> UnsafePointer {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37"), .lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy)) +func noescapeOpt(_ ptr: UnsafePointer?) -> UnsafePointer? {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37"), .lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy)) +func noescapeMut(_ ptr: UnsafeMutablePointer) -> UnsafeMutablePointer {} + +@_SwiftifyImport(.countedBy(pointer: .param(1), count: "37"), .lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy)) +func noescapeMutOpt(_ ptr: UnsafeMutablePointer?) -> UnsafeMutablePointer? {} + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func plain(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: let _ptrCount = unsafe ptr.count +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in plain: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe plain(ptr.baseAddress!) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func opt(_ ptr: UnsafeBufferPointer?) { +// CHECK-NEXT: let _ptrCount = unsafe ptr?.count ?? 0 +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in opt: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe opt(ptr?.baseAddress) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func mut(_ ptr: UnsafeMutableBufferPointer) { +// CHECK-NEXT: let _ptrCount = unsafe ptr.count +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in mut: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe mut(ptr.baseAddress!) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func mutOpt(_ ptr: UnsafeMutableBufferPointer?) { +// CHECK-NEXT: let _ptrCount = unsafe ptr?.count ?? 0 +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in mutOpt: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe mutOpt(ptr?.baseAddress) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func noescape(_ ptr: Span) { +// CHECK-NEXT: let _ptrCount = ptr.count +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in noescape: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe ptr.withUnsafeBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe noescape(_ptrPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @lifetime(copy ptr) @_disfavoredOverload +// CHECK-NEXT: func noescape(_ ptr: Span) -> UnsafePointer { +// CHECK-NEXT: let _ptrCount = ptr.count +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in noescape: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe ptr.withUnsafeBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe noescape(_ptrPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func noescapeOpt(_ ptr: Span?) { +// CHECK-NEXT: let _ptrCount = ptr?.count ?? 0 +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in noescapeOpt: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return { () in +// CHECK-NEXT: return if ptr == nil { +// CHECK-NEXT: unsafe noescapeOpt(nil) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe noescapeOpt(_ptrPtr.baseAddress) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @lifetime(copy ptr) @_disfavoredOverload +// CHECK-NEXT: func noescapeOpt(_ ptr: Span?) -> UnsafePointer? { +// CHECK-NEXT: let _ptrCount = ptr?.count ?? 0 +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in noescapeOpt: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return { () in +// CHECK-NEXT: return if ptr == nil { +// CHECK-NEXT: unsafe noescapeOpt(nil) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe noescapeOpt(_ptrPtr.baseAddress) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @_disfavoredOverload +// CHECK-NEXT: func noescapeMut(_ ptr: inout MutableSpan) { +// CHECK-NEXT: let _ptrCount = ptr.count +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in noescapeMut: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe ptr.withUnsafeMutableBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe noescapeMut(_ptrPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) @_disfavoredOverload +// CHECK-NEXT: func noescapeMut(_ ptr: inout MutableSpan) -> UnsafeMutablePointer { +// CHECK-NEXT: let _ptrCount = ptr.count +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in noescapeMut: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe ptr.withUnsafeMutableBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe noescapeMut(_ptrPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @_disfavoredOverload +// CHECK-NEXT: func noescapeMutOpt(_ ptr: inout MutableSpan?) { +// CHECK-NEXT: let _ptrCount = ptr?.count ?? 0 +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in noescapeMutOpt: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return { () in +// CHECK-NEXT: return if ptr == nil { +// CHECK-NEXT: unsafe noescapeMutOpt(nil) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe noescapeMutOpt(_ptrPtr.baseAddress) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) @_disfavoredOverload +// CHECK-NEXT: func noescapeMutOpt(_ ptr: inout MutableSpan?) -> UnsafeMutablePointer? { +// CHECK-NEXT: let _ptrCount = ptr?.count ?? 0 +// CHECK-NEXT: if _ptrCount != 37 { +// CHECK-NEXT: fatalError("bounds check failure in noescapeMutOpt: expected \(37) but got \(_ptrCount)") +// CHECK-NEXT: } +// CHECK-NEXT: return { () in +// CHECK-NEXT: return if ptr == nil { +// CHECK-NEXT: unsafe noescapeMutOpt(nil) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe noescapeMutOpt(_ptrPtr.baseAddress) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func plainReturn() -> UnsafeBufferPointer { +// CHECK-NEXT: return unsafe UnsafeBufferPointer (start: unsafe plainReturn(), count: Int(37)) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func optReturn() -> UnsafeBufferPointer? { +// CHECK-NEXT: return unsafe { () in +// CHECK-NEXT: let _resultValue = unsafe optReturn() +// CHECK-NEXT: if unsafe _resultValue == nil { +// CHECK-NEXT: return nil +// CHECK-NEXT: } else { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(UnsafeBufferPointer(start: _resultValue!, count: Int(37)), copying: ()) +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func mutReturn() -> UnsafeMutableBufferPointer { +// CHECK-NEXT: return unsafe UnsafeMutableBufferPointer (start: unsafe mutReturn(), count: Int(37)) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: func mutOptReturn() -> UnsafeMutableBufferPointer? { +// CHECK-NEXT: return unsafe { () in +// CHECK-NEXT: let _resultValue = unsafe mutOptReturn() +// CHECK-NEXT: if unsafe _resultValue == nil { +// CHECK-NEXT: return nil +// CHECK-NEXT: } else { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(UnsafeMutableBufferPointer(start: _resultValue!, count: Int(37)), copying: ()) +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: }