Skip to content

Commit 6e53f8c

Browse files
committed
SIL: Fix crash in remapParentFunction() due to missing generic signature
We need to pass down the generic signature of the caller to correctly mangle the substitution map, because the replacement types in this substitution maps are interface types for the caller's generic signature. Fixes rdar://problem/161968922.
1 parent fe52553 commit 6e53f8c

File tree

4 files changed

+60
-19
lines changed

4 files changed

+60
-19
lines changed

include/swift/SIL/GenericSpecializationMangler.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ class GenericSpecializationMangler : public SpecializationMangler {
8383
return Function->getLoweredFunctionType()->getInvocationGenericSignature();
8484
}
8585

86-
void appendSubstitutions(GenericSignature sig, SubstitutionMap subs);
86+
void appendSubstitutions(GenericSignature calleeSig,
87+
SubstitutionMap calleeSubs,
88+
GenericSignature callerSig);
8789

8890
std::string manglePrespecialized(GenericSignature sig,
8991
SubstitutionMap subs);
@@ -112,7 +114,9 @@ class GenericSpecializationMangler : public SpecializationMangler {
112114
std::string mangleReabstracted(SubstitutionMap subs, bool alternativeMangling,
113115
const SmallBitVector &paramsRemoved = SmallBitVector());
114116

115-
std::string mangleForDebugInfo(GenericSignature sig, SubstitutionMap subs,
117+
std::string mangleForDebugInfo(GenericSignature calleeSig,
118+
SubstitutionMap calleeSubs,
119+
GenericSignature callerSubs,
116120
bool forInlining);
117121

118122
std::string manglePrespecialized(SubstitutionMap subs) {

include/swift/SIL/TypeSubstCloner.h

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -384,23 +384,40 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
384384
enum { ForInlining = true };
385385
/// Helper function to clone the parent function of a SILDebugScope if
386386
/// necessary when inlining said function into a new generic context.
387-
/// \param SubsMap - the substitutions of the inlining/specialization process.
388-
/// \param RemappedSig - the generic signature.
387+
/// \param SubsMap - the substitutions for the call to the callee.
388+
/// \param CalleeSig - the callee generic signature.
389389
template<typename FunctionBuilderTy>
390390
static SILFunction *remapParentFunction(FunctionBuilderTy &FuncBuilder,
391391
SILModule &M,
392392
SILFunction *ParentFunction,
393393
SubstitutionMap SubsMap,
394-
GenericSignature RemappedSig,
394+
GenericSignature CalleeSig,
395395
bool ForInlining = false) {
396396
// If the original, non-inlined version of the function had no generic
397397
// environment, there is no need to remap it.
398-
auto *OriginalEnvironment = ParentFunction->getGenericEnvironment();
399-
if (!RemappedSig || !OriginalEnvironment)
398+
auto *CalleeEnv = ParentFunction->getGenericEnvironment();
399+
if (!CalleeSig || !CalleeEnv)
400400
return ParentFunction;
401401

402-
if (SubsMap.getRecursiveProperties().hasPrimaryArchetype())
402+
// FIXME: Pass the CallerSig down directly instead of doing this.
403+
GenericSignature CallerSig;
404+
if (SubsMap.getRecursiveProperties().hasPrimaryArchetype()) {
405+
for (auto ReplacementType : SubsMap.getReplacementTypes()) {
406+
ReplacementType.visit([&](Type t) {
407+
if (t->is<PrimaryArchetypeType>() || t->is<PackArchetypeType>()) {
408+
auto sig =
409+
t->castTo<ArchetypeType>()->getGenericEnvironment()
410+
->getGenericSignature();
411+
if (!CallerSig)
412+
CallerSig = sig;
413+
else
414+
ASSERT(CallerSig.getPointer() == sig.getPointer());
415+
}
416+
});
417+
}
418+
403419
SubsMap = SubsMap.mapReplacementTypesOutOfContext();
420+
}
404421

405422
// One abstract function in the debug info can only have one set of variables
406423
// and types. We check if the function is called with non-identity substitutions
@@ -419,7 +436,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
419436
Mangle::GenericSpecializationMangler Mangler(M.getASTContext(), ParentFunction,
420437
IsNotSerialized);
421438
std::string MangledName =
422-
Mangler.mangleForDebugInfo(RemappedSig, SubsMap, ForInlining);
439+
Mangler.mangleForDebugInfo(CalleeSig, SubsMap, CallerSig, ForInlining);
423440

424441
if (ParentFunction->getName() == MangledName)
425442
return ParentFunction;
@@ -443,7 +460,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
443460
// undead.
444461
if (ParentFunction->empty()) {
445462
FuncBuilder.eraseFunction(ParentFunction);
446-
ParentFunction->setGenericEnvironment(OriginalEnvironment);
463+
ParentFunction->setGenericEnvironment(CalleeEnv);
447464
}
448465
}
449466
}

lib/SIL/Utils/GenericSpecializationMangler.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,16 @@ std::string SpecializationMangler::finalize() {
9191
//===----------------------------------------------------------------------===//
9292

9393
void GenericSpecializationMangler::
94-
appendSubstitutions(GenericSignature sig, SubstitutionMap subs) {
94+
appendSubstitutions(GenericSignature calleeSig,
95+
SubstitutionMap calleeSubs,
96+
GenericSignature callerSig) {
9597
bool First = true;
96-
sig->forEachParam([&](GenericTypeParamType *ParamType, bool Canonical) {
98+
calleeSig->forEachParam([&](GenericTypeParamType *ParamType, bool Canonical) {
9799
if (Canonical) {
98100
auto ty = Type(ParamType);
99-
auto substTy = ty.subst(subs);
101+
auto substTy = ty.subst(calleeSubs);
100102
auto canTy = substTy->getCanonicalType();
101-
appendType(canTy, nullptr);
103+
appendType(canTy, callerSig);
102104
appendListSeparator(First);
103105
}
104106
});
@@ -108,7 +110,7 @@ appendSubstitutions(GenericSignature sig, SubstitutionMap subs) {
108110
std::string GenericSpecializationMangler::
109111
manglePrespecialized(GenericSignature sig, SubstitutionMap subs) {
110112
beginMangling();
111-
appendSubstitutions(sig, subs);
113+
appendSubstitutions(sig, subs, GenericSignature());
112114
appendSpecializationOperator("Ts");
113115
return finalize();
114116
}
@@ -117,7 +119,7 @@ std::string GenericSpecializationMangler::
117119
mangleNotReabstracted(SubstitutionMap subs,
118120
const SmallBitVector &paramsRemoved) {
119121
beginMangling();
120-
appendSubstitutions(getGenericSignature(), subs);
122+
appendSubstitutions(getGenericSignature(), subs, GenericSignature());
121123
appendOperator("T");
122124
appendRemovedParams(paramsRemoved);
123125
appendSpecializationOperator("G");
@@ -128,7 +130,7 @@ std::string GenericSpecializationMangler::
128130
mangleReabstracted(SubstitutionMap subs, bool alternativeMangling,
129131
const SmallBitVector &paramsRemoved) {
130132
beginMangling();
131-
appendSubstitutions(getGenericSignature(), subs);
133+
appendSubstitutions(getGenericSignature(), subs, GenericSignature());
132134
appendOperator("T");
133135
appendRemovedParams(paramsRemoved);
134136

@@ -147,9 +149,10 @@ void GenericSpecializationMangler::appendRemovedParams(const SmallBitVector &par
147149
}
148150

149151
std::string GenericSpecializationMangler::
150-
mangleForDebugInfo(GenericSignature sig, SubstitutionMap subs, bool forInlining) {
152+
mangleForDebugInfo(GenericSignature calleeSig, SubstitutionMap calleeSubs,
153+
GenericSignature callerSig, bool forInlining) {
151154
beginMangling();
152-
appendSubstitutions(sig, subs);
155+
appendSubstitutions(calleeSig, calleeSubs, callerSig);
153156
appendSpecializationOperator(forInlining ? "Ti" : "TG");
154157
return finalize();
155158
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-frontend -emit-sil -O %s
2+
3+
extension Array: Comparable where Element: Comparable {
4+
public static func < (lhs: Array<Element>, rhs: Array<Element>) -> Bool {
5+
// Contents do not matter
6+
for (l, r) in zip(lhs, rhs) { if l != r { return l < r } }
7+
return lhs.count < rhs.count
8+
}
9+
}
10+
11+
public struct Wrapper<Symbol: Hashable & Comparable>: Hashable {
12+
public var partitions: PartitionSet<Array<Symbol>>
13+
}
14+
15+
public struct PartitionSet<Symbol: Hashable & Comparable>: Equatable, Hashable {
16+
public var partitions: Set<Set<Symbol>>
17+
}

0 commit comments

Comments
 (0)