Skip to content

Commit c4bd50c

Browse files
Merge pull request #29569 from aschwaighofer/silgen_fix_withoutActuallyEscaping_c_closure
SILGen: Fix withoutActuallyEscaping of 'c' closures
2 parents d24537f + fce335b commit c4bd50c

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

lib/SILGen/SILGenExpr.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -5023,13 +5023,17 @@ RValue RValueEmitter::visitMakeTemporarilyEscapableExpr(
50235023
return visit(E->getSubExpr(), C);
50245024
};
50255025

5026-
// Handle @convention(block). No withoutActuallyEscaping verification yet.
5027-
if (silFnTy->getExtInfo().getRepresentation() !=
5028-
SILFunctionTypeRepresentation::Thick) {
5026+
// Handle @convention(block) an @convention(c). No withoutActuallyEscaping
5027+
// verification yet.
5028+
auto closureRepresentation = silFnTy->getExtInfo().getRepresentation();
5029+
if (closureRepresentation != SILFunctionTypeRepresentation::Thick) {
50295030
auto escapingClosure =
50305031
SGF.B.createConvertFunction(E, functionValue, escapingFnTy,
50315032
/*WithoutActuallyEscaping=*/true);
5032-
return visitSubExpr(escapingClosure, true /*isClosureConsumable*/);
5033+
bool isBlockConvention =
5034+
closureRepresentation == SILFunctionTypeRepresentation::Block;
5035+
return visitSubExpr(escapingClosure,
5036+
isBlockConvention /*isClosureConsumable*/);
50335037
}
50345038

50355039
// Convert it to an escaping function value.

test/SILGen/without_actually_escaping.swift

+13
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,16 @@ func withoutActuallyEscapingConflict() {
100100
modifyAndPerform(&localVar, closure: $0)
101101
}
102102
}
103+
104+
// CHECK-LABEL: sil [ossa] @$s25without_actually_escaping0A25ActuallyEscapingCFunction8functionyyyXC_tF
105+
// CHECK: bb0([[ARG:%.*]] : $@convention(c) @noescape () -> ()):
106+
// CHECK: [[E:%.*]] = convert_function [[ARG]] : $@convention(c) @noescape () -> () to [without_actually_escaping] $@convention(c) () -> ()
107+
// CHECK: [[F:%.*]] = function_ref @$s25without_actually_escaping0A25ActuallyEscapingCFunction8functionyyyXC_tFyyyXCXEfU_ : $@convention(thin) (@convention(c) () -> ()) -> ()
108+
// CHECK: apply [[F]]([[E]]) : $@convention(thin) (@convention(c) () -> ()) -> ()
109+
public func withoutActuallyEscapingCFunction(function: (@convention(c) () -> Void)) {
110+
withoutActuallyEscaping(function) { f in
111+
var pointer: UnsafeRawPointer? = nil
112+
pointer = unsafeBitCast(f, to: UnsafeRawPointer.self)
113+
print(pointer)
114+
}
115+
}

0 commit comments

Comments
 (0)