Skip to content

Commit cf451c2

Browse files
authored
Merge pull request swiftlang#30228 from slavapestov/stronger-invariant-apply-inst-substitution-map
SIL: Verify that the substitution map of an apply instruction matches the callee
2 parents 97d8c99 + 5aee910 commit cf451c2

File tree

5 files changed

+24
-19
lines changed

5 files changed

+24
-19
lines changed

include/swift/SIL/TypeSubstCloner.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
8282
// substitutions may be different from the original ones, e.g.
8383
// there can be less substitutions.
8484
RecursiveSubs = SubstitutionMap::get(
85-
AI.getFunction()
86-
->getLoweredFunctionType()
87-
->getInvocationGenericSignature(),
85+
LoweredFnTy->getSubstGenericSignature(),
8886
Subs);
8987

9088
// Use the new set of substitutions to compute the new

lib/SIL/SILVerifier.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,17 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
13081308
});
13091309
}
13101310

1311+
if (subs.getGenericSignature()->getCanonicalSignature() !=
1312+
fnTy->getSubstGenericSignature()->getCanonicalSignature()) {
1313+
llvm::dbgs() << "substitution map's generic signature: ";
1314+
subs.getGenericSignature()->print(llvm::dbgs());
1315+
llvm::dbgs() << "\n";
1316+
llvm::dbgs() << "callee's generic signature: ";
1317+
fnTy->getSubstGenericSignature()->print(llvm::dbgs());
1318+
llvm::dbgs() << "\n";
1319+
require(false,
1320+
"Substitution map does not match callee in apply instruction");
1321+
}
13111322
// Apply the substitutions.
13121323
return fnTy->substGenericArgs(F.getModule(), subs, F.getTypeExpansionContext());
13131324
}

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,15 +1927,6 @@ static void prepareCallArguments(ApplySite AI, SILBuilder &Builder,
19271927
}
19281928
}
19291929

