Skip to content

Commit 442fc68

Browse files
authored
Merge pull request #34419 from slavapestov/type-of-self-protocol-convenience-init
DI: Fix crash when value_metatype was used with a non-class 'self' type
2 parents 40ce7f6 + 37f2bc1 commit 442fc68

16 files changed

+177
-84
lines changed

include/swift/SIL/SILFunction.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -587,15 +587,18 @@ class SILFunction
587587
return getLoweredFunctionType()->hasIndirectFormalResults();
588588
}
589589

590-
/// Returns true if this function either has a self metadata argument or
591-
/// object that Self metadata may be derived from.
590+
/// Returns true if this function ie either a class method, or a
591+
/// closure that captures the 'self' value or its metatype.
592+
///
593+
/// If this returns true, DynamicSelfType can be used in the body
594+
/// of the function.
592595
///
593596
/// Note that this is not the same as hasSelfParam().
594597
///
595-
/// For closures that capture DynamicSelfType, hasSelfMetadataParam()
598+
/// For closures that capture DynamicSelfType, hasDynamicSelfMetadata()
596599
/// is true and hasSelfParam() is false. For methods on value types,
597-
/// hasSelfParam() is true and hasSelfMetadataParam() is false.
598-
bool hasSelfMetadataParam() const;
600+
/// hasSelfParam() is true and hasDynamicSelfMetadata() is false.
601+
bool hasDynamicSelfMetadata() const;
599602

600603
/// Return the mangled name of this SILFunction.
601604
StringRef getName() const { return Name; }
@@ -1084,8 +1087,8 @@ class SILFunction
10841087
return getArguments().back();
10851088
}
10861089

