diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index b1dd8f644f9cc..8942556abce0a 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -9201,9 +9201,10 @@ void ClangImporter::Implementation::swiftify(FuncDecl *MappedDecl) { paramHasLifetimeInfo = true; } if (clangParam->hasAttr()) { - printer.printLifetimeboundReturn( - index, !paramHasBoundsInfo && - swiftParamTy->isEscapable()); + // If this parameter has bounds info we will tranform it into a Span, + // so then it will no longer be Escapable. + bool willBeEscapable = swiftParamTy->isEscapable() && !paramHasBoundsInfo; + printer.printLifetimeboundReturn(index, willBeEscapable); paramHasLifetimeInfo = true; returnHasLifetimeInfo = true; } diff --git a/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift b/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift index b9f7504bf5010..5be714860742a 100644 --- a/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift +++ b/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift @@ -40,24 +40,15 @@ protocol ParamInfo: CustomStringConvertible { var dependencies: [LifetimeDependence] { get set } func getBoundsCheckedThunkBuilder( - _ base: BoundsCheckedThunkBuilder, _ funcDecl: FunctionDeclSyntax, - _ skipTrivialCount: Bool + _ base: BoundsCheckedThunkBuilder, _ funcDecl: FunctionDeclSyntax ) -> BoundsCheckedThunkBuilder } -func getParamName(_ param: FunctionParameterSyntax, _ paramIndex: Int) -> TokenSyntax { - let name = param.secondName ?? param.firstName - if name.trimmed.text == "_" { - return "_param\(raw: paramIndex)" - } - return name -} - func tryGetParamName(_ funcDecl: FunctionDeclSyntax, _ expr: SwiftifyExpr) -> TokenSyntax? { switch expr { case .param(let i): let funcParam = getParam(funcDecl, i - 1) - return getParamName(funcParam, i - 1) + return funcParam.name case .`self`: return .keyword(.self) default: return nil @@ -88,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 @@ -125,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 @@ -388,11 +377,18 @@ 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, Bool) + -> FunctionSignatureSyntax } func getParam(_ signature: FunctionSignatureSyntax, _ paramIndex: Int) -> FunctionParameterSyntax { @@ -415,24 +411,22 @@ 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 [] } func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws - -> (FunctionSignatureSyntax, Bool) + -> FunctionSignatureSyntax { var newParams = base.signature.parameterClause.parameters.enumerated().filter { let type = argTypes[$0.offset] // filter out deleted parameters, i.e. ones where argTypes[i] _contains_ nil return type == nil || type! != nil }.map { (i: Int, e: FunctionParameterSyntax) in - let param = e.with(\.type, (argTypes[i] ?? e.type)!) - let name = param.secondName ?? param.firstName - if name.trimmed.text == "_" { - return param.with(\.secondName, getParamName(param, i)) - } - return param + e.with(\.type, (argTypes[i] ?? e.type)!) } if let last = newParams.popLast() { newParams.append(last.with(\.trailingComma, nil)) @@ -443,16 +437,14 @@ struct FunctionCallBuilder: BoundsCheckedThunkBuilder { if returnType != nil { sig = sig.with(\.returnClause!.type, returnType!) } - return (sig, (argTypes.count == 0 && returnType != nil)) + return sig } func buildFunctionCall(_ pointerArgs: [Int: ExprSyntax]) throws -> ExprSyntax { let functionRef = DeclReferenceExprSyntax(baseName: base.name) let args: [ExprSyntax] = base.signature.parameterClause.parameters.enumerated() .map { (i: Int, param: FunctionParameterSyntax) in - let name = getParamName(param, i) - let declref = DeclReferenceExprSyntax(baseName: name) - return pointerArgs[i] ?? ExprSyntax(declref) + return pointerArgs[i] ?? ExprSyntax("\(param.name)") } let labels: [TokenSyntax?] = base.signature.parameterClause.parameters.map { param in let firstName = param.firstName.trimmed @@ -468,7 +460,8 @@ struct FunctionCallBuilder: BoundsCheckedThunkBuilder { comma = .commaToken() } let colon: TokenSyntax? = label != nil ? .colonToken() : nil - return LabeledExprSyntax(label: label, colon: colon, expression: arg, trailingComma: comma) + // The compiler emits warnings if you unnecessarily escape labels in function calls + return LabeledExprSyntax(label: label?.withoutBackticks, colon: colon, expression: arg, trailingComma: comma) } let call = ExprSyntax( FunctionCallExprSyntax( @@ -481,19 +474,22 @@ 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 - -> (FunctionSignatureSyntax, Bool) + -> FunctionSignatureSyntax { var types = argTypes types[index] = try newType @@ -510,7 +506,7 @@ struct CxxSpanThunkBuilder: SpanBoundsThunkBuilder, ParamBoundsThunkBuilder { args[index] = ExprSyntax("\(raw: typeName)(\(raw: name))") return try base.buildFunctionCall(args) } else { - let unwrappedName = TokenSyntax("_\(name)Ptr") + let unwrappedName = TokenSyntax("_\(name.withoutBackticks)Ptr") args[index] = ExprSyntax("\(raw: typeName)(\(unwrappedName))") let call = try base.buildFunctionCall(args) @@ -518,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 } @@ -529,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 @@ -538,12 +534,15 @@ 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 - -> (FunctionSignatureSyntax, Bool) + -> FunctionSignatureSyntax { assert(returnType == nil) return try base.buildFunctionSignature(argTypes, newType) @@ -565,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 { @@ -663,14 +668,14 @@ extension ParamBoundsThunkBuilder { } var name: TokenSyntax { - getParamName(param, index) + param.name } } 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] @@ -683,14 +688,17 @@ struct CountedOrSizedReturnPointerThunkBuilder: PointerBoundsThunkBuilder { } func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws - -> (FunctionSignatureSyntax, Bool) + -> FunctionSignatureSyntax { assert(returnType == nil) 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 { @@ -735,42 +743,60 @@ 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 } func buildFunctionSignature(_ argTypes: [Int: TypeSyntax?], _ returnType: TypeSyntax?) throws - -> (FunctionSignatureSyntax, Bool) + -> FunctionSignatureSyntax { 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 } @@ -796,20 +822,13 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds } func buildUnwrapCall(_ argOverrides: [Int: ExprSyntax]) throws -> ExprSyntax { - let unwrappedName = TokenSyntax("_\(name)Ptr") + let unwrappedName = TokenSyntax("_\(name.withoutBackticks)Ptr").escapeIfNeeded var args = argOverrides 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(ExprSyntax(DeclReferenceExprSyntax(baseName: name))) + let ptrRef = unwrapIfNullable("\(name)") let funcName = switch (isSizedBy, isMutablePointerType(oldType)) { @@ -820,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("\(name).\(raw: countLabel)") + return ExprSyntax("\(raw: unsafeKw)\(name).\(raw: countLabel)") + } + + func getCountName() -> TokenSyntax { + if let countVar = countExpr.as(DeclReferenceExprSyntax.self) { + return countVar.baseName + } + return "_\(raw: name)Count" } func peelOptionalType(_ type: TypeSyntax) -> TypeSyntax { @@ -861,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) @@ -879,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 @@ -1004,7 +1022,7 @@ func parseSwiftifyExpr(_ expr: ExprSyntax) throws -> SwiftifyExpr { } func parseCountedByEnum( - _ enumConstructorExpr: FunctionCallExprSyntax, _ signature: FunctionSignatureSyntax + _ enumConstructorExpr: FunctionCallExprSyntax, _ signature: FunctionSignatureSyntax, _ rewriter: CountExprRewriter ) throws -> ParamInfo { let argumentList = enumConstructorExpr.arguments let pointerExprArg = try getArgumentByName(argumentList, "pointer") @@ -1015,7 +1033,8 @@ func parseCountedByEnum( "expected string literal for 'count' parameter, got \(countExprArg)", node: countExprArg) } let unwrappedCountExpr = ExprSyntax(stringLiteral: countExprStringLit.representedLiteralValue!) - if let countVar = unwrappedCountExpr.as(DeclReferenceExprSyntax.self) { + let rewrittenCountExpr = rewriter.visit(unwrappedCountExpr) + if let countVar = rewrittenCountExpr.as(DeclReferenceExprSyntax.self) { // Perform this lookup here so we can override the position to point to the string literal // instead of line 1, column 1 do { @@ -1025,11 +1044,11 @@ func parseCountedByEnum( } } return CountedBy( - pointerIndex: pointerExpr, count: unwrappedCountExpr, sizedBy: false, + pointerIndex: pointerExpr, count: rewrittenCountExpr, sizedBy: false, nonescaping: false, dependencies: [], original: ExprSyntax(enumConstructorExpr)) } -func parseSizedByEnum(_ enumConstructorExpr: FunctionCallExprSyntax) throws -> ParamInfo { +func parseSizedByEnum(_ enumConstructorExpr: FunctionCallExprSyntax, _ rewriter: CountExprRewriter) throws -> ParamInfo { let argumentList = enumConstructorExpr.arguments let pointerExprArg = try getArgumentByName(argumentList, "pointer") let pointerExpr: SwiftifyExpr = try parseSwiftifyExpr(pointerExprArg) @@ -1039,8 +1058,9 @@ func parseSizedByEnum(_ enumConstructorExpr: FunctionCallExprSyntax) throws -> P "expected string literal for 'size' parameter, got \(sizeExprArg)", node: sizeExprArg) } let unwrappedCountExpr = ExprSyntax(stringLiteral: sizeExprStringLit.representedLiteralValue!) + let rewrittenCountExpr = rewriter.visit(unwrappedCountExpr) return CountedBy( - pointerIndex: pointerExpr, count: unwrappedCountExpr, sizedBy: true, nonescaping: false, + pointerIndex: pointerExpr, count: rewrittenCountExpr, sizedBy: true, nonescaping: false, dependencies: [], original: ExprSyntax(enumConstructorExpr)) } @@ -1177,7 +1197,7 @@ func parseCxxSpansInSignature( } func parseMacroParam( - _ paramAST: LabeledExprSyntax, _ signature: FunctionSignatureSyntax, + _ paramAST: LabeledExprSyntax, _ signature: FunctionSignatureSyntax, _ rewriter: CountExprRewriter, nonescapingPointers: inout Set, lifetimeDependencies: inout [SwiftifyExpr: [LifetimeDependence]] ) throws -> ParamInfo? { @@ -1188,8 +1208,8 @@ func parseMacroParam( } let enumName = try parseEnumName(paramExpr) switch enumName { - case "countedBy": return try parseCountedByEnum(enumConstructorExpr, signature) - case "sizedBy": return try parseSizedByEnum(enumConstructorExpr) + case "countedBy": return try parseCountedByEnum(enumConstructorExpr, signature, rewriter) + case "sizedBy": return try parseSizedByEnum(enumConstructorExpr, rewriter) case "endedBy": return try parseEndedByEnum(enumConstructorExpr) case "nonescaping": let index = try parseNonEscaping(enumConstructorExpr) @@ -1217,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 @@ -1306,6 +1303,18 @@ func setLifetimeDependencies( } } +func isInout(_ type: TypeSyntax) -> Bool { + guard let attr = type.as(AttributedTypeSyntax.self) else { + return false + } + return attr.specifiers.contains(where: { e in + guard let simpleSpec = e.as(SimpleTypeSpecifierSyntax.self) else { + return false + } + return simpleSpec.specifier.text == "inout" + }) +} + func getReturnLifetimeAttribute( _ funcDecl: FunctionDeclSyntax, _ dependencies: [SwiftifyExpr: [LifetimeDependence]] @@ -1318,10 +1327,14 @@ func getReturnLifetimeAttribute( for dependence in returnDependencies { switch dependence.type { case .borrow: - args.append( - LabeledExprSyntax( - expression: - DeclReferenceExprSyntax(baseName: TokenSyntax("borrow")))) + if isInout(getSwiftifyExprType(funcDecl, dependence.dependsOn)) { + args.append(LabeledExprSyntax(expression: ExprSyntax("&"))) + } else { + args.append( + LabeledExprSyntax( + expression: + DeclReferenceExprSyntax(baseName: TokenSyntax("borrow")))) + } case .copy: args.append( LabeledExprSyntax( @@ -1422,7 +1435,7 @@ func paramLifetimeAttributes( if !isMutableSpan(param.type) { continue } - let paramName = param.secondName ?? param.firstName + let paramName = param.name if containsLifetimeAttr(oldAttrs, for: paramName) { continue } @@ -1440,6 +1453,61 @@ func paramLifetimeAttributes( return defaultLifetimes } +class CountExprRewriter: SyntaxRewriter { + public let nameMap: [String: String] + + init(_ renamedParams: [String: String]) { + nameMap = renamedParams + } + + override func visit(_ node: DeclReferenceExprSyntax) -> ExprSyntax { + if let newName = nameMap[node.baseName.trimmed.text] { + return ExprSyntax( + node.with( + \.baseName, + .identifier( + newName, leadingTrivia: node.baseName.leadingTrivia, + trailingTrivia: node.baseName.trailingTrivia))) + } + return escapeIfNeeded(node) + } +} + +func renameParameterNamesIfNeeded(_ funcDecl: FunctionDeclSyntax) -> (FunctionDeclSyntax, CountExprRewriter) { + let params = funcDecl.signature.parameterClause.parameters + let funcName = funcDecl.name.withoutBackticks.trimmed.text + let shouldRename = params.contains(where: { param in + let paramName = param.name.trimmed.text + return paramName == "_" || paramName == funcName || "`\(paramName)`" == funcName + }) + var renamedParams: [String: String] = [:] + let newParams = params.enumerated().map { (i, param) in + let secondName = if shouldRename { + // Including funcName in name prevents clash with function name. + // Renaming all parameters if one requires renaming guarantees that other parameters don't clash with the renamed one. + TokenSyntax("_\(raw: funcName)_param\(raw: i)") + } else { + param.secondName?.escapeIfNeeded + } + let firstName = param.firstName.escapeIfNeeded + let newParam = param.with(\.secondName, secondName) + .with(\.firstName, firstName) + let newName = newParam.name.trimmed.text + let oldName = param.name.trimmed.text + if newName != oldName { + renamedParams[oldName] = newName + } + return newParam + } + let newDecl = if renamedParams.count > 0 { + funcDecl.with(\.signature.parameterClause.parameters, FunctionParameterListSyntax(newParams)) + } else { + // Keeps source locations for diagnostics, in the common case where nothing was renamed + funcDecl + } + return (newDecl, CountExprRewriter(renamedParams)) +} + /// A macro that adds safe(r) wrappers for functions with unsafe pointer types. /// Depends on bounds, escapability and lifetime information for each pointer. /// Intended to map to C attributes like __counted_by, __ended_by and __no_escape, @@ -1453,9 +1521,10 @@ public struct SwiftifyImportMacro: PeerMacro { in context: some MacroExpansionContext ) throws -> [DeclSyntax] { do { - guard let funcDecl = declaration.as(FunctionDeclSyntax.self) else { + guard let origFuncDecl = declaration.as(FunctionDeclSyntax.self) else { throw DiagnosticError("@_SwiftifyImport only works on functions", node: declaration) } + let (funcDecl, rewriter) = renameParameterNamesIfNeeded(origFuncDecl) let argumentList = node.arguments!.as(LabeledExprListSyntax.self)! var arguments = [LabeledExprSyntax](argumentList) @@ -1471,7 +1540,7 @@ public struct SwiftifyImportMacro: PeerMacro { var lifetimeDependencies: [SwiftifyExpr: [LifetimeDependence]] = [:] var parsedArgs = try arguments.compactMap { try parseMacroParam( - $0, funcDecl.signature, nonescapingPointers: &nonescapingPointers, + $0, funcDecl.signature, rewriter, nonescapingPointers: &nonescapingPointers, lifetimeDependencies: &lifetimeDependencies) } parsedArgs.append(contentsOf: try parseCxxSpansInSignature(funcDecl.signature, typeMappings)) @@ -1499,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, onlyReturnTypeChanged) = try builder.buildFunctionSignature([:], nil) - let checks = - skipTrivialCount - ? [] as [CodeBlockItemSyntax] - : try builder.buildBoundsChecks().map { e in - CodeBlockItemSyntax(leadingTrivia: "\n", item: e) - } + let newSignature = try builder.buildFunctionSignature([:], nil) + 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( @@ -1524,13 +1591,12 @@ public struct SwiftifyImportMacro: PeerMacro { returnLifetimeAttribute + paramLifetimeAttributes(newSignature, funcDecl.attributes) let availabilityAttr = try getAvailability(newSignature, spanAvailability) let disfavoredOverload: [AttributeListSyntax.Element] = - (onlyReturnTypeChanged - ? [ - .attribute( - AttributeSyntax( - atSign: .atSignToken(), - attributeName: IdentifierTypeSyntax(name: "_disfavoredOverload"))) - ] : []) + [ + .attribute( + AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: "_disfavoredOverload"))) + ] let newFunc = funcDecl .with(\.signature, newSignature) @@ -1611,3 +1677,33 @@ extension TypeSyntaxProtocol { return false } } + +extension FunctionParameterSyntax { + var name: TokenSyntax { + self.secondName ?? self.firstName + } +} + +extension TokenSyntax { + public var withoutBackticks: TokenSyntax { + return .identifier(self.identifier!.name) + } + + public var escapeIfNeeded: TokenSyntax { + var parser = Parser("let \(self)") + let decl = DeclSyntax.parse(from: &parser) + if !decl.hasError { + return self + } else { + return self.copyTrivia(to: "`\(raw: self.trimmed.text)`") + } + } + + public func copyTrivia(to other: TokenSyntax) -> TokenSyntax { + return .identifier(other.text, leadingTrivia: self.leadingTrivia, trailingTrivia: self.trailingTrivia) + } +} + +func escapeIfNeeded(_ identifier: DeclReferenceExprSyntax) -> ExprSyntax { + return "\(identifier.baseName.escapeIfNeeded)" +} diff --git a/stdlib/public/Cxx/CxxSpan.swift b/stdlib/public/Cxx/CxxSpan.swift index 55d5f0dba0b70..1da23193b0cb2 100644 --- a/stdlib/public/Cxx/CxxSpan.swift +++ b/stdlib/public/Cxx/CxxSpan.swift @@ -88,7 +88,7 @@ extension CxxSpan { unsafe self.init(unsafeMutableBufferPointer.baseAddress!, Size(unsafeMutableBufferPointer.count)) } - @available(SwiftStdlib 6.2, *) + @available(SwiftCompatibilitySpan 5.0, *) @inlinable @unsafe public init(_ span: Span) { @@ -99,7 +99,7 @@ extension CxxSpan { } } -@available(SwiftStdlib 6.2, *) +@available(SwiftCompatibilitySpan 5.0, *) extension Span { @_alwaysEmitIntoClient @unsafe @@ -115,7 +115,7 @@ extension Span { } } -@available(SwiftStdlib 6.2, *) +@available(SwiftCompatibilitySpan 5.0, *) extension MutableSpan { @_alwaysEmitIntoClient @unsafe @@ -151,7 +151,7 @@ extension CxxMutableSpan { unsafe self.init(unsafeMutableBufferPointer.baseAddress!, Size(unsafeMutableBufferPointer.count)) } - @available(SwiftStdlib 6.2, *) + @available(SwiftCompatibilitySpan 5.0, *) @inlinable @unsafe public init(_ span: consuming MutableSpan) { 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 2bfce825fda85..2a7ac8c530f8b 100644 --- a/test/Interop/C/swiftify-import/Inputs/counted-by-lifetimebound.h +++ b/test/Interop/C/swiftify-import/Inputs/counted-by-lifetimebound.h @@ -16,3 +16,5 @@ int * __counted_by(len) _Nonnull nonnull(int len, int len2, int * __counted_by(l int * __counted_by(len) _Nullable nullable(int len, int len2, int * __counted_by(len2) __lifetimebound _Nullable 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/Inputs/counted-by-noescape.h b/test/Interop/C/swiftify-import/Inputs/counted-by-noescape.h index d7d849d3cdd5c..73a48ec5b220f 100644 --- a/test/Interop/C/swiftify-import/Inputs/counted-by-noescape.h +++ b/test/Interop/C/swiftify-import/Inputs/counted-by-noescape.h @@ -24,3 +24,58 @@ int * __counted_by(len) __noescape returnPointer(int len); int * __counted_by(len1) returnLifetimeBound(int len1, int len2, int * __counted_by(len2) p __lifetimebound); void anonymous(int len, int * __counted_by(len) _Nullable __noescape); + +void keyword(int len, int * __counted_by(len) _Nullable func __noescape, + int extension, + int init, + int open, + int var, + int is, + int as, + int in, + int guard, + int where +); + +void pointerName(int len, int * __counted_by(len) _Nullable pointerName __noescape); + +void lenName(int lenName, int size, int * __counted_by(lenName * size) _Nullable p __noescape); + +void func(int len, int * __counted_by(len) _Nullable func __noescape); + +void *funcRenameKeyword(int len, int * __counted_by(len) _Nullable func __noescape, + int extension __lifetimebound, + int init, + int open, + int var, + int is, + int as, + int in, + int guard, + int where) __attribute__((swift_name("funcRenamed(len:func:extension:init:open:var:is:as:in:guard:where:)"))); + +void *funcRenameKeywordAnonymous(int len, int * __counted_by(len) _Nullable __noescape, + int __lifetimebound, + int, + int, + int, + int, + int, + int, + int, + int) __attribute__((swift_name("funcRenamedAnon(len:func:extension:init:open:var:is:as:in:guard:where:)"))); + +void funcRenameClash(int len, int * __counted_by(len) _Nullable func __noescape, int where) + __attribute__((swift_name("clash(len:func:clash:)"))); + +void funcRenameClashKeyword(int len, int * __counted_by(len) _Nullable func __noescape, int where) + __attribute__((swift_name("open(len:func:open:)"))); + +void funcRenameClashAnonymous(int len, int * __counted_by(len) _Nullable func __noescape, int) + __attribute__((swift_name("clash2(len:func:clash2:)"))); + +void funcRenameClashKeywordAnonymous(int len, int * __counted_by(len) _Nullable func __noescape, int) + __attribute__((swift_name("in(len:func:in:)"))); + +typedef struct actor_ *actor; +actor _Nonnull keywordType(int len, actor * __counted_by(len) __noescape p, actor _Nonnull p2); diff --git a/test/Interop/C/swiftify-import/comments.swift b/test/Interop/C/swiftify-import/comments.swift index fbb87b26e3823..2dcd0e19e203e 100644 --- a/test/Interop/C/swiftify-import/comments.swift +++ b/test/Interop/C/swiftify-import/comments.swift @@ -27,7 +27,7 @@ // CHECK-NEXT:func blockDocComment(_ len: Int32, _ p: UnsafeMutablePointer!) // CHECK-NEXT:/// This is an auto-generated wrapper for safer interop -// CHECK-NEXT:@_alwaysEmitIntoClient public func blockComment(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT:@_alwaysEmitIntoClient @_disfavoredOverload public func blockComment(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT:/** // CHECK-NEXT: * block doc comment @@ -37,10 +37,10 @@ // CHECK-NEXT: * @param p some integers to play with // CHECK-NEXT: */ // CHECK-NEXT:/// This is an auto-generated wrapper for safer interop -// CHECK-NEXT:@_alwaysEmitIntoClient public func blockDocComment(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT:@_alwaysEmitIntoClient @_disfavoredOverload public func blockDocComment(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT:/// This is an auto-generated wrapper for safer interop -// CHECK-NEXT:@_alwaysEmitIntoClient public func lineComment(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT:@_alwaysEmitIntoClient @_disfavoredOverload public func lineComment(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT:/// line doc comment // CHECK-NEXT:/// @@ -49,4 +49,4 @@ // CHECK-NEXT:/// @param len the buffer length // CHECK-NEXT:/// @param p the buffer // CHECK-NEXT:/// This is an auto-generated wrapper for safer interop -// CHECK-NEXT:@_alwaysEmitIntoClient public func lineDocComment(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT:@_alwaysEmitIntoClient @_disfavoredOverload public func lineDocComment(_ p: UnsafeMutableBufferPointer) diff --git a/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift b/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift index 2307998931356..2c46096b5edee 100644 --- a/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift +++ b/test/Interop/C/swiftify-import/counted-by-lifetimebound.swift @@ -15,7 +15,13 @@ 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 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: /// 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, *) @@ -26,37 +32,37 @@ 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 public func nonnull(_ len: Int32, _ p: inout MutableSpan) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nonnull(_ len: 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, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ len: Int32, _ p: inout MutableSpan) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullUnspecified(_ len: 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, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullable(_ len: Int32, _ p: inout MutableSpan?) -> MutableSpan? +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullable(_ len: 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, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient 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, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ len: Int32, _ p: inout MutableSpan) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simple(_ len: Int32, _ p: inout MutableSpan) -> MutableSpan @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 +86,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, *) @@ -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/Interop/C/swiftify-import/counted-by-noescape.swift b/test/Interop/C/swiftify-import/counted-by-noescape.swift index d230834b58679..617dfeb33cefc 100644 --- a/test/Interop/C/swiftify-import/counted-by-noescape.swift +++ b/test/Interop/C/swiftify-import/counted-by-noescape.swift @@ -13,34 +13,91 @@ import CountedByNoEscapeClang // 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(_param1: copy _param1) -// CHECK-NEXT: @_alwaysEmitIntoClient public func anonymous(_ _param1: inout MutableSpan?) +// CHECK-NEXT: @lifetime(_anonymous_param1: copy _anonymous_param1) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func anonymous(_ _anonymous_param1: 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, *) +// CHECK-NEXT: @lifetime(func: copy func) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func clash(func: inout MutableSpan?, clash where: Int32) + +// 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(_clash2_param1: copy _clash2_param1) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func clash2(func _clash2_param1: inout MutableSpan?, clash2 _clash2_param2: Int32) + +// 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(p: copy p) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int32, _ offset: Int32, _ p: 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, *) +// CHECK-NEXT: @lifetime(_func_param1: copy _func_param1) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func `func`(_ _func_param1: 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, *) +// CHECK-NEXT: @lifetime(borrow extension) +// CHECK-NEXT: @lifetime(func: copy func) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcRenamed(func: inout MutableSpan?, extension: Int32, init: Int32, open: Int32, var: Int32, is: Int32, as: Int32, in: Int32, guard: Int32, where: Int32) -> UnsafeMutableRawPointer! + +// 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 _funcRenamedAnon_param2) +// CHECK-NEXT: @lifetime(_funcRenamedAnon_param1: copy _funcRenamedAnon_param1) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcRenamedAnon(func _funcRenamedAnon_param1: inout MutableSpan?, extension _funcRenamedAnon_param2: Int32, init _funcRenamedAnon_param3: Int32, open _funcRenamedAnon_param4: Int32, var _funcRenamedAnon_param5: Int32, is _funcRenamedAnon_param6: Int32, as _funcRenamedAnon_param7: Int32, in _funcRenamedAnon_param8: Int32, guard _funcRenamedAnon_param9: Int32, where _funcRenamedAnon_param10: Int32) -> UnsafeMutableRawPointer! + +// 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(_in_param1: copy _in_param1) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func `in`(func _in_param1: inout MutableSpan?, in _in_param2: Int32) + +// 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(func: copy func) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func keyword(_ func: inout MutableSpan?, _ extension: Int32, _ init: Int32, _ open: Int32, _ var: Int32, _ is: Int32, _ as: Int32, _ in: Int32, _ guard: Int32, _ where: Int32) // 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(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func complexExpr(_ len: Int32, _ offset: Int32, _ p: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func keywordType(_ p: inout MutableSpan, _ p2: actor) -> actor + +// 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(_lenName_param2: copy _lenName_param2) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func lenName(_ _lenName_param0: Int32, _ _lenName_param1: Int32, _ _lenName_param2: 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, *) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nonnull(_ p: 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, *) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullUnspecified(_ p: 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, *) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullable(_ p: inout MutableSpan?) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullable(_ p: 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, *) +// CHECK-NEXT: @lifetime(func: copy func) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func open(func: inout MutableSpan?, open where: Int32) + +// 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(_pointerName_param1: copy _pointerName_param1) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func pointerName(_ _pointerName_param1: 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, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func returnLifetimeBound(_ len1: Int32, _ p: inout MutableSpan) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnLifetimeBound(_ len1: Int32, _ p: inout MutableSpan) -> MutableSpan // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int32) -> UnsafeMutableBufferPointer @@ -49,17 +106,17 @@ 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 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, *) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ p: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simple(_ p: 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, *) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func swiftAttr(_ p: inout MutableSpan) @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @lifetime(p: copy p) @@ -108,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, *) @@ -125,8 +182,65 @@ public func callSwiftAttr(_ p: inout MutableSpan) { swiftAttr(&p) } +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @lifetime(p: copy p) @inlinable public func callAnonymous(_ p: inout MutableSpan?) { anonymous(&p) } + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@lifetime(p: copy p) +@inlinable +public func callKeyword(_ p: inout MutableSpan?) { + keyword(&p, 1, 2, 3, 4, 5, 6, 7, 8, 9) +} + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@lifetime(p: copy p) +@inlinable +public func callFunc(_ p: inout MutableSpan?) { + `func`(&p) +} + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@lifetime(p: copy p) +@inlinable +public func callFuncRenameKeyword(_ p: inout MutableSpan?) { + funcRenamed(func: &p, extension: 1, init: 2, open: 3, var: 4, is: 5, as: 6, in: 7, guard: 8, where: 9) +} + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@lifetime(p: copy p) +@inlinable +public func callFuncRenameClash(_ p: inout MutableSpan?) { + clash(func: &p, clash: 1) +} + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@lifetime(p: copy p) +@inlinable +public func callFuncRenameClashKeyword(_ p: inout MutableSpan?) { + `open`(func: &p, open: 1) +} + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@lifetime(p: copy p) +@inlinable +public func callFuncRenameClashKeywordAnon(_ p: inout MutableSpan?) { + `in`(func: &p, in: 1) +} + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@lifetime(p: copy p) +@inlinable +public func callPointerName(_ p: inout MutableSpan?) { + pointerName(&p) +} + +@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +@lifetime(p: copy p) +@inlinable +public func callLenName(_ p: inout MutableSpan?) { + lenName(CInt(p?.count ?? 0), 2, &p) +} diff --git a/test/Interop/C/swiftify-import/counted-by.swift b/test/Interop/C/swiftify-import/counted-by.swift index 6623b7ccf9650..2b092419b2284 100644 --- a/test/Interop/C/swiftify-import/counted-by.swift +++ b/test/Interop/C/swiftify-import/counted-by.swift @@ -12,58 +12,58 @@ import CountedByClang // CHECK: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func bitshift(_ m: Int32, _ n: Int32, _ o: Int32, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func bitshift(_ m: Int32, _ n: Int32, _ o: Int32, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func bitwise(_ m: Int32, _ n: Int32, _ o: Int32, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func bitwise(_ m: Int32, _ n: Int32, _ o: Int32, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func constFloatCastedToInt(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func constFloatCastedToInt(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func constInt(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func constInt(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nonnull(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullUnspecified(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullable(_ p: UnsafeMutableBufferPointer?) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullable(_ p: UnsafeMutableBufferPointer?) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func offByOne(_ len: Int32, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func offByOne(_ len: Int32, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func offBySome(_ len: Int32, _ offset: Int32, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func offBySome(_ len: Int32, _ offset: Int32, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableBufferPointer // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func scalar(_ m: Int32, _ n: Int32, _ p: UnsafeMutableBufferPointer) +// 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 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 public func simple(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simple(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func simpleFlipped(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simpleFlipped(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func sizeofParam(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func sizeofParam(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func sizeofType(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func sizeofType(_ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func swiftAttr(_ p: UnsafeMutableBufferPointer) @inlinable public func callComplexExpr(_ 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 @@ -116,6 +116,18 @@ public func callSimple(_ p: UnsafeMutableBufferPointer) { simple(p) } +@inlinable +public func callSimpleIndirectOriginal(_ p: UnsafeMutablePointer) { + let f = simple + f(13, p) +} + +@inlinable +public func callSimpleIndirectOverload(_ p: UnsafeMutableBufferPointer) { + let f: (UnsafeMutableBufferPointer) -> Void = simple + f(p) +} + @inlinable public func callSimpleFlipped(_ p: UnsafeMutableBufferPointer) { simpleFlipped(p) diff --git a/test/Interop/C/swiftify-import/sized-by-lifetimebound.swift b/test/Interop/C/swiftify-import/sized-by-lifetimebound.swift index 8447f17211f47..49ab16b36d1b7 100644 --- a/test/Interop/C/swiftify-import/sized-by-lifetimebound.swift +++ b/test/Interop/C/swiftify-import/sized-by-lifetimebound.swift @@ -14,12 +14,12 @@ 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 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, *) // CHECK-NEXT: @lifetime(copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ len: Int32, _ p: RawSpan) -> RawSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nonnull(_ len: 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, *) @@ -29,33 +29,33 @@ 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 public func nullUnspecified(_ len: Int32, _ p: RawSpan) -> RawSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullUnspecified(_ len: 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, *) // CHECK-NEXT: @lifetime(copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullable(_ len: Int32, _ p: RawSpan?) -> RawSpan? +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullable(_ len: 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, *) // CHECK-NEXT: @lifetime(copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func opaque(_ len: Int32, _ p: RawSpan) -> RawSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func opaque(_ len: 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, *) // CHECK-NEXT: @lifetime(copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient 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, *) // CHECK-NEXT: @lifetime(copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ len: Int32, _ p: RawSpan) -> RawSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simple(_ len: Int32, _ p: RawSpan) -> RawSpan @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 e8372becc5321..f672a4da1bccd 100644 --- a/test/Interop/C/swiftify-import/sized-by-noescape.swift +++ b/test/Interop/C/swiftify-import/sized-by-noescape.swift @@ -12,38 +12,38 @@ import SizedByNoEscapeClang // 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: @_alwaysEmitIntoClient public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: RawSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: 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, *) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: RawSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nonnull(_ p: 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, *) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: RawSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullUnspecified(_ p: 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, *) -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullable(_ p: RawSpan?) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullable(_ p: 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, *) -// CHECK-NEXT: @_alwaysEmitIntoClient public func opaque(_ p: RawSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func opaque(_ p: RawSpan) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeRawBufferPointer // 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 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, *) -// CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ p: RawSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simple(_ p: 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, *) -// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: RawSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func swiftAttr(_ p: RawSpan) @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @inlinable @@ -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 316fc0e6c791f..1643dd27069c8 100644 --- a/test/Interop/C/swiftify-import/sized-by.swift +++ b/test/Interop/C/swiftify-import/sized-by.swift @@ -11,31 +11,31 @@ import SizedByClang // CHECK: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: UnsafeMutableRawBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: UnsafeMutableRawBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: UnsafeMutableRawBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nonnull(_ p: UnsafeMutableRawBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: UnsafeMutableRawBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullUnspecified(_ p: UnsafeMutableRawBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func nullable(_ p: UnsafeMutableRawBufferPointer?) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func nullable(_ p: UnsafeMutableRawBufferPointer?) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func opaque(_ p: UnsafeRawBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func opaque(_ p: UnsafeRawBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableRawBufferPointer // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient 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 public func simple(_ p: UnsafeMutableRawBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func simple(_ p: UnsafeMutableRawBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: UnsafeMutableRawBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func swiftAttr(_ p: UnsafeMutableRawBufferPointer) @inlinable public func callComplexExpr(_ 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/Interop/Cxx/stdlib/Inputs/std-span.h b/test/Interop/Cxx/stdlib/Inputs/std-span.h index b02c869d88cf7..d49773165ccaf 100644 --- a/test/Interop/Cxx/stdlib/Inputs/std-span.h +++ b/test/Interop/Cxx/stdlib/Inputs/std-span.h @@ -170,4 +170,7 @@ struct SpanWithoutTypeAlias { void foo(std::span s [[clang::noescape]]); }; +inline void func(ConstSpanOfInt copy [[clang::noescape]]) {} +inline void mutableKeyword(SpanOfInt copy [[clang::noescape]]) {} + #endif // TEST_INTEROP_CXX_STDLIB_INPUTS_STD_SPAN_H diff --git a/test/Interop/Cxx/stdlib/std-span-interface.swift b/test/Interop/Cxx/stdlib/std-span-interface.swift index 5b8704e891c45..436c9fd1070a8 100644 --- a/test/Interop/Cxx/stdlib/std-span-interface.swift +++ b/test/Interop/Cxx/stdlib/std-span-interface.swift @@ -2,7 +2,11 @@ // RUN: %target-swift-ide-test -plugin-path %swift-plugin-dir -I %S/Inputs -enable-experimental-feature SafeInteropWrappers -print-module -module-to-print=StdSpan -source-filename=x -enable-experimental-cxx-interop -Xcc -std=c++20 -module-cache-path %t > %t/interface.swift // RUN: %FileCheck %s < %t/interface.swift +// Make sure we trigger typechecking and SIL diagnostics +// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -I %S/Inputs -enable-experimental-feature SafeInteropWrappers -enable-experimental-feature LifetimeDependence -cxx-interoperability-mode=default -strict-memory-safety -warnings-as-errors -Xcc -std=c++20 %s + // REQUIRES: swift_feature_SafeInteropWrappers +// REQUIRES: swift_feature_LifetimeDependence // FIXME swift-ci linux tests do not support std::span // UNSUPPORTED: OS=linux-gnu @@ -25,7 +29,7 @@ import CxxStdlib // CHECK-NEXT: init() // 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 public mutating func methodWithSafeWrapper(_ s: Span) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func methodWithSafeWrapper(_ s: Span) // CHECK-NEXT: mutating func methodWithSafeWrapper(_ s: ConstSpanOfInt) // CHECK-NEXT: } // CHECK: struct SpanWithoutTypeAlias { @@ -37,68 +41,71 @@ import CxxStdlib // CHECK-NEXT: mutating func bar() -> std.{{.*}}span<__cxxConst, _C{{.*}}_{{.*}}> // 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 public mutating func foo(_ s: Span) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func foo(_ s: Span) // CHECK-NEXT: mutating func foo(_ s: std.{{.*}}span<__cxxConst, _C{{.*}}_{{.*}}>) // CHECK-NEXT: } // 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(s: copy s) -// CHECK-NEXT: @_alwaysEmitIntoClient public func FuncWithMutableSafeWrapper(_ s: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func FuncWithMutableSafeWrapper(_ s: 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, *) // CHECK-NEXT: @lifetime(copy s) // CHECK-NEXT: @lifetime(s: copy s) -// CHECK-NEXT: @_alwaysEmitIntoClient public func FuncWithMutableSafeWrapper2(_ s: inout MutableSpan) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func FuncWithMutableSafeWrapper2(_ s: 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 v) +// CHECK-NEXT: @lifetime(&v) // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func FuncWithMutableSafeWrapper3(_ v: inout VecOfInt) -> 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(copy p) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper1(_ p: inout MutableSpan) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper1(_ 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 v) +// CHECK-NEXT: @lifetime(&v) // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper2(_ v: inout VecOfInt, _ len: Int32) -> 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(s: copy s) -// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper3(_ s: inout MutableSpan, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper3(_ s: inout MutableSpan, _ p: UnsafeMutableBufferPointer) // 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(s: copy s) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper4(_ s: inout MutableSpan, _ p: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper4(_ s: inout MutableSpan, _ p: 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, *) // CHECK-NEXT: @lifetime(p: copy p) -// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper5(_ s: SpanOfInt, _ p: inout MutableSpan) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper5(_ s: SpanOfInt, _ p: inout MutableSpan) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper6(_ s: SpanOfInt, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper6(_ s: SpanOfInt, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper7(_ p: UnsafeMutableBufferPointer) -> SpanOfInt - +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper7(_ p: UnsafeMutableBufferPointer) -> SpanOfInt // 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: @_alwaysEmitIntoClient public func funcWithSafeWrapper(_ s: Span) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func `func`(_ copy: Span) + +// 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 funcWithSafeWrapper(_ s: Span) // 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 s) -// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper2(_ s: Span) -> Span +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcWithSafeWrapper2(_ s: Span) -> Span // 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, *) @@ -108,7 +115,7 @@ import CxxStdlib // 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 public func mixedFuncWithSafeWrapper1(_ p: Span) -> Span +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper1(_ p: Span) -> Span // 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, *) @@ -117,18 +124,121 @@ import CxxStdlib // 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 public func mixedFuncWithSafeWrapper3(_ s: Span, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper3(_ s: Span, _ p: UnsafeMutableBufferPointer) // 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 public func mixedFuncWithSafeWrapper4(_ s: Span, _ p: Span) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper4(_ s: Span, _ p: Span) // 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 public func mixedFuncWithSafeWrapper5(_ s: ConstSpanOfInt, _ p: Span) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper5(_ s: ConstSpanOfInt, _ p: Span) + +// CHECK-NEXT: /// This is an auto-generated wrapper for safer interop +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper6(_ s: ConstSpanOfInt, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper6(_ s: ConstSpanOfInt, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper7(_ p: UnsafeBufferPointer) -> ConstSpanOfInt // CHECK-NEXT: /// This is an auto-generated wrapper for safer interop -// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper7(_ p: UnsafeBufferPointer) -> ConstSpanOfInt +// CHECK-NEXT: @available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +// CHECK-NEXT: @lifetime(copy: copy copy) +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mutableKeyword(_ copy: inout MutableSpan) + +func callMethodWithSafeWrapper(_ x: inout X, s: Span) { + x.methodWithSafeWrapper(s) +} + +func callFooBar(_ x: inout SpanWithoutTypeAlias, _ s: ConstSpanOfInt) { + let _: Span = x.bar() + unsafe x.foo(s) +} + +@lifetime(span: copy span) +func callFuncWithMutableSafeWrapper(_ span: inout MutableSpan, ) { + FuncWithMutableSafeWrapper(&span) +} + +@lifetime(span: copy span) +func callFuncWithMutableSafeWrapper2(_ span: inout MutableSpan, ) { + let _: MutableSpan = FuncWithMutableSafeWrapper2(&span) +} + +@lifetime(span: copy span) +func callMixedFuncWithMutableSafeWrapper1(_ span: inout MutableSpan, ) { + let _: MutableSpan = MixedFuncWithMutableSafeWrapper1(&span) +} + +func MixedFuncWithMutableSafeWrapper2(_ v: VecOfInt) { + var v2 = v + let _ = MixedFuncWithMutableSafeWrapper2(&v2, 37) +} + +@lifetime(span: copy span) +func callMixedFuncWithMutableSafeWrapper3(_ span: inout MutableSpan, _ p: UnsafeMutableBufferPointer) { + unsafe MixedFuncWithMutableSafeWrapper3(&span, p) +} + +@lifetime(span1: copy span2) +@lifetime(span2: copy span2) +func callMixedFuncWithMutableSafeWrapper4(_ span1: inout MutableSpan, _ span2: inout MutableSpan) { + MixedFuncWithMutableSafeWrapper4(&span1, &span2) +} + +@lifetime(span: copy span) +func callMixedFuncWithMutableSafeWrapper5(_ span: inout MutableSpan, _ s: SpanOfInt) { + unsafe MixedFuncWithMutableSafeWrapper5(s, &span) +} + +func callMixedFuncWithMutableSafeWrapper6(_ s: SpanOfInt, _ p: UnsafeMutableBufferPointer) { + unsafe MixedFuncWithMutableSafeWrapper6(s, p) +} + +func callMixedFuncWithMutableSafeWrapper7(_ p: UnsafeMutableBufferPointer) { + let _ = unsafe MixedFuncWithMutableSafeWrapper7(p) +} + +func callFuncWithSafeWrapper(_ s: Span) { + funcWithSafeWrapper(s) +} + +func callFuncWithSafeWrapper2(_ s: Span) { + let _ = funcWithSafeWrapper2(s) +} + +func callFuncWithSafeWrapper3(_ v: borrowing VecOfInt) { + let _: Span = funcWithSafeWrapper3(v) +} + +func callMixedFuncWithSafeWrapper1(_ s: Span) { + let _: Span = mixedFuncWithSafeWrapper1(s) +} + +func callMixedFuncWithSafeWrapper2(_ v: borrowing VecOfInt) { + let _: Span = mixedFuncWithSafeWrapper2(v, 73) +} + +func callMixedFuncWithSafeWrapper3(_ s: Span, _ p: UnsafeMutableBufferPointer) { + unsafe mixedFuncWithSafeWrapper3(s, p) +} + +func callMixedFuncWithSafeWrapper4(_ s: Span, _ s2: Span) { + mixedFuncWithSafeWrapper4(s, s2) +} + +func callMixedFuncWithSafeWrapper5(_ s: ConstSpanOfInt, _ s2: Span) { + unsafe mixedFuncWithSafeWrapper5(s, s2) +} + +func callMixedFuncWithSafeWrapper6(_ s: ConstSpanOfInt, _ p: UnsafeMutableBufferPointer) { + unsafe mixedFuncWithSafeWrapper6(s, p) +} + +func callMixedFuncWithSafeWrapper7(_ p: UnsafeBufferPointer) { + let _: ConstSpanOfInt = unsafe mixedFuncWithSafeWrapper7(p) +} + +@lifetime(span: copy span) +func callMutableKeyword(_ span: inout MutableSpan) { + mutableKeyword(&span) +} diff --git a/test/Interop/ObjC/swiftify-import/objc-no-swiftify.swift b/test/Interop/ObjC/swiftify-import/objc-no-swiftify.swift index 36994897f0314..5c918bc4bec5c 100644 --- a/test/Interop/ObjC/swiftify-import/objc-no-swiftify.swift +++ b/test/Interop/ObjC/swiftify-import/objc-no-swiftify.swift @@ -7,8 +7,8 @@ import NoSwiftifyClang -// CHECK-NOT: @_alwaysEmitIntoClient public func callAutoreleaseParam -// CHECK-NOT: @_alwaysEmitIntoClient public func callAutoreleaseReturn +// CHECK-NOT: @_alwaysEmitIntoClient @_disfavoredOverload public func callAutoreleaseParam +// CHECK-NOT: @_alwaysEmitIntoClient @_disfavoredOverload public func callAutoreleaseReturn public func callAutoreleaseParam(_ p: UnsafeMutableBufferPointer) { // expected-error@+2{{missing argument for parameter #2 in call}} diff --git a/test/Macros/SwiftifyImport/CountedBy/Anonymous.swift b/test/Macros/SwiftifyImport/CountedBy/Anonymous.swift index 8ee47af046761..165ca31d5a4d2 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Anonymous.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Anonymous.swift @@ -18,26 +18,30 @@ public func myFunc3(_: UnsafePointer, _ len: CInt) { public func myFunc4(_: UnsafeMutablePointer, _ len: CInt) { } -// CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: public func myFunc(_ _param0: UnsafeBufferPointer) { -// CHECK-NEXT: return unsafe myFunc(_param0.baseAddress!, CInt(exactly: _param0.count)!) +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: public func myFunc(_ _myFunc_param0: UnsafeBufferPointer) { +// 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 -// CHECK-NEXT: public func myFunc2(_ p: UnsafeBufferPointer, _ _param2: CInt) { -// CHECK-NEXT: return unsafe myFunc2(p.baseAddress!, CInt(exactly: p.count)!, _param2) +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: public func myFunc2(_ _myFunc2_param0: UnsafeBufferPointer, _ _myFunc2_param2: CInt) { +// 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 -// CHECK-NEXT: public func myFunc3(_ _param0: Span) { -// CHECK-NEXT: return unsafe _param0.withUnsafeBufferPointer { __param0Ptr in -// CHECK-NEXT: return unsafe myFunc3(__param0Ptr.baseAddress!, CInt(exactly: __param0Ptr.count)!) +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: public func myFunc3(_ _myFunc3_param0: Span) { +// 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(_param0: copy _param0) -// CHECK-NEXT: public func myFunc4(_ _param0: inout MutableSpan) { -// CHECK-NEXT: return unsafe _param0.withUnsafeMutableBufferPointer { __param0Ptr in -// CHECK-NEXT: return unsafe myFunc4(__param0Ptr.baseAddress!, CInt(exactly: __param0Ptr.count)!) +// CHECK: @_alwaysEmitIntoClient @lifetime(_myFunc4_param0: copy _myFunc4_param0) @_disfavoredOverload +// CHECK-NEXT: public func myFunc4(_ _myFunc4_param0: inout MutableSpan) { +// 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: } \ No newline at end of file +// CHECK-NEXT: } 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: } diff --git a/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift b/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift index 92fe4889bdad1..8bc4018956683 100644 --- a/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift +++ b/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift @@ -6,12 +6,11 @@ func myFunc(_ ptr: UnsafePointer, _ size: CInt, _ count: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 6ad7bf0cc7824..8f0ac6f8d09f1 100644 --- a/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift +++ b/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift @@ -6,7 +6,9 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt, _ ptr2: UnsafePointer, _ len2: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 1df1df1329115..bb1b1f615026a 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Mutable.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Mutable.swift @@ -6,8 +6,8 @@ func myFunc(_ ptr: UnsafeMutablePointer, _ len: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 62d4612f10fbc..eb0327f812768 100644 --- a/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift +++ b/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift @@ -7,9 +7,10 @@ func myFunc(_ ptr: UnsafeMutablePointer, _ len: CInt) { } -// CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) +// CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: inout MutableSpan) { -// CHECK-NEXT: return unsafe ptr.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: let len = CInt(exactly: ptr.count)! +// CHECK-NEXT: return unsafe ptr.withUnsafeMutableBufferPointer { _ptrPtr in +// 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 6e450b8afa124..d75240dafec34 100644 --- a/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift +++ b/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift @@ -26,33 +26,38 @@ func allNamed(ptr: UnsafePointer, len: CInt) { func allNamedOther(buf ptr: UnsafePointer, count len: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 +// 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 +// 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 +// 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 +// 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 +// 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 4a1a078d40f54..240f61ad9a5c8 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Nullable.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Nullable.swift @@ -18,34 +18,38 @@ func myFunc3(_ ptr: UnsafeMutablePointer?, _ len: CInt, _ ptr2: UnsafeMuta func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePointer? { } -// CHECK: @_alwaysEmitIntoClient +// 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) +// 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: }() // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @lifetime(ptr2: copy ptr2) +// 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: }() @@ -65,12 +69,9 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo // CHECK-NEXT: }() // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) -// 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: @_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) @_disfavoredOverload +// 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 260486de4e785..42572608723b3 100644 --- a/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift +++ b/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift @@ -28,15 +28,16 @@ func lifetimeDependentBorrow(_ p: borrowing UnsafePointer, _ len1: CInt, _ // CHECK-NEXT: func nonEscaping(_ len: CInt) -> UnsafeBufferPointer { // CHECK-NEXT: return unsafe UnsafeBufferPointer (start: unsafe nonEscaping(len), count: Int(len)) -// CHECK: @_alwaysEmitIntoClient @lifetime(copy p) +// 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) +// 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 3a7139e92f133..a8efdd51e25ab 100644 --- a/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift +++ b/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift @@ -10,14 +10,14 @@ func foo(_ ptr: Swift.UnsafePointer, _ len: Swift.Int) -> Swift.Void func bar(_ ptr: Swift.UnsafePointer, _ len: Swift.Int) -> () { } -// CHECK: @_alwaysEmitIntoClient +// 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 +// 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 ceebe3e43ac81..dab352b4cc686 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Return.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Return.swift @@ -6,7 +6,8 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) -> CInt { } -// CHECK: @_alwaysEmitIntoClient +// 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 71a084acb6f71..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) { } -// CHECK: @_alwaysEmitIntoClient -// 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") +@_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) { +// 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 3f252815fc557..c5727fb0b0e34 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift @@ -6,7 +6,8 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 59635e7ccf8a7..c6f99fa5bad85 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift @@ -7,9 +7,10 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 b4f5a9ae40d06..ac8bc628c427b 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift @@ -7,9 +7,10 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) -> CInt { } -// CHECK: @_alwaysEmitIntoClient +// 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 09fa7f41de45c..1823fa3edca56 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift @@ -8,10 +8,11 @@ func myFunc(_ ptr1: UnsafePointer, _ len1: CInt, _ ptr2: UnsafePointer, _ len2: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr1: Span, _ 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 8677adf97a741..3e220c1726473 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift @@ -6,8 +6,8 @@ func myFunc(_ ptr: UnsafePointer!, _ len: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 5c680129eb306..5a75578ae7866 100644 --- a/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift +++ b/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift @@ -57,7 +57,11 @@ func myFunc8(_ ptr: UnsafeRawPointer, _ span: SpanOfInt, _ count: CInt, _ size: func myFunc9(_ span: MutableSpanOfInt) -> MutableSpanOfInt { } -// CHECK: @_alwaysEmitIntoClient @lifetime(copy span) +@_SwiftifyImport(.lifetimeDependence(dependsOn: .param(1), pointer: .return, type: .copy), typeMappings: ["MutableSpanOfInt" : "std.span"]) +func myFunc10(_ self: MutableSpanOfInt) -> MutableSpanOfInt { +} + +// CHECK: @_alwaysEmitIntoClient @lifetime(copy span) @_disfavoredOverload // CHECK-NEXT: func myFunc(_ span: Span) -> Span { // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc(SpanOfInt(span))), copying: ()) // CHECK-NEXT: } @@ -67,12 +71,12 @@ func myFunc9(_ span: MutableSpanOfInt) -> MutableSpanOfInt { // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc2(vec)), copying: ()) // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(copy span1, copy span2) +// CHECK: @_alwaysEmitIntoClient @lifetime(copy span1, copy span2) @_disfavoredOverload // CHECK-NEXT: func myFunc3(_ span1: Span, _ span2: Span) -> Span { // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc3(SpanOfInt(span1), SpanOfInt(span2))), copying: ()) // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(borrow vec, copy span) +// CHECK: @_alwaysEmitIntoClient @lifetime(borrow vec, copy span) @_disfavoredOverload // CHECK-NEXT: func myFunc4(_ vec: borrowing VecOfInt, _ span: Span) -> Span { // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc4(vec, SpanOfInt(span))), copying: ()) // CHECK-NEXT: } @@ -82,42 +86,49 @@ func myFunc9(_ span: MutableSpanOfInt) -> MutableSpanOfInt { // CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc5()), copying: ()) // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(copy span) +// 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) +// 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) +// 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) +// 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: return unsafe myFunc9(MutableSpanOfInt(_spanPtr)) +// CHECK-NEXT: }), copying: ()) +// CHECK-NEXT: } + +// CHECK: @_alwaysEmitIntoClient @lifetime(copy `self`) @lifetime(`self`: copy `self`) @_disfavoredOverload +// CHECK-NEXT: func myFunc10(_ `self`: inout MutableSpan) -> MutableSpan { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableSpan(_unsafeCxxSpan: unsafe `self`.withUnsafeMutableBufferPointer { _selfPtr in +// CHECK-NEXT: return unsafe myFunc10(MutableSpanOfInt(_selfPtr)) // CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CxxSpan/NoEscapeSpan.swift b/test/Macros/SwiftifyImport/CxxSpan/NoEscapeSpan.swift index 84474ac42795c..6093902b4f716 100644 --- a/test/Macros/SwiftifyImport/CxxSpan/NoEscapeSpan.swift +++ b/test/Macros/SwiftifyImport/CxxSpan/NoEscapeSpan.swift @@ -25,26 +25,26 @@ func myFunc3(_ span: MutableSpanOfInt, _ secondSpan: SpanOfInt) { func myFunc4(_ span: MutableSpanOfInt, _ secondSpan: MutableSpanOfInt) { } -// CHECK: @_alwaysEmitIntoClient +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ span: Span, _ secondSpan: SpanOfInt) { // CHECK-NEXT: return unsafe myFunc(SpanOfInt(span), secondSpan) // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) +// CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) @_disfavoredOverload // CHECK-NEXT: func myFunc2(_ span: inout MutableSpan, _ secondSpan: MutableSpanOfInt) { // CHECK-NEXT: return unsafe span.withUnsafeMutableBufferPointer { _spanPtr in // CHECK-NEXT: return unsafe myFunc2(MutableSpanOfInt(_spanPtr), secondSpan) // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) +// CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) @_disfavoredOverload // CHECK-NEXT: func myFunc3(_ span: inout MutableSpan, _ secondSpan: Span) { // CHECK-NEXT: return unsafe span.withUnsafeMutableBufferPointer { _spanPtr in // CHECK-NEXT: return unsafe myFunc3(MutableSpanOfInt(_spanPtr), SpanOfInt(secondSpan)) // CHECK-NEXT: } // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) @lifetime(secondSpan: copy secondSpan) +// CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) @lifetime(secondSpan: copy secondSpan) @_disfavoredOverload // CHECK-NEXT: func myFunc4(_ span: inout MutableSpan, _ secondSpan: inout MutableSpan) { // CHECK-NEXT: return unsafe secondSpan.withUnsafeMutableBufferPointer { _secondSpanPtr in // CHECK-NEXT: return unsafe span.withUnsafeMutableBufferPointer { _spanPtr in diff --git a/test/Macros/SwiftifyImport/MacroErrors/UnexpectedCountType.swift b/test/Macros/SwiftifyImport/MacroErrors/UnexpectedCountType.swift index 6a230425c477c..5042895b4b2a3 100644 --- a/test/Macros/SwiftifyImport/MacroErrors/UnexpectedCountType.swift +++ b/test/Macros/SwiftifyImport/MacroErrors/UnexpectedCountType.swift @@ -9,7 +9,7 @@ func myFunc(_ ptr: UnsafePointer, _ len: String) { } -// CHECK: @_alwaysEmitIntoClient +// CHECK: @_alwaysEmitIntoClient @_disfavoredOverload // CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer) { // CHECK-NEXT: myFunc(ptr.baseAddress!, String(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift b/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift index 912c9dbcd8822..dbf142efcfe87 100644 --- a/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift +++ b/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift @@ -6,7 +6,9 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt, _ ptr2: UnsafeRawPointer, _ size2: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 1e8e9d9023d84..7cb497c206587 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Mutable.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Mutable.swift @@ -6,7 +6,8 @@ func myFunc(_ ptr: UnsafeMutableRawPointer, _ size: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 cdf33a0e3add6..1e194e9ee9493 100644 --- a/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift +++ b/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift @@ -7,9 +7,10 @@ func myFunc(_ ptr: UnsafeMutableRawPointer, _ size: CInt) { } -// CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) +// 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 beb19dceb156c..337d805b84af9 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Nullable.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Nullable.swift @@ -18,68 +18,69 @@ func myFunc3(_ ptr: UnsafeMutableRawPointer?, _ len: CInt, _ ptr2: UnsafeMutable func myFunc4(_ ptr: UnsafeMutableRawPointer?, _ len: CInt) -> UnsafeMutableRawPointer? { } -// CHECK: @_alwaysEmitIntoClient +// 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) +// 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) +// 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) -// 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: @_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) @_disfavoredOverload +// 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 f4067cc321b83..72bf7ba8e7a96 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Opaque.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Opaque.swift @@ -26,45 +26,49 @@ func nullableSpan(_ ptr: OpaquePointer?, _ size: CInt) { func impNullableSpan(_ ptr: OpaquePointer!, _ size: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 +// 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 +// 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 +// 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 +// 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 +// 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 78b6d16976340..1e0b000becf95 100644 --- a/test/Macros/SwiftifyImport/SizedBy/PointerReturn.swift +++ b/test/Macros/SwiftifyImport/SizedBy/PointerReturn.swift @@ -37,26 +37,30 @@ func lifetimeDependentBorrowMut(_ p: borrowing UnsafeMutableRawPointer, _ len1: // CHECK-NEXT: return unsafe UnsafeRawBufferPointer(start: unsafe nonEscaping(len), count: Int(len)) // CHECK-NEXT: } -// CHECK: @_alwaysEmitIntoClient @lifetime(copy p) +// 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) +// 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) +// 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) +// 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: } \ No newline at end of file +// 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 61dcbc9764861..346a1835f77a8 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Return.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Return.swift @@ -6,7 +6,8 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) -> CInt { } -// CHECK: @_alwaysEmitIntoClient +// 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 2d331b9c19805..524e901b8ae5f 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift @@ -6,15 +6,11 @@ func myFunc(_ ptr: UnsafeRawPointer, _ ptr2: UnsafeRawPointer, _ size: CInt) { } -// CHECK: @_alwaysEmitIntoClient -// 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: @_alwaysEmitIntoClient @_disfavoredOverload +// 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 def3831b72cb6..bb53ff31997c5 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift @@ -7,9 +7,10 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 9cf85ba8ee776..418290c939ab4 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift @@ -7,9 +7,10 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) -> CInt { } -// CHECK: @_alwaysEmitIntoClient +// 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 803d81e788d1f..580ec4298bc52 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift @@ -6,7 +6,8 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 506ae8da2b687..76c9bb716007e 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift @@ -6,11 +6,11 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt, _ count: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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 c18be3ae42f62..15ba4616a586f 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift @@ -6,8 +6,8 @@ func myFunc(_ ptr: UnsafeRawPointer!, _ len: CInt) { } -// CHECK: @_alwaysEmitIntoClient +// 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: } - diff --git a/test/SourceKit/CursorInfo/cursor_doc_comment_from_clang_safe_wrapper.swift b/test/SourceKit/CursorInfo/cursor_doc_comment_from_clang_safe_wrapper.swift index a9a69647c73ce..77917f65dda7f 100644 --- a/test/SourceKit/CursorInfo/cursor_doc_comment_from_clang_safe_wrapper.swift +++ b/test/SourceKit/CursorInfo/cursor_doc_comment_from_clang_safe_wrapper.swift @@ -28,7 +28,7 @@ func test(_ s: Span) { // CHECK: This comment contains `markup`. // CHECK: - And a list // CHECK-LABEL: DOC COMMENT XML -// CHECK: testCDecl(_:)s:SC9testCDeclyys4SpanVys5Int32VGF@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) +// CHECK: testCDecl(_:)s:SC9testCDeclyys4SpanVys5Int32VGF@available(visionOS 1.1, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) // CHECK-NEXT: public func testCDecl(_ p: Span<Int32>)This comment contains markup. *And a listThis is an auto-generated wrapper for safer interop // CHECK-LABEL: SYMBOL GRAPH BEGIN