Skip to content

[DebugInfo] Ignore noescape bit for all @convention(c) pointers #42189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 19, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions include/swift/AST/ExtInfo.h
Original file line number Diff line number Diff line change
@@ -358,8 +358,6 @@ class ASTExtInfoBuilder {

constexpr Representation getRepresentation() const {
unsigned rawRep = bits & RepresentationMask;
assert(rawRep <= unsigned(Representation::Last) &&
"unexpected SIL representation");
return Representation(rawRep);
}

15 changes: 15 additions & 0 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/DistributedDecl.h"
#include "swift/AST/ExistentialLayout.h"
#include "swift/AST/ExtInfo.h"
#include "swift/AST/FileUnit.h"
#include "swift/AST/ForeignAsyncConvention.h"
#include "swift/AST/ForeignErrorConvention.h"
@@ -3681,6 +3682,16 @@ FunctionType *FunctionType::get(ArrayRef<AnyFunctionType::Param> params,
auto properties = getFunctionRecursiveProperties(params, result, globalActor);
auto arena = getArena(properties);

if (info.hasValue()) {
// Canonicalize all thin functions to be escaping (to keep compatibility
// with generic parameters). Note that one can pass SIL-level representation
// here, so we need additional check for maximum non-SIL value.
Representation rep = info.getValue().getRepresentation();
if (rep <= FunctionTypeRepresentation::Last &&
isThinRepresentation(rep))
info = info->withNoEscape(false);
}

llvm::FoldingSetNodeID id;
FunctionType::Profile(id, params, result, info);

@@ -4098,6 +4109,10 @@ CanSILFunctionType SILFunctionType::get(
ext = ext.intoBuilder().withClangFunctionType(nullptr).build();
}

// Canonicalize all thin functions to be escaping (to keep compatibility
// with generic parameters)
if (isThinRepresentation(ext.getRepresentation()))
ext = ext.intoBuilder().withNoEscape(false);

llvm::FoldingSetNodeID id;
SILFunctionType::Profile(id, genericSig, ext, coroutineKind, callee, params,
9 changes: 4 additions & 5 deletions test/AutoDiff/SILOptimizer/activity_analysis.swift
Original file line number Diff line number Diff line change
@@ -552,14 +552,13 @@ func testTryApply(_ x: Float) -> Float {
// CHECK: bb0:
// CHECK: [ACTIVE] %0 = argument of bb0 : $Float
// CHECK: [NONE] // function_ref closure #1 in testTryApply(_:)
// CHECK: [NONE] %3 = convert_function %2 : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
// CHECK: [NONE] %4 = thin_to_thick_function %3 : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [NONE] %5 = convert_function %4 : $@noescape @callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> @error Error
// CHECK: [NONE] %3 = thin_to_thick_function %2 : $@convention(thin) () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [NONE] %4 = convert_function %3 : $@noescape @callee_guaranteed () -> () to $@noescape @callee_guaranteed () -> @error Error
// CHECK: [NONE] // function_ref rethrowing(_:)
// CHECK: bb1:
// CHECK: [NONE] %8 = argument of bb1 : $()
// CHECK: [NONE] %7 = argument of bb1 : $()
// CHECK: bb2:
// CHECK: [NONE] %10 = argument of bb2 : $Error
// CHECK: [NONE] %9 = argument of bb2 : $Error

//===----------------------------------------------------------------------===//
// Coroutine differentiation (`begin_apply`)
2 changes: 1 addition & 1 deletion test/IRGen/objc_retainAutoreleasedReturnValue.swift
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ public func test(_ dict: NSDictionary) {
// CHECK: notail call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: ret void

// OPT-LABEL: define {{.*}}swiftcc void @"$s34objc_retainAutoreleasedReturnValue4testyySo12NSDictionaryCFyADXEfU_"(%TSo12NSDictionaryC* %0)
// OPT-LABEL: define {{.*}}swiftcc void @"$s34objc_retainAutoreleasedReturnValue10useClosureyySo12NSDictionaryC_yADXEtF09$s34objc_bcd16Value4testyySo12H10CFyADXEfU_Tf1nc_n"(%TSo12NSDictionaryC* %0)
// OPT: entry:
// OPT: call {{.*}}@objc_msgSend
// OPT: notail call i8* @llvm.objc.retainAutoreleasedReturnValue
2 changes: 1 addition & 1 deletion test/PrintAsObjC/blocks.swift
Original file line number Diff line number Diff line change
@@ -101,7 +101,7 @@ typealias MyBlockWithNoescapeParam = (() -> ()) -> Int
) {
}

// CHECK-NEXT: - (void (* _Nonnull)(SWIFT_NOESCAPE NSInteger (* _Nonnull)(NSInteger, NSInteger)))returnsFunctionPointerThatTakesFunctionPointer SWIFT_WARN_UNUSED_RESULT;
// CHECK-NEXT: - (void (* _Nonnull)(NSInteger (* _Nonnull)(NSInteger, NSInteger)))returnsFunctionPointerThatTakesFunctionPointer SWIFT_WARN_UNUSED_RESULT;
@objc func returnsFunctionPointerThatTakesFunctionPointer() ->
@convention(c) (_ comparator: @convention(c) (_ x: Int, _ y: Int) -> Int) -> Void {
fatalError()
2 changes: 1 addition & 1 deletion test/PrintAsObjC/cdecl-imports.swift
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ import Foundation
public func fwdDeclaresBee() -> Bee { fatalError() }

// CHECK: @class Hive;
// CHECK-LABEL: void fwd_declares_hive(SWIFT_NOESCAPE Hive * _Nonnull (* _Nonnull bzzz)(Bee * _Nonnull));
// CHECK-LABEL: void fwd_declares_hive(Hive * _Nonnull (* _Nonnull bzzz)(Bee * _Nonnull));

@_cdecl("fwd_declares_hive")
public func fwdDeclaresHive(bzzz: @convention(c) (Bee) -> Hive) { fatalError() }
4 changes: 2 additions & 2 deletions test/PrintAsObjC/cdecl.swift
Original file line number Diff line number Diff line change
@@ -26,12 +26,12 @@ public func block_recurring_nightmare(x: @escaping @convention(block) (@conventi
@_cdecl("foo_bar")
func foo(x: Int, bar y: Int) {}

// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_nightmare(SWIFT_NOESCAPE float (* _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT;
// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_nightmare(float (* _Nonnull x)(NSInteger)))(char) SWIFT_WARN_UNUSED_RESULT;
@_cdecl("function_pointer_nightmare")
func function_pointer_nightmare(x: @convention(c) (Int) -> Float)
-> @convention(c) (CChar) -> Double { return { _ in 0 } }

// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(SWIFT_NOESCAPE NSInteger (* _Nonnull)(double))))(SWIFT_NOESCAPE char (* _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT;
// CHECK-LABEL: SWIFT_EXTERN double (* _Nonnull function_pointer_recurring_nightmare(float (* _Nonnull x)(NSInteger (* _Nonnull)(double))))(char (* _Nonnull)(unsigned char)) SWIFT_WARN_UNUSED_RESULT;
@_cdecl("function_pointer_recurring_nightmare")
public func function_pointer_recurring_nightmare(x: @escaping @convention(c) (@convention(c) (Double) -> Int) -> Float)
-> @convention(c) (@convention(c) (CUnsignedChar) -> CChar) -> Double {
6 changes: 3 additions & 3 deletions test/SIL/clang-function-types-nonwindows.swift
Original file line number Diff line number Diff line change
@@ -7,6 +7,6 @@ import ctypes

public func f(g: @convention(c, cType: "void (*)(size_t)") (Int) -> ()) { g(0) }

// CHECK: sil @$s4main1f1gyySiXzC9_ZTSPFvmE_tF : $@convention(thin) (@convention(c, cType: "void (*)(unsigned long)") @noescape (Int) -> ()) -> () {
// CHECK: bb0(%0 : $@convention(c, cType: "void (*)(unsigned long)") @noescape (Int) -> ()):
// CHECK: debug_value %0 : $@convention(c, cType: "void (*)(unsigned long)") @noescape (Int) -> (), let, name "g", argno 1 // id: %1
// CHECK: sil @$s4main1f1gyySiXzC9_ZTSPFvmE_tF : $@convention(thin) (@convention(c, cType: "void (*)(unsigned long)") (Int) -> ()) -> () {
// CHECK: bb0(%0 : $@convention(c, cType: "void (*)(unsigned long)") (Int) -> ()):
// CHECK: debug_value %0 : $@convention(c, cType: "void (*)(unsigned long)") (Int) -> (), let, name "g", argno 1 // id: %1
12 changes: 4 additions & 8 deletions test/SILGen/async_builtins.swift
Original file line number Diff line number Diff line change
@@ -43,8 +43,7 @@ public func usesWithUnsafeContinuation() async {
let _: Int = await Builtin.withUnsafeContinuation { c in }

// CHECK: [[FN:%.*]] = function_ref @$s4test26usesWithUnsafeContinuationyyYaFyBcXEfU_ : $@convention(thin) (Builtin.RawUnsafeContinuation) -> ()
// CHECK: [[TMP:%.*]] = convert_function [[FN]] : $@convention(thin) (Builtin.RawUnsafeContinuation) -> () to $@convention(thin) @noescape (Builtin.RawUnsafeContinuation) -> ()
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[TMP]]
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[FN]]
// CHECK: [[BOX:%.*]] = alloc_stack $Int
// CHECK: [[CC:%.*]] = get_async_continuation_addr Int, [[BOX]] : $*Int
// CHECK: apply [[CLOSURE]]([[CC]]) : $@noescape @callee_guaranteed (Builtin.RawUnsafeContinuation) -> ()
@@ -58,8 +57,7 @@ public func usesWithUnsafeContinuation() async {
let _: String = await Builtin.withUnsafeContinuation { c in }

// CHECK: [[FN:%.*]] = function_ref @$s4test26usesWithUnsafeContinuationyyYaFyBcXEfU0_ : $@convention(thin) (Builtin.RawUnsafeContinuation) -> ()
// CHECK: [[TMP:%.*]] = convert_function [[FN]] : $@convention(thin) (Builtin.RawUnsafeContinuation) -> () to $@convention(thin) @noescape (Builtin.RawUnsafeContinuation) -> ()
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[TMP]]
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[FN]]
// CHECK: [[BOX:%.*]] = alloc_stack $String
// CHECK: [[CC:%.*]] = get_async_continuation_addr String, [[BOX]] : $*String
// CHECK: apply [[CLOSURE]]([[CC]]) : $@noescape @callee_guaranteed (Builtin.RawUnsafeContinuation) -> ()
@@ -74,8 +72,7 @@ public func usesWithUnsafeContinuation() async {
let _: Any = await Builtin.withUnsafeContinuation { c in }

// CHECK: [[FN:%.*]] = function_ref @$s4test26usesWithUnsafeContinuationyyYaFyBcXEfU1_ : $@convention(thin) (Builtin.RawUnsafeContinuation) -> ()
// CHECK: [[TMP:%.*]] = convert_function [[FN]] : $@convention(thin) (Builtin.RawUnsafeContinuation) -> () to $@convention(thin) @noescape (Builtin.RawUnsafeContinuation) -> ()
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[TMP]]
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[FN]]
// CHECK: [[BOX:%.*]] = alloc_stack $Any
// CHECK: [[CC:%.*]] = get_async_continuation_addr Any, [[BOX]] : $*Any
// CHECK: apply [[CLOSURE]]([[CC]]) : $@noescape @callee_guaranteed (Builtin.RawUnsafeContinuation) -> ()
@@ -94,8 +91,7 @@ public func usesWithUnsafeThrowingContinuation() async throws {
let _: Int = try await Builtin.withUnsafeThrowingContinuation { c in }

// CHECK: [[FN:%.*]] = function_ref @$s4test34usesWithUnsafeThrowingContinuationyyYaKFyBcXEfU_ : $@convention(thin) (Builtin.RawUnsafeContinuation) -> ()
// CHECK: [[TMP:%.*]] = convert_function [[FN]] : $@convention(thin) (Builtin.RawUnsafeContinuation) -> () to $@convention(thin) @noescape (Builtin.RawUnsafeContinuation) -> ()
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[TMP]]
// CHECK: [[CLOSURE:%.*]] = thin_to_thick_function [[FN]]
// CHECK: [[BOX:%.*]] = alloc_stack $Int
// CHECK: [[CC:%.*]] = get_async_continuation_addr [throws] Int, [[BOX]] : $*Int
// CHECK: apply [[CLOSURE]]([[CC]]) : $@noescape @callee_guaranteed (Builtin.RawUnsafeContinuation) -> ()
3 changes: 1 addition & 2 deletions test/SILGen/auto_closures.swift
Original file line number Diff line number Diff line change
@@ -25,8 +25,7 @@ func test_auto_closure_with_capture(_ x: Bool) -> Bool {
// CHECK-LABEL: sil hidden [ossa] @$s13auto_closures05test_A24_closure_without_capture{{[_0-9a-zA-Z]*}}F
func test_auto_closure_without_capture() -> Bool {
// CHECK: [[CLOSURE:%.*]] = function_ref @$s13auto_closures05test_A24_closure_without_capture
// CHECK: [[CVT:%.*]] = convert_function [[CLOSURE]]
// CHECK: [[THICK:%.*]] = thin_to_thick_function [[CVT]] : $@convention(thin) @noescape () -> Bool to $@noescape @callee_guaranteed () -> Bool
// CHECK: [[THICK:%.*]] = thin_to_thick_function [[CLOSURE]] : $@convention(thin) () -> Bool to $@noescape @callee_guaranteed () -> Bool
// CHECK: [[RET:%.*]] = apply {{%.*}}([[THICK]])
// CHECK: return [[RET]]
return call_auto_closure(false_)
16 changes: 6 additions & 10 deletions test/SILGen/c_function_pointers.swift
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ func calls(_ arg: @convention(c) (Int) -> Int, _ x: Int) -> Int {
return arg(x)
}
// CHECK-LABEL: sil hidden [ossa] @$s19c_function_pointers5callsyS3iXC_SitF
// CHECK: bb0(%0 : $@convention(c) @noescape (Int) -> Int, %1 : $Int):
// CHECK: bb0(%0 : $@convention(c) (Int) -> Int, %1 : $Int):
// CHECK: [[RESULT:%.*]] = apply %0(%1)
// CHECK: return [[RESULT]]

@@ -60,24 +60,20 @@ func pointers_to_swift_functions(_ x: Int) {
func local(_ y: Int) -> Int { return y }

// CHECK: [[GLOBAL_C:%.*]] = function_ref @$s19c_function_pointers6globalyS2iFTo
// CHECK: [[CVT:%.*]] = convert_function [[GLOBAL_C]]
// CHECK: apply {{.*}}([[CVT]], [[X]])
// CHECK: apply {{.*}}([[GLOBAL_C]], [[X]])
calls(global, x)

// CHECK: [[LOCAL_C:%.*]] = function_ref @$s19c_function_pointers0B19_to_swift_functionsyySiF5localL_yS2iFTo
// CHECK: [[CVT:%.*]] = convert_function [[LOCAL_C]]
// CHECK: apply {{.*}}([[CVT]], [[X]])
// CHECK: apply {{.*}}([[LOCAL_C]], [[X]])
calls(local, x)

// CHECK: [[CLOSURE_C:%.*]] = function_ref @$s19c_function_pointers0B19_to_swift_functionsyySiFS2iXEfU_To
// CHECK: [[CVT:%.*]] = convert_function [[CLOSURE_C]]
// CHECK: apply {{.*}}([[CVT]], [[X]])
// CHECK: [[CLOSURE_C:%.*]] = function_ref @$s19c_function_pointers0B19_to_swift_functionsyySiFS2icfU_To
// CHECK: apply {{.*}}([[CLOSURE_C]], [[X]])
calls({ $0 + 1 }, x)

calls_no_args(no_args)
// CHECK: [[NO_ARGS_C:%.*]] = function_ref @$s19c_function_pointers7no_argsSiyFTo
// CHECK: [[CVT:%.*]] = convert_function [[NO_ARGS_C]]
// CHECK: apply {{.*}}([[CVT]])
// CHECK: apply {{.*}}([[NO_ARGS_C]])
}

func unsupported(_ a: Any) -> Int { return 0 }
3 changes: 1 addition & 2 deletions test/SILGen/closures_callee_guaranteed.swift
Original file line number Diff line number Diff line change
@@ -22,8 +22,7 @@ public func apply(_ f : () -> Int) -> Int {

// CHECK-LABEL: sil [ossa] @{{.*}}test{{.*}} : $@convention(thin) () -> ()
// CHECK: [[C1:%.*]] = function_ref @{{.*}}test{{.*}} : $@convention(thin) () -> Int
// CHECK: [[C2:%.*]] = convert_function [[C1]] : $@convention(thin) () -> Int to $@convention(thin) @noescape () -> Int
// CHECK: [[C3:%.*]] = thin_to_thick_function [[C2]] : $@convention(thin) @noescape () -> Int to $@noescape @callee_guaranteed () -> Int
// CHECK: [[C3:%.*]] = thin_to_thick_function [[C1]] : $@convention(thin) () -> Int to $@noescape @callee_guaranteed () -> Int
// CHECK: [[A:%.*]] = function_ref @{{.*}}apply{{.*}} : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> Int
// CHECK: apply [[A]]([[C3]]) : $@convention(thin) (@noescape @callee_guaranteed () -> Int) -> Int
public func test() {
8 changes: 3 additions & 5 deletions test/SILGen/objc_blocks_bridging.swift
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ import Foundation
}

// CHECK-LABEL: sil hidden [thunk] [ossa] @$s20objc_blocks_bridging3FooC16cFunctionPointer{{[_0-9a-zA-Z]*}}FTo
// CHECK: bb0([[F:%.*]] : $@convention(c) @noescape (Int) -> Int, [[X:%.*]] : $Int, [[SELF:%.*]] : @unowned $Foo):
// CHECK: bb0([[F:%.*]] : $@convention(c) (Int) -> Int, [[X:%.*]] : $Int, [[SELF:%.*]] : @unowned $Foo):
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: [[BORROWED_SELF_COPY:%.*]] = begin_borrow [[SELF_COPY]]
// CHECK: [[NATIVE:%.*]] = function_ref @$s20objc_blocks_bridging3FooC16cFunctionPointer{{[_0-9a-zA-Z]*}}F
@@ -175,8 +175,7 @@ func bridgeNonnullBlockResult() {
// CHECK-LABEL: sil hidden [ossa] @$s20objc_blocks_bridging19bridgeNoescapeBlock2fn5optFnyyyXE_yycSgtF
func bridgeNoescapeBlock(fn: () -> (), optFn: (() -> ())?) {
// CHECK: [[CLOSURE_FN:%.*]] = function_ref @$s20objc_blocks_bridging19bridgeNoescapeBlock2fn5optFnyyyXE_yycSgtFyyXEfU_
// CHECK: [[CONV_FN:%.*]] = convert_function [[CLOSURE_FN]]
// CHECK: [[THICK_FN:%.*]] = thin_to_thick_function [[CONV_FN]]
// CHECK: [[THICK_FN:%.*]] = thin_to_thick_function [[CLOSURE_FN]]
// without actually escaping sentinel
// CHECK: [[WAE_THUNK:%.*]] = function_ref @$sIg_Ieg_TR
// CHECK: [[WAE_PA:%.*]] = partial_apply [callee_guaranteed] [[WAE_THUNK]]([[THICK_FN]])
@@ -224,8 +223,7 @@ func bridgeNoescapeBlock(fn: () -> (), optFn: (() -> ())?) {
noescapeBlock(nil)

// CHECK: [[CLOSURE_FN:%.*]] = function_ref @$s20objc_blocks_bridging19bridgeNoescapeBlock2fn5optFnyyyXE_yycSgtF
// CHECK: [[CONV_FN:%.*]] = convert_function [[CLOSURE_FN]]
// CHECK: [[THICK_FN:%.*]] = thin_to_thick_function [[CONV_FN]]
// CHECK: [[THICK_FN:%.*]] = thin_to_thick_function [[CLOSURE_FN]]
// CHECK: [[WAE_THUNK:%.*]] = function_ref @$sIg_Ieg_TR
// CHECK: [[WAE_PA:%.*]] = partial_apply [callee_guaranteed] [[WAE_THUNK]]([[THICK_FN]])
// CHECK: [[WAE_MD:%.*]] = mark_dependence [[WAE_PA]] : $@callee_guaranteed () -> () on [[THICK_FN]]
9 changes: 3 additions & 6 deletions test/SILGen/parameterized_existentials.swift
Original file line number Diff line number Diff line change
@@ -54,8 +54,7 @@ func use(_ k: (S) -> Void) {}
// CHECK-LABEL: sil hidden [ossa] @$s13parameterized11upcastInputyyF : $@convention(thin) () -> () {
func upcastInput() {
// CHECK: [[P_FN:%.*]] = function_ref @$s13parameterized11upcastInputyyFyAA1P_pXEfU_ : $@convention(thin) (@in_guaranteed P) -> ()
// CHECK: [[NOESCAPE_P_FN:%.*]] = convert_function [[P_FN]] : $@convention(thin) (@in_guaranteed P) -> () to $@convention(thin) @noescape (@in_guaranteed P) -> ()
// CHECK: [[THICK_P_FN:%.*]] = thin_to_thick_function [[NOESCAPE_P_FN]] : $@convention(thin) @noescape (@in_guaranteed P) -> () to $@noescape @callee_guaranteed (@in_guaranteed P) -> ()
// CHECK: [[THICK_P_FN:%.*]] = thin_to_thick_function [[P_FN]] : $@convention(thin) (@in_guaranteed P) -> () to $@noescape @callee_guaranteed (@in_guaranteed P) -> ()
// CHECK: [[S_TO_P_THUNK_FN:%.*]] = function_ref @$s13parameterized1P_pIgn_AA1SVIegy_TR : $@convention(thin) (S, @noescape @callee_guaranteed (@in_guaranteed P) -> ()) -> ()
// CHECK: [[PARTIAL_INT_THUNK_FN:%.*]] = partial_apply [callee_guaranteed] [[S_TO_P_THUNK_FN]]([[THICK_P_FN]]) : $@convention(thin) (S, @noescape @callee_guaranteed (@in_guaranteed P) -> ()) -> ()
// CHECK: [[NOESCAPE_P_THUNK_FN:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_INT_THUNK_FN]] : $@callee_guaranteed (S) -> () to $@noescape @callee_guaranteed (S) -> ()
@@ -70,8 +69,7 @@ func reuse(_ k: () -> any P<Int, String, Float>) {}
// CHECK-LABEL: sil hidden [ossa] @$s13parameterized12upcastResultyyF : $@convention(thin) () -> () {
func upcastResult() {
// CHECK: [[RES_FN:%.*]] = function_ref @$s13parameterized12upcastResultyyFAA1SVyXEfU_ : $@convention(thin) () -> S
// CHECK: [[NOESCAPE_RES_FN:%.*]] = convert_function [[RES_FN]] : $@convention(thin) () -> S to $@convention(thin) @noescape () -> S
// CHECK: [[THICK_RES_FN:%.*]] = thin_to_thick_function [[NOESCAPE_RES_FN]] : $@convention(thin) @noescape () -> S to $@noescape @callee_guaranteed () -> S
// CHECK: [[THICK_RES_FN:%.*]] = thin_to_thick_function [[RES_FN]] : $@convention(thin) () -> S to $@noescape @callee_guaranteed () -> S
// CHECK: [[S_TO_P_RES_THUNK_FN:%.*]] = function_ref @$s13parameterized1SVIgd_AA1P_pySiSSSfXPIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> S) -> @out P<Int, String, Float>
// CHECK: [[PARTIAL_RES_THUNK_FN:%.*]] = partial_apply [callee_guaranteed] [[S_TO_P_RES_THUNK_FN]]([[THICK_RES_FN]]) : $@convention(thin) (@noescape @callee_guaranteed () -> S) -> @out P<Int, String, Float>
// CHECK: [[NOESCAPE_RES_THUNK_FN:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_RES_THUNK_FN]] : $@callee_guaranteed () -> @out P<Int, String, Float> to $@noescape @callee_guaranteed () -> @out P<Int, String, Float>
@@ -81,8 +79,7 @@ func upcastResult() {
reuse({ () -> S in S() })

// CHECK: [[RES_Q_FN:%.*]] = function_ref @$s13parameterized12upcastResultyyFAA1Q_pySiSSSfXPyXEfU0_ : $@convention(thin) () -> @out Q<Int, String, Float>
// CHECK: [[NOESCAPE_RES_Q_FN:%.*]] = convert_function [[RES_Q_FN]] : $@convention(thin) () -> @out Q<Int, String, Float> to $@convention(thin) @noescape () -> @out Q<Int, String, Float>
// CHECK: [[THICK_NOESCAPE_RES_Q_FN:%.*]] = thin_to_thick_function [[NOESCAPE_RES_Q_FN]] : $@convention(thin) @noescape () -> @out Q<Int, String, Float> to $@noescape @callee_guaranteed () -> @out Q<Int, String, Float>
// CHECK: [[THICK_NOESCAPE_RES_Q_FN:%.*]] = thin_to_thick_function [[RES_Q_FN]] : $@convention(thin) () -> @out Q<Int, String, Float> to $@noescape @callee_guaranteed () -> @out Q<Int, String, Float>
// CHECK: [[P_TO_Q_RES_THUNK_FN:%.*]] = function_ref @$s13parameterized1Q_pySiSSSfXPIgr_AA1P_pySiSSSfXPIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> @out Q<Int, String, Float>) -> @out P<Int, String, Float>
// CHECK: [[PARTIAL_P_TO_Q_RES_THUNK_FN:%.*]] = partial_apply [callee_guaranteed] [[P_TO_Q_RES_THUNK_FN]]([[THICK_NOESCAPE_RES_Q_FN]]) : $@convention(thin) (@noescape @callee_guaranteed () -> @out Q<Int, String, Float>) -> @out P<Int, String, Float>
// CHECK: [[NOESCAPE_PARTIAL_P_TO_Q_RES_THUNK_FN:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_P_TO_Q_RES_THUNK_FN]] : $@callee_guaranteed () -> @out P<Int, String, Float> to $@noescape @callee_guaranteed () -> @out P<Int, String, Float>
6 changes: 2 additions & 4 deletions test/SILGen/rethrows.swift
Original file line number Diff line number Diff line change
@@ -27,8 +27,7 @@ func test0() throws {

// CHECK-LABEL: sil hidden @$s8rethrows5test1yyKF : $@convention(thin) () -> @error Error {
// CHECK: [[CLOSURE:%.*]] = function_ref @$s8rethrows5test1yyKFSiyKXEfU_ : $@convention(thin) () -> (Int, @error Error)
// CHECK: [[CVT:%.*]] = convert_function [[CLOSURE]]
// CHECK: [[T0:%.*]] = thin_to_thick_function [[CVT]]
// CHECK: [[T0:%.*]] = thin_to_thick_function [[CLOSURE]]
// CHECK: [[RETHROWER:%.*]] = function_ref @$s8rethrows9rethroweryS2iyKXEKF : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error Error)) -> (Int, @error Error)
// CHECK: try_apply [[RETHROWER]]([[T0]]) : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error Error)) -> (Int, @error Error), normal [[NORMAL:bb1]], error [[ERROR:bb2]]
// CHECK: [[NORMAL]]({{%.*}} : $Int):
@@ -72,8 +71,7 @@ func test2() {

// CHECK-LABEL: sil hidden @$s8rethrows5test3yyF : $@convention(thin) () -> () {
// CHECK: [[CLOSURE:%.*]] = function_ref @$s8rethrows5test3yyFSiyXEfU_ : $@convention(thin) () -> Int
// CHECK: [[CVT:%.*]] = convert_function [[CLOSURE]] : $@convention(thin) () -> Int to $@convention(thin) @noescape () -> Int
// CHECK: [[T0:%.*]] = thin_to_thick_function [[CVT]]
// CHECK: [[T0:%.*]] = thin_to_thick_function [[CLOSURE]]
// CHECK: [[T1:%.*]] = convert_function [[T0]] : $@noescape @callee_guaranteed () -> Int to $@noescape @callee_guaranteed () -> (Int, @error Error)
// CHECK: [[RETHROWER:%.*]] = function_ref @$s8rethrows9rethroweryS2iyKXEKF : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error Error)) -> (Int, @error Error)
// CHECK: try_apply [[RETHROWER]]([[T1]]) : $@convention(thin) (@noescape @callee_guaranteed () -> (Int, @error Error)) -> (Int, @error Error), normal [[NORMAL:bb1]], error [[ERROR:bb2]]
4 changes: 2 additions & 2 deletions test/SILGen/without_actually_escaping.swift
Original file line number Diff line number Diff line change
@@ -102,8 +102,8 @@ func withoutActuallyEscapingConflict() {
}

// CHECK-LABEL: sil [ossa] @$s25without_actually_escaping0A25ActuallyEscapingCFunction8functionyyyXC_tF
// CHECK: bb0([[ARG:%.*]] : $@convention(c) @noescape () -> ()):
// CHECK: [[E:%.*]] = convert_function [[ARG]] : $@convention(c) @noescape () -> () to [without_actually_escaping] $@convention(c) () -> ()
// CHECK: bb0([[ARG:%.*]] : $@convention(c) () -> ()):
// CHECK: [[E:%.*]] = convert_function [[ARG]] : $@convention(c) () -> () to [without_actually_escaping] $@convention(c) () -> ()
// CHECK: [[F:%.*]] = function_ref @$s25without_actually_escaping0A25ActuallyEscapingCFunction8functionyyyXC_tFyyyXCXEfU_ : $@convention(thin) (@convention(c) () -> ()) -> ()
// CHECK: apply [[F]]([[E]]) : $@convention(thin) (@convention(c) () -> ()) -> ()
public func withoutActuallyEscapingCFunction(function: (@convention(c) () -> Void)) {
16 changes: 8 additions & 8 deletions test/SILOptimizer/access_enforcement_opts.sil
Original file line number Diff line number Diff line change
@@ -52,8 +52,8 @@ bb0(%0 : $@thin X.Type):
//
// CHECK-LABEL: sil hidden @testNestedAccess1 : $@convention(thin) () -> () {
// CHECK: [[F1:%.*]] = function_ref @testNestedAccessClosure1 : $@convention(thin) () -> ()
// CHECK: [[C1:%.*]] = convert_function [[F1]] : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
// CHECK: [[TF1:%.*]] = thin_to_thick_function [[C1]] : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed ()
// CHECK: [[C1:%.*]] = convert_function [[F1]] : $@convention(thin) () -> () to $@convention(thin) () -> ()
// CHECK: [[TF1:%.*]] = thin_to_thick_function [[C1]] : $@convention(thin) () -> () to $@noescape @callee_guaranteed ()
// CHECK: [[A1:%.*]] = begin_access [read] [dynamic] %0 : $*X
// CHECK: apply [[TF1]]() : $@noescape @callee_guaranteed () -> ()
// CHECK: end_access [[A1]] : $*X
@@ -62,8 +62,8 @@ sil hidden @testNestedAccess1 : $@convention(thin) () -> () {
bb0:
%2 = global_addr @globalX: $*X
%3 = function_ref @testNestedAccessClosure1 : $@convention(thin) () -> ()
%4 = convert_function %3 : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
%5 = thin_to_thick_function %4 : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed () -> ()
%4 = convert_function %3 : $@convention(thin) () -> () to $@convention(thin) () -> ()
%5 = thin_to_thick_function %4 : $@convention(thin) () -> () to $@noescape @callee_guaranteed () -> ()
%6 = begin_access [read] [dynamic] %2 : $*X
%9 = apply %5() : $@noescape @callee_guaranteed () -> ()
end_access %6 : $*X
@@ -72,8 +72,8 @@ bb0:
}
// CHECK-LABEL: sil hidden @testNestedAccess2 : $@convention(thin) () -> () {
// CHECK: [[F2:%.*]] = function_ref @testNestedAccessClosure2 : $@convention(thin) () -> ()
// CHECK: [[C2:%.*]] = convert_function [[F2]] : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
// CHECK: [[TF2:%.*]] = thin_to_thick_function [[C2]] : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[C2:%.*]] = convert_function [[F2]] : $@convention(thin) () -> () to $@convention(thin) () -> ()
// CHECK: [[TF2:%.*]] = thin_to_thick_function [[C2]] : $@convention(thin) () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[A2:%.*]] = begin_access [modify] [dynamic] %0 : $*X
// CHECK: apply [[TF2]]() : $@noescape @callee_guaranteed () -> ()
// CHECK: end_access [[A2]] : $*X
@@ -92,8 +92,8 @@ bb0:
}
// CHECK-LABEL: sil hidden @testNestedAccess3 : $@convention(thin) () -> () {
// CHECK: [[F3:%.*]] = function_ref @testNestedAccessClosure3 : $@convention(thin) () -> ()
// CHECK: [[C3:%.*]] = convert_function [[F3]] : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
// CHECK: [[TF3:%.*]] = thin_to_thick_function [[C3]] : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[C3:%.*]] = convert_function [[F3]] : $@convention(thin) () -> () to $@convention(thin) () -> ()
// CHECK: [[TF3:%.*]] = thin_to_thick_function [[C3]] : $@convention(thin) () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[A3:%.*]] = begin_access [modify] [dynamic] %0 : $*X
// CHECK: apply [[TF3]]() : $@noescape @callee_guaranteed () -> ()
// CHECK: end_access [[A3]] : $*X
12 changes: 6 additions & 6 deletions test/SILOptimizer/access_enforcement_opts_ossa.sil
Original file line number Diff line number Diff line change
@@ -62,8 +62,8 @@ bb0(%0 : $@thin X.Type):
//
// CHECK-LABEL: sil hidden [ossa] @testNestedAccess1 : $@convention(thin) () -> () {
// CHECK: [[F1:%.*]] = function_ref @testNestedAccessClosure1 : $@convention(thin) () -> ()
// CHECK: [[C1:%.*]] = convert_function [[F1]] : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
// CHECK: [[TF1:%.*]] = thin_to_thick_function [[C1]] : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed ()
// CHECK: [[C1:%.*]] = convert_function [[F1]] : $@convention(thin) () -> () to $@convention(thin) () -> ()
// CHECK: [[TF1:%.*]] = thin_to_thick_function [[C1]] : $@convention(thin) () -> () to $@noescape @callee_guaranteed ()
// CHECK: [[A1:%.*]] = begin_access [read] [dynamic] %0 : $*X
// CHECK: apply [[TF1]]() : $@noescape @callee_guaranteed () -> ()
// CHECK: end_access [[A1]] : $*X
@@ -82,8 +82,8 @@ bb0:
}
// CHECK-LABEL: sil hidden [ossa] @testNestedAccess2 : $@convention(thin) () -> () {
// CHECK: [[F2:%.*]] = function_ref @testNestedAccessClosure2 : $@convention(thin) () -> ()
// CHECK: [[C2:%.*]] = convert_function [[F2]] : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
// CHECK: [[TF2:%.*]] = thin_to_thick_function [[C2]] : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[C2:%.*]] = convert_function [[F2]] : $@convention(thin) () -> () to $@convention(thin) () -> ()
// CHECK: [[TF2:%.*]] = thin_to_thick_function [[C2]] : $@convention(thin) () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[A2:%.*]] = begin_access [modify] [dynamic] %0 : $*X
// CHECK: apply [[TF2]]() : $@noescape @callee_guaranteed () -> ()
// CHECK: end_access [[A2]] : $*X
@@ -102,8 +102,8 @@ bb0:
}
// CHECK-LABEL: sil hidden [ossa] @testNestedAccess3 : $@convention(thin) () -> () {
// CHECK: [[F3:%.*]] = function_ref @testNestedAccessClosure3 : $@convention(thin) () -> ()
// CHECK: [[C3:%.*]] = convert_function [[F3]] : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
// CHECK: [[TF3:%.*]] = thin_to_thick_function [[C3]] : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[C3:%.*]] = convert_function [[F3]] : $@convention(thin) () -> () to $@convention(thin) () -> ()
// CHECK: [[TF3:%.*]] = thin_to_thick_function [[C3]] : $@convention(thin) () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[A3:%.*]] = begin_access [modify] [dynamic] %0 : $*X
// CHECK: apply [[TF3]]() : $@noescape @callee_guaranteed () -> ()
// CHECK: end_access [[A3]] : $*X
10 changes: 5 additions & 5 deletions test/SILOptimizer/capture_propagate_keypath.swift
Original file line number Diff line number Diff line change
@@ -30,27 +30,27 @@ struct GenStr<T> {



// CHECK-LABEL: sil {{.*}} @$s4test0A6SimpleyyySiAA3StrVXEXEF
// CHECK-LABEL: sil {{.*}} @$s4test0A6SimpleyyySiAA3StrVXEXEF :
// CHECK-NOT: keypath
// CHECK: } // end sil function '$s4test0A6SimpleyyySiAA3StrVXEXEF'
// CHECK-LABEL: } // end sil function '$s4test0A6SimpleyyySiAA3StrVXEXEF'
@inline(never)
func testSimple(_ mymap: ((Str)->Int) -> ()) {
mymap(\.i)
mymap(\.j)
mymap(\.c)
}

// CHECK-LABEL: sil {{.*}} @$s4test0A6GenStryyySiAA0bC0VySiGXEXEF
// CHECK-LABEL: sil {{.*}} @$s4test0A6GenStryyySiAA0bC0VySiGXEXEF :
// CHECK-NOT: keypath
// CHECK: } // end sil function '$s4test0A6GenStryyySiAA0bC0VySiGXEXEF'
// CHECK-LABEL: } // end sil function '$s4test0A6GenStryyySiAA0bC0VySiGXEXEF'
@inline(never)
func testGenStr(_ mymap: ((GenStr<Int>)->Int) -> ()) {
mymap(\.i)
mymap(\.j)
mymap(\.c)
}

// CHECK-LABEL: sil {{.*}} @$s4test0A7GenericyyyxAA6GenStrVyxGXEXElF
// CHECK-LABEL: sil {{.*}} @$s4test0A7GenericyyyxAA6GenStrVyxGXEXElF :
// CHECK: keypath
// CHECK: keypath
// CHECK: keypath
4 changes: 2 additions & 2 deletions test/SILOptimizer/capture_propagation.sil
Original file line number Diff line number Diff line change
@@ -487,8 +487,8 @@ bb0(%0 : $Builtin.Int32, %1 : $Builtin.FPIEEE32, %2 : $Builtin.RawPointer, %3 :

// CHECK: sil @test_capture_propagation2_caller_on_stack
// CHECK: [[F:%.*]] = function_ref @test_capture_propagation2_callee_on_stack : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
// CHECK: [[F2:%.*]] = function_ref @$s40test_capture_propagation2_thunk_on_stack4_12353globalinit_33_06E7F1D906492AE070936A9B58CBAE1C_token808_TFtest_b1_C8_closureTf3pi0pd0psbpgpf_n : $@convention(thin) @noescape () -> ()
// CHECK: [[CL:%.*]] = thin_to_thick_function [[F2]] : $@convention(thin) @noescape () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: [[F2:%.*]] = function_ref @$s40test_capture_propagation2_thunk_on_stack4_12353globalinit_33_06E7F1D906492AE070936A9B58CBAE1C_token808_TFtest_b1_C8_closureTf3pi0pd0psbpgpf_n : $@convention(thin) () -> ()
// CHECK: [[CL:%.*]] = thin_to_thick_function [[F2]] : $@convention(thin) () -> () to $@noescape @callee_guaranteed () -> ()
// CHECK: apply [[F]]([[CL]]) : $@convention(thin) (@noescape @callee_guaranteed () -> ()) -> ()
// CHECK: return

3 changes: 1 addition & 2 deletions test/SILOptimizer/mandatory_inlining_reasync.swift
Original file line number Diff line number Diff line change
@@ -11,8 +11,7 @@ func reasyncFunction(_ value: Optional<Int>, _ fn: () async throws -> Int) reasy

// CHECK-LABEL: sil hidden @$s26mandatory_inlining_reasync20callsReasyncFunctionSiyF : $@convention(thin) () -> Int {
// CHECK: [[FN:%.*]] = function_ref @$s26mandatory_inlining_reasync20callsReasyncFunctionSiyFSiyXEfU_ : $@convention(thin) () -> Int
// CHECK-NEXT: [[CONV:%.*]] = convert_function [[FN]] : $@convention(thin) () -> Int to $@convention(thin) @noescape () -> Int
// CHECK-NEXT: [[THICK:%.*]] = thin_to_thick_function [[CONV]] : $@convention(thin) @noescape () -> Int to $@noescape @callee_guaranteed () -> Int
// CHECK-NEXT: [[THICK:%.*]] = thin_to_thick_function [[FN]] : $@convention(thin) () -> Int to $@noescape @callee_guaranteed () -> Int
// FIXME: it looks like the hop is being removed but not this instruction
// CHECK-NEXT: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: br bb1
18 changes: 12 additions & 6 deletions validation-test/compiler_crashers_2_fixed/sr12723.swift
Original file line number Diff line number Diff line change
@@ -35,35 +35,41 @@ func cContext() {
let c = SR12723_C { app in app() }

proxy(c.function)
// expected-error@-1 {{cannot convert value of type '(@convention(c) () -> Void) -> Void' to expected argument type '(() -> Void) -> Void'}}
// expected-error@-1 {{converting non-escaping value to '@convention(c) () -> Void' may allow it to escape}}
// expected-error@-2 {{cannot convert value of type '(@convention(c) () -> Void) -> Void' to expected argument type '(() -> Void) -> Void'}}

let _ : (@convention(block) () -> Void) -> Void = c.function
// expected-error@-1 {{cannot convert value of type '(@convention(c) () -> Void) -> Void' to specified type '(@convention(block) () -> Void) -> Void'}}
// expected-error@-1 {{converting non-escaping value to '@convention(c) () -> Void' may allow it to escape}}
// expected-error@-2 {{cannot convert value of type '(@convention(c) () -> Void) -> Void' to specified type '(@convention(block) () -> Void) -> Void'}}

let _ : (@convention(c) () -> Void) -> Void = c.function // OK

let _ : (@convention(thin) () -> Void) -> Void = c.function // OK

let _ : (() -> Void) -> Void = c.function
// expected-error@-1 {{cannot convert value of type '(@convention(c) () -> Void) -> Void' to specified type '(() -> Void) -> Void'}}
// expected-error@-1 {{converting non-escaping value to '@convention(c) () -> Void' may allow it to escape}}
// expected-error@-2 {{cannot convert value of type '(@convention(c) () -> Void) -> Void' to specified type '(() -> Void) -> Void'}}

}

func thinContext() {
let thin = SR12723_Thin { app in app() }

proxy(thin.function)
// expected-error@-1 {{cannot convert value of type '(@convention(thin) () -> Void) -> Void' to expected argument type '(() -> Void) -> Void'}}
// expected-error@-1 {{converting non-escaping value to '@convention(thin) () -> Void' may allow it to escape}}
// expected-error@-2 {{cannot convert value of type '(@escaping @convention(thin) () -> Void) -> Void' to expected argument type '(() -> Void) -> Void'}}

let _ : (@convention(block) () -> Void) -> Void = thin.function
// expected-error@-1 {{cannot convert value of type '(@convention(thin) () -> Void) -> Void' to specified type '(@convention(block) () -> Void) -> Void'}}
// expected-error@-1 {{converting non-escaping value to '@convention(thin) () -> Void' may allow it to escape}}
// expected-error@-2 {{cannot convert value of type '(@escaping @convention(thin) () -> Void) -> Void' to specified type '(@convention(block) () -> Void) -> Void'}}

let _ : (@convention(c) () -> Void) -> Void = thin.function // OK

let _ : (@convention(thin) () -> Void) -> Void = thin.function // OK

let _ : (() -> Void) -> Void = thin.function
// expected-error@-1 {{cannot convert value of type '(@convention(thin) () -> Void) -> Void' to specified type '(() -> Void) -> Void'}}
// expected-error@-1 {{converting non-escaping value to '@convention(thin) () -> Void' may allow it to escape}}
// expected-error@-2 {{cannot convert value of type '(@escaping @convention(thin) () -> Void) -> Void' to specified type '(() -> Void) -> Void'}}
}

func blockContext() {