diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 83711be6d8ae9..29a3845a05c03 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -5024,13 +5024,17 @@ RValue RValueEmitter::visitMakeTemporarilyEscapableExpr( return visit(E->getSubExpr(), C); }; - // Handle @convention(block). No withoutActuallyEscaping verification yet. - if (silFnTy->getExtInfo().getRepresentation() != - SILFunctionTypeRepresentation::Thick) { + // Handle @convention(block) an @convention(c). No withoutActuallyEscaping + // verification yet. + auto closureRepresentation = silFnTy->getExtInfo().getRepresentation(); + if (closureRepresentation != SILFunctionTypeRepresentation::Thick) { auto escapingClosure = SGF.B.createConvertFunction(E, functionValue, escapingFnTy, /*WithoutActuallyEscaping=*/true); - return visitSubExpr(escapingClosure, true /*isClosureConsumable*/); + bool isBlockConvention = + closureRepresentation == SILFunctionTypeRepresentation::Block; + return visitSubExpr(escapingClosure, + isBlockConvention /*isClosureConsumable*/); } // Convert it to an escaping function value. diff --git a/test/SILGen/without_actually_escaping.swift b/test/SILGen/without_actually_escaping.swift index 2979157df33b5..1d5e1569e627e 100644 --- a/test/SILGen/without_actually_escaping.swift +++ b/test/SILGen/without_actually_escaping.swift @@ -100,3 +100,16 @@ func withoutActuallyEscapingConflict() { modifyAndPerform(&localVar, closure: $0) } } + +// 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: [[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)) { + withoutActuallyEscaping(function) { f in + var pointer: UnsafeRawPointer? = nil + pointer = unsafeBitCast(f, to: UnsafeRawPointer.self) + print(pointer) + } +}