Skip to content

Commit 59ddb5b

Browse files
authored
[SILGen] Don't crash when calling a generic init with default args. (#7169)
In cases where a default value is used for a parameter with generic type, the argument list might be empty. In that case, we don't need to emit any arguments!
1 parent 8bdc8ec commit 59ddb5b

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3673,11 +3673,13 @@ void ArgEmitter::emitShuffle(Expr *inner,
36733673
// Emit the inner expression.
36743674
SmallVector<ManagedValue, 8> innerArgs;
36753675
SmallVector<InOutArgument, 2> innerInOutArgs;
3676-
ArgEmitter(SGF, Rep, ClaimedParamsRef(innerParams), innerArgs, innerInOutArgs,
3677-
/*foreign error*/ None, /*foreign self*/ ImportAsMemberStatus(),
3678-
(innerSpecialDests ? ArgSpecialDestArray(*innerSpecialDests)
3679-
: Optional<ArgSpecialDestArray>()))
3680-
.emitTopLevel(ArgumentSource(inner), innerOrigParamType);
3676+
if (!innerParams.empty()) {
3677+
ArgEmitter(SGF, Rep, ClaimedParamsRef(innerParams), innerArgs, innerInOutArgs,
3678+
/*foreign error*/ None, /*foreign self*/ ImportAsMemberStatus(),
3679+
(innerSpecialDests ? ArgSpecialDestArray(*innerSpecialDests)
3680+
: Optional<ArgSpecialDestArray>()))
3681+
.emitTopLevel(ArgumentSource(inner), innerOrigParamType);
3682+
}
36813683

36823684
// Make a second pass to split the inner arguments correctly.
36833685
{

test/SILGen/default_arguments_generic.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,21 @@ func bar() {
2828
// CHECK: apply [[ZANG_DFLT_1]]<Int, Double>
2929
Zim<Int>.zang(Double.self, 22)
3030
}
31+
32+
protocol Initializable {
33+
init()
34+
}
35+
struct Generic<T: Initializable> {
36+
init(_ value: T = T()) {}
37+
}
38+
struct InitializableImpl: Initializable {
39+
init() {}
40+
}
41+
// CHECK-LABEL: sil hidden @_T025default_arguments_generic17testInitializableyyF
42+
func testInitializable() {
43+
// The ".init" is required to trigger the crash that used to happen.
44+
_ = Generic<InitializableImpl>.init()
45+
// CHECK: [[INIT:%.+]] = function_ref @_T025default_arguments_generic7GenericVACyxGxcfC
46+
// CHECK: function_ref @_T025default_arguments_generic7GenericVACyxGxcfcfA_ : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> () -> @out τ_0_0
47+
// CHECK: apply [[INIT]]<InitializableImpl>({{%.+}}, {{%.+}}) : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @thin Generic<τ_0_0>.Type) -> Generic<τ_0_0>
48+
} // CHECK: end sil function '_T025default_arguments_generic17testInitializableyyF'

0 commit comments

Comments
 (0)