1087-
const SILArgument *getSelfMetadataArgument() const {
1088-
assert(hasSelfMetadataParam() && "This method can only be called if the "
1090+
const SILArgument *getDynamicSelfMetadata() const {
1091+
assert(hasDynamicSelfMetadata() && "This method can only be called if the "
10891092
"SILFunction has a self-metadata parameter");
10901093
return getArguments().back();
10911094
}

lib/IRGen/GenHeap.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,12 +1733,12 @@ void IRGenFunction::emit##ID(llvm::Value *value, Address src) { \
17331733
#undef DEFINE_STORE_WEAK_OP
17341734
#undef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE_HELPER
17351735

1736-
llvm::Value *IRGenFunction::getLocalSelfMetadata() {
1737-
assert(LocalSelf && "no local self metadata");
1736+
llvm::Value *IRGenFunction::getDynamicSelfMetadata() {
1737+
assert(SelfValue && "no local self metadata");
17381738

17391739
// If we already have a metatype, just return it.
17401740
if (SelfKind == SwiftMetatype)
1741-
return LocalSelf;
1741+
return SelfValue;
17421742

17431743
// We need to materialize a metatype. Emit the code for that once at the
17441744
// top of the function and cache the result.
@@ -1754,29 +1754,29 @@ llvm::Value *IRGenFunction::getLocalSelfMetadata() {
17541754
// with the correct value.
17551755

17561756
llvm::IRBuilderBase::InsertPointGuard guard(Builder);
1757-
auto insertPt = isa<llvm::Instruction>(LocalSelf)
1757+
auto insertPt = isa<llvm::Instruction>(SelfValue)
17581758
? std::next(llvm::BasicBlock::iterator(
1759-
cast<llvm::Instruction>(LocalSelf)))
1759+
cast<llvm::Instruction>(SelfValue)))
17601760
: CurFn->getEntryBlock().begin();
17611761
Builder.SetInsertPoint(&CurFn->getEntryBlock(), insertPt);
17621762

17631763
switch (SelfKind) {
17641764
case SwiftMetatype:
17651765
llvm_unreachable("Already handled");
17661766
case ObjCMetatype:
1767-
LocalSelf = emitObjCMetadataRefForMetadata(*this, LocalSelf);
1767+
SelfValue = emitObjCMetadataRefForMetadata(*this, SelfValue);
17681768
SelfKind = SwiftMetatype;
17691769
break;
17701770
case ObjectReference:
1771-
LocalSelf = emitDynamicTypeOfHeapObject(*this, LocalSelf,
1771+
SelfValue = emitDynamicTypeOfHeapObject(*this, SelfValue,
17721772
MetatypeRepresentation::Thick,
1773-
SILType::getPrimitiveObjectType(LocalSelfType),
1773+
SILType::getPrimitiveObjectType(SelfType),
17741774
/*allow artificial*/ false);
17751775
SelfKind = SwiftMetatype;
17761776
break;
17771777
}
17781778

1779-
return LocalSelf;
1779+
return SelfValue;
17801780
}
17811781

17821782
/// Given a non-tagged object pointer, load a pointer to its class object.

lib/IRGen/GenType.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2381,16 +2381,16 @@ unsigned IRGenModule::getBuiltinIntegerWidth(BuiltinIntegerWidth w) {
23812381
llvm_unreachable("impossible width value");
23822382
}
23832383

2384-
void IRGenFunction::setLocalSelfMetadata(CanType selfClass,
2385-
bool isExactSelfClass,
2386-
llvm::Value *value,
2387-
IRGenFunction::LocalSelfKind kind) {
2388-
assert(!LocalSelf && "already have local self metadata");
2389-
LocalSelf = value;
2384+
void IRGenFunction::setDynamicSelfMetadata(CanType selfClass,
2385+
bool isExactSelfClass,
2386+
llvm::Value *value,
2387+
IRGenFunction::DynamicSelfKind kind) {
2388+
assert(!SelfValue && "already have local self metadata");
2389+
SelfValue = value;
23902390
assert(selfClass->getClassOrBoundGenericClass()
23912391
&& "self type not a class?");
2392-
LocalSelfIsExact = isExactSelfClass;
2393-
LocalSelfType = selfClass;
2392+
SelfTypeIsExact = isExactSelfClass;
2393+
SelfType = selfClass;
23942394
SelfKind = kind;
23952395
}
23962396

lib/IRGen/IRGenFunction.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,8 @@ class IRGenFunction {
643643
~ConditionalDominanceScope();
644644
};
645645

646-
/// The kind of value LocalSelf is.
647-
enum LocalSelfKind {
646+
/// The kind of value DynamicSelf is.
647+
enum DynamicSelfKind {
648648
/// An object reference.
649649
ObjectReference,
650650
/// A Swift metatype.
@@ -653,9 +653,9 @@ class IRGenFunction {
653653
ObjCMetatype,
654654
};
655655

656-
llvm::Value *getLocalSelfMetadata();
657-
void setLocalSelfMetadata(CanType selfBaseTy, bool selfIsExact,
658-
llvm::Value *value, LocalSelfKind kind);
656+
llvm::Value *getDynamicSelfMetadata();
657+
void setDynamicSelfMetadata(CanType selfBaseTy, bool selfIsExact,
658+
llvm::Value *value, DynamicSelfKind kind);
659659

660660
private:
661661
LocalTypeDataCache &getOrCreateLocalTypeData();
@@ -669,12 +669,12 @@ class IRGenFunction {
669669
DominancePoint ActiveDominancePoint = DominancePoint::universal();
670670
ConditionalDominanceScope *ConditionalDominance = nullptr;
671671

672-
/// The value that satisfies metadata lookups for dynamic Self.
673-
llvm::Value *LocalSelf = nullptr;
672+
/// The value that satisfies metadata lookups for DynamicSelfType.
673+
llvm::Value *SelfValue = nullptr;
674674
/// If set, the dynamic Self type is assumed to be equivalent to this exact class.
675-
CanType LocalSelfType;
676-
bool LocalSelfIsExact = false;
677-
LocalSelfKind SelfKind;
675+
CanType SelfType;
676+
bool SelfTypeIsExact = false;
677+
DynamicSelfKind SelfKind;
678678
};
679679

680680
using ConditionalDominanceScope = IRGenFunction::ConditionalDominanceScope;

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,15 +1855,15 @@ static void emitEntryPointArgumentsCOrObjC(IRGenSILFunction &IGF,
18551855
}
18561856

18571857
/// Get metadata for the dynamic Self type if we have it.
1858-
static void emitLocalSelfMetadata(IRGenSILFunction &IGF) {
1859-
if (!IGF.CurSILFn->hasSelfMetadataParam())
1858+
static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) {
1859+
if (!IGF.CurSILFn->hasDynamicSelfMetadata())
18601860
return;
18611861

1862-
const SILArgument *selfArg = IGF.CurSILFn->getSelfMetadataArgument();
1862+
const SILArgument *selfArg = IGF.CurSILFn->getDynamicSelfMetadata();
18631863
auto selfTy = selfArg->getType().getASTType();
18641864
CanMetatypeType metaTy =
18651865
dyn_cast<MetatypeType>(selfTy);
1866-
IRGenFunction::LocalSelfKind selfKind;
1866+
IRGenFunction::DynamicSelfKind selfKind;
18671867
if (!metaTy)
18681868
selfKind = IRGenFunction::ObjectReference;
18691869
else {
@@ -1889,7 +1889,7 @@ static void emitLocalSelfMetadata(IRGenSILFunction &IGF) {
18891889
bool isExact = selfTy->getClassOrBoundGenericClass()->isFinal()
18901890
|| IGF.CurSILFn->isExactSelfClass();
18911891

1892-
IGF.setLocalSelfMetadata(selfTy, isExact, value, selfKind);
1892+
IGF.setDynamicSelfMetadata(selfTy, isExact, value, selfKind);
18931893
}
18941894

18951895
/// Emit the definition for the given SIL constant.
@@ -1960,7 +1960,7 @@ void IRGenSILFunction::emitSILFunction() {
19601960
emitEntryPointArgumentsCOrObjC(*this, entry->first, params, funcTy);
19611961
break;
19621962
}
1963-
emitLocalSelfMetadata(*this);
1963+
emitDynamicSelfMetadata(*this);
19641964

19651965
assert(params.empty() && "did not map all llvm params to SIL params?!");
19661966

lib/IRGen/MetadataRequest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,7 +1574,7 @@ namespace {
15741574

15751575
MetadataResponse visitDynamicSelfType(CanDynamicSelfType type,
15761576
DynamicMetadataRequest request) {
1577-
return MetadataResponse::forComplete(IGF.getLocalSelfMetadata());
1577+
return MetadataResponse::forComplete(IGF.getDynamicSelfMetadata());
15781578
}
15791579

15801580
MetadataResponse emitExistentialTypeMetadata(CanType type,
@@ -2751,8 +2751,8 @@ IRGenFunction::emitTypeMetadataRef(CanType type,
27512751

27522752
// If we're asking for the metadata of the type that dynamic Self is known
27532753
// to be equal to, we can just use the self metadata.
2754-
if (LocalSelfIsExact && LocalSelfType == type) {
2755-
return MetadataResponse::forComplete(getLocalSelfMetadata());
2754+
if (SelfTypeIsExact && SelfType == type) {
2755+
return MetadataResponse::forComplete(getDynamicSelfMetadata());
27562756
}
27572757

27582758
if (type->hasArchetype() ||

lib/SIL/IR/SILFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ void SILFunction::viewCFGOnly() const {
571571
}
572572

573573

574-
bool SILFunction::hasSelfMetadataParam() const {
574+
bool SILFunction::hasDynamicSelfMetadata() const {
575575
auto paramTypes =
576576
getConventions().getParameterSILTypes(TypeExpansionContext::minimal());
577577
if (paramTypes.empty())

lib/SIL/IR/SILInstructions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static void buildTypeDependentOperands(
8484
TypeDependentOperands.push_back(Def);
8585
}
8686
if (hasDynamicSelf)
87-
TypeDependentOperands.push_back(F.getSelfMetadataArgument());
87+
TypeDependentOperands.push_back(F.getDynamicSelfMetadata());
8888
}
8989

9090
// Collects all opened archetypes from a type and a substitutions list and form

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,9 +1391,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
13911391
if (isa<SILArgument>(V)) {
13921392
require(hasDynamicSelf,
13931393
"dynamic self operand without dynamic self type");
1394-
require(AI->getFunction()->hasSelfMetadataParam(),
1394+
require(AI->getFunction()->hasDynamicSelfMetadata(),
13951395
"self metadata operand in function without self metadata param");
1396-
require((ValueBase *)V == AI->getFunction()->getSelfMetadataArgument(),
1396+
require((ValueBase *)V == AI->getFunction()->getDynamicSelfMetadata(),
13971397
"wrong self metadata operand");
13981398
} else {
13991399
require(isa<SingleValueInstruction>(V),
@@ -3615,10 +3615,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
36153615
require(Def, "Opened archetype should be registered in SILFunction");
36163616
} else if (t->hasDynamicSelfType()) {
36173617
require(I->getFunction()->hasSelfParam() ||
3618-
I->getFunction()->hasSelfMetadataParam(),
3618+
I->getFunction()->hasDynamicSelfMetadata(),
36193619
"Function containing dynamic self type must have self parameter");
3620-
if (I->getFunction()->hasSelfMetadataParam())
3621-
Def = I->getFunction()->getArguments().back();
3620+
if (I->getFunction()->hasDynamicSelfMetadata())
3621+
Def = I->getFunction()->getDynamicSelfMetadata();
36223622
else
36233623
Def = I->getFunction()->getSelfArgument();
36243624
} else {

lib/SILGen/SILGenPoly.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3204,7 +3204,7 @@ CanSILFunctionType SILGenFunction::buildThunkType(
32043204
// If this thunk involves DynamicSelfType in any way, add a capture for it
32053205
// in case we need to recover metadata.
32063206
if (hasDynamicSelf) {
3207-
dynamicSelfType = F.getSelfMetadataArgument()->getType().getASTType();
3207+
dynamicSelfType = F.getDynamicSelfMetadata()->getType().getASTType();
32083208
if (!isa<MetatypeType>(dynamicSelfType)) {
32093209
dynamicSelfType = CanMetatypeType::get(dynamicSelfType,
32103210
MetatypeRepresentation::Thick);

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,10 @@ collectDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
14091409
Kind = DIUseKind::LoadForTypeOfSelf;
14101410
}
14111411
}
1412+
// value_metatype may also use the 'self' value directly, if it has an
1413+
// address-only type.
1414+
if (isa<ValueMetatypeInst>(User))
1415+
Kind = DIUseKind::TypeOfSelf;
14121416

14131417
// We can safely handle anything else as an escape. They should all happen
14141418
// after self.init is invoked.

lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,9 @@ enum DIUseKind {
281281
/// This instruction is a load that's only used to answer a `type(of: self)`
282282
/// question.
283283
LoadForTypeOfSelf,
284+
285+
/// This instruction is a value_metatype on the address of 'self'.
286+
TypeOfSelf
284287
};
285288

286289
/// This struct represents a single classified access to the memory object

0 commit comments

Comments
 (0)