Skip to content

Commit bd548db

Browse files
committed
ClosureSpecializer: always make a new specialized function a thin function.
This fixes a crash in IRGen (which I found with a modified compiler).
1 parent 8e8a0ef commit bd548db

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

lib/SILOptimizer/IPO/ClosureSpecializer.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,8 +536,14 @@ ClosureSpecCloner::initCloned(const CallSiteDescriptor &CallSiteDesc,
536536
NewParameterInfoList.push_back(NewPInfo);
537537
}
538538

539+
// The specialized function is always a thin function. This is important
540+
// because we may add additional parameters after the Self parameter of
541+
// witness methods. In this case the new function is not a method anymore.
542+
auto ExtInfo = ClosureUserFunTy->getExtInfo();
543+
ExtInfo = ExtInfo.withRepresentation(SILFunctionTypeRepresentation::Thin);
544+
539545
auto ClonedTy = SILFunctionType::get(
540-
ClosureUserFunTy->getGenericSignature(), ClosureUserFunTy->getExtInfo(),
546+
ClosureUserFunTy->getGenericSignature(), ExtInfo,
541547
ClosureUserFunTy->getCalleeConvention(), NewParameterInfoList,
542548
ClosureUserFunTy->getAllResults(),
543549
ClosureUserFunTy->getOptionalErrorResult(),

test/SILOptimizer/closure_specialize.sil

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,3 +426,42 @@ bb0(%0 : $Builtin.Int32, %1 : $@box Builtin.Int32):
426426
%7 = tuple ()
427427
return %7 : $()
428428
}
429+
430+
// The specialized function should always be a thin function, regardless of the
431+
// representation of the original function.
432+
433+
public protocol P {
434+
static func foo(cl: () -> Int) -> Int
435+
}
436+
437+
public struct S : P {
438+
public static func foo(cl: () -> Int) -> Int
439+
init()
440+
}
441+
442+
// CHECK-LABEL: sil shared @_TTSf1cl8closure2Si_n___TTWV4test1SS_1PS_ZFS1_3foofFT_SiSi : $@convention(thin) (@thick S.Type, Int) -> Int
443+
sil @_TTWV4test1SS_1PS_ZFS1_3foofFT_SiSi : $@convention(witness_method) (@owned @callee_owned () -> Int, @thick S.Type) -> Int {
444+
bb0(%0 : $@callee_owned () -> Int, %1 : $@thick S.Type):
445+
%3 = apply %0() : $@callee_owned () -> Int
446+
return %3 : $Int
447+
}
448+
449+
sil shared @closure2 : $@convention(thin) (Int) -> Int {
450+
bb0(%0 : $Int):
451+
return %0 : $Int
452+
}
453+
454+
sil @call_witness_method : $@convention(thin) (Int, S) -> Int {
455+
bb0(%0 : $Int, %1 : $S):
456+
%3 = function_ref @closure2 : $@convention(thin) (Int) -> Int
457+
%4 = partial_apply %3(%0) : $@convention(thin) (Int) -> Int
458+
%5 = metatype $@thick S.Type
459+
%6 = function_ref @_TTWV4test1SS_1PS_ZFS1_3foofFT_SiSi : $@convention(witness_method) (@owned @callee_owned () -> Int, @thick S.Type) -> Int
460+
%7 = apply %6(%4, %5) : $@convention(witness_method) (@owned @callee_owned () -> Int, @thick S.Type) -> Int
461+
return %7 : $Int
462+
}
463+
464+
sil_witness_table S: P module test {
465+
method #P.foo!1: @_TTWV4test1SS_1PS_ZFS1_3foofFT_SiSi
466+
}
467+

0 commit comments

Comments
 (0)