Skip to content

Commit 7c9f13a

Browse files
committed
SILGen: Add missing processing to reabstraction fast-path.
Calling into foreign-convention functions requires bridging, and the code that bypassed reabstraction conversions failed to take this into account. Fixes rdar://89319249.
1 parent edf98aa commit 7c9f13a

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ SubstitutionMap SILGenModule::mapSubstitutionsForWitnessOverride(
6868
/// Return the abstraction pattern to use when calling a function value.
6969
static AbstractionPattern
7070
getIndirectApplyAbstractionPattern(SILGenFunction &SGF,
71+
AbstractionPattern pattern,
7172
CanFunctionType fnType) {
7273
assert(fnType);
73-
AbstractionPattern pattern(fnType);
7474
switch (fnType->getRepresentation()) {
7575
case FunctionTypeRepresentation::Swift:
7676
case FunctionTypeRepresentation::Thin:
@@ -875,9 +875,9 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
875875

876876
ManagedValue fn = SGF.emitRValueAsSingleValue(e);
877877
auto substType = cast<FunctionType>(e->getType()->getCanonicalType());
878-
878+
auto origType = AbstractionPattern(substType);
879879
// When calling an C or block function, there's implicit bridging.
880-
auto origType = getIndirectApplyAbstractionPattern(SGF, substType);
880+
origType = getIndirectApplyAbstractionPattern(SGF, origType, substType);
881881

882882
setCallee(Callee::forIndirect(fn, origType, substType, e));
883883
}
@@ -1171,10 +1171,6 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
11711171
}
11721172

11731173
void visitMemberRefExpr(MemberRefExpr *e) {
1174-
// If we're loading a closure-type property out of a generic aggregate,
1175-
// we might reabstract it under normal circumstances, but since we're
1176-
// going to apply it immediately here, there's no reason to. We can
1177-
// invoke the function value at whatever abstraction level we get.
11781174
assert(isa<VarDecl>(e->getMember().getDecl()));
11791175

11801176
// Any writebacks for this access are tightly scoped.
@@ -1186,9 +1182,12 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
11861182

11871183
ManagedValue fn = SGF.emitLoadOfLValue(e, std::move(lv), SGFContext())
11881184
.getAsSingleValue(SGF, e);
1189-
1190-
setCallee(Callee::forIndirect(fn, lv.getOrigFormalType(),
1191-
cast<FunctionType>(lv.getSubstFormalType()), e));
1185+
auto substType = cast<FunctionType>(lv.getSubstFormalType());
1186+
auto origType = lv.getOrigFormalType();
1187+
// When calling an C or block function, there's implicit bridging.
1188+
origType = getIndirectApplyAbstractionPattern(SGF, origType, substType);
1189+
1190+
setCallee(Callee::forIndirect(fn, origType, substType, e));
11921191
}
11931192

11941193
void visitAbstractClosureExpr(AbstractClosureExpr *e) {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -verify %s
2+
// REQUIRES: objc_interop
3+
4+
import Foundation
5+
6+
struct Wrapper {
7+
let closure: @convention(c) ([Int]) -> Void
8+
9+
func callIt() {
10+
self.closure([])
11+
}
12+
}

0 commit comments

Comments
 (0)