1930-
/// Return a substituted callee function type.
1931-
static CanSILFunctionType
1932-
getCalleeSubstFunctionType(SILValue Callee, SubstitutionMap Subs,
1933-
TypeExpansionContext context) {
1934-
// Create a substituted callee type.
1935-
auto CanFnTy = Callee->getType().castTo<SILFunctionType>();
1936-
return CanFnTy->substGenericArgs(*Callee->getModule(), Subs, context);
1937-
}
1938-
19391930
/// Create a new apply based on an old one, but with a different
19401931
/// function being applied.
19411932
static ApplySite replaceWithSpecializedCallee(ApplySite AI,
@@ -1949,13 +1940,16 @@ static ApplySite replaceWithSpecializedCallee(ApplySite AI,
19491940
prepareCallArguments(AI, Builder, ReInfo, Arguments, StoreResultTo);
19501941

19511942
// Create a substituted callee type.
1943+
auto CanFnTy = Callee->getType().castTo<SILFunctionType>();
19521944
SubstitutionMap Subs;
19531945
if (ReInfo.getSpecializedType()->isPolymorphic()) {
19541946
Subs = ReInfo.getCallerParamSubstitutionMap();
1947+
Subs = SubstitutionMap::get(CanFnTy->getSubstGenericSignature(), Subs);
19551948
}
19561949

19571950
auto CalleeSubstFnTy =
1958-
getCalleeSubstFunctionType(Callee, Subs, ReInfo.getResilienceExpansion());
1951+
CanFnTy->substGenericArgs(*Callee->getModule(), Subs,
1952+
ReInfo.getResilienceExpansion());
19591953
auto CalleeSILSubstFnTy = SILType::getPrimitiveObjectType(CalleeSubstFnTy);
19601954
SILFunctionConventions substConv(CalleeSubstFnTy, Builder.getModule());
19611955

@@ -2453,6 +2447,8 @@ void swift::trySpecializeApplyOfGeneric(
24532447
Arguments.push_back(Op.get());
24542448
}
24552449
auto Subs = ReInfo.getCallerParamSubstitutionMap();
2450+
auto FnTy = Thunk->getLoweredFunctionType();
2451+
Subs = SubstitutionMap::get(FnTy->getSubstGenericSignature(), Subs);
24562452
auto *NewPAI = Builder.createPartialApply(
24572453
PAI->getLoc(), FRI, Subs, Arguments,
24582454
PAI->getType().getAs<SILFunctionType>()->getCalleeConvention(),

test/SILOptimizer/devirt_default_witness_method.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public protocol ResilientProtocolWithGeneric {
4343
func defaultB<T: Q>(_: T)
4444
}
4545

46-
sil @defaultB : $@convention(witness_method: ResilientProtocolWithGeneric) <Self where Self : ResilientProtocolWithGeneric><T where T : P> (@in T, @in_guaranteed Self) -> () {
46+
sil @defaultB : $@convention(witness_method: ResilientProtocolWithGeneric) <Self where Self : ResilientProtocolWithGeneric><T where T : Q> (@in T, @in_guaranteed Self) -> () {
4747
bb0(%0 : $*T, %1 : $*Self):
4848
%result = tuple ()
4949
return %result : $()
@@ -89,8 +89,8 @@ bb0(%0 : $*ConformingGenericStruct<Int>):
8989

9090
// CHECK-LABEL: test_devirt_of_inner_generic_default_witness_method
9191
// CHECK: bb0(%0 : $*ConformingGenericStruct<Int>, %1 : $*Int):
92-
// CHECK: [[FN:%[0-9]+]] = function_ref @defaultB : $@convention(witness_method: ResilientProtocolWithGeneric) <τ_0_0 where τ_0_0 : ResilientProtocolWithGeneric><τ_1_0 where τ_1_0 : P> (@in τ_1_0, @in_guaranteed τ_0_0) -> ()
93-
// CHECK: [[RESULT:%[0-9]+]] = apply [[FN]]<ConformingGenericStruct<Int>, Int>(%1, %0) : $@convention(witness_method: ResilientProtocolWithGeneric) <τ_0_0 where τ_0_0 : ResilientProtocolWithGeneric><τ_1_0 where τ_1_0 : P> (@in τ_1_0, @in_guaranteed τ_0_0) -> ()
92+
// CHECK: [[FN:%[0-9]+]] = function_ref @defaultB : $@convention(witness_method: ResilientProtocolWithGeneric) <τ_0_0 where τ_0_0 : ResilientProtocolWithGeneric><τ_1_0 where τ_1_0 : Q> (@in τ_1_0, @in_guaranteed τ_0_0) -> ()
93+
// CHECK: [[RESULT:%[0-9]+]] = apply [[FN]]<ConformingGenericStruct<Int>, Int>(%1, %0) : $@convention(witness_method: ResilientProtocolWithGeneric) <τ_0_0 where τ_0_0 : ResilientProtocolWithGeneric><τ_1_0 where τ_1_0 : Q> (@in τ_1_0, @in_guaranteed τ_0_0) -> ()
9494
// CHECK: return [[RESULT]] : $()
9595
// CHECK: }
9696
sil hidden @test_devirt_of_inner_generic_default_witness_method : $@convention(thin) (@in_guaranteed ConformingGenericStruct<Int>, @in Int) -> () {

test/SILOptimizer/devirt_default_witness_method_ownership.sil

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public protocol ResilientProtocolWithGeneric {
4343
func defaultB<T: Q>(_: T)
4444
}
4545

46-
sil @defaultB : $@convention(witness_method: ResilientProtocolWithGeneric) <Self where Self : ResilientProtocolWithGeneric><T where T : P> (@in T, @in_guaranteed Self) -> () {
46+
sil @defaultB : $@convention(witness_method: ResilientProtocolWithGeneric) <Self where Self : ResilientProtocolWithGeneric><T where T : Q> (@in T, @in_guaranteed Self) -> () {
4747
bb0(%0 : $*T, %1 : $*Self):
4848
%result = tuple ()
4949
return %result : $()
@@ -89,8 +89,8 @@ bb0(%0 : $*ConformingGenericStruct<Int>):
8989

9090
// CHECK-LABEL: test_devirt_of_inner_generic_default_witness_method
9191
// CHECK: bb0(%0 : $*ConformingGenericStruct<Int>, %1 : $*Int):
92-
// CHECK: [[FN:%[0-9]+]] = function_ref @defaultB : $@convention(witness_method: ResilientProtocolWithGeneric) <τ_0_0 where τ_0_0 : ResilientProtocolWithGeneric><τ_1_0 where τ_1_0 : P> (@in τ_1_0, @in_guaranteed τ_0_0) -> ()
93-
// CHECK: [[RESULT:%[0-9]+]] = apply [[FN]]<ConformingGenericStruct<Int>, Int>(%1, %0) : $@convention(witness_method: ResilientProtocolWithGeneric) <τ_0_0 where τ_0_0 : ResilientProtocolWithGeneric><τ_1_0 where τ_1_0 : P> (@in τ_1_0, @in_guaranteed τ_0_0) -> ()
92+
// CHECK: [[FN:%[0-9]+]] = function_ref @defaultB : $@convention(witness_method: ResilientProtocolWithGeneric) <τ_0_0 where τ_0_0 : ResilientProtocolWithGeneric><τ_1_0 where τ_1_0 : Q> (@in τ_1_0, @in_guaranteed τ_0_0) -> ()
93+
// CHECK: [[RESULT:%[0-9]+]] = apply [[FN]]<ConformingGenericStruct<Int>, Int>(%1, %0) : $@convention(witness_method: ResilientProtocolWithGeneric) <τ_0_0 where τ_0_0 : ResilientProtocolWithGeneric><τ_1_0 where τ_1_0 : Q> (@in τ_1_0, @in_guaranteed τ_0_0) -> ()
9494
// CHECK: return [[RESULT]] : $()
9595
// CHECK: }
9696
sil hidden [ossa] @test_devirt_of_inner_generic_default_witness_method : $@convention(thin) (@in_guaranteed ConformingGenericStruct<Int>, @in Int) -> () {

0 commit comments

Comments
 (0)