@@ -460,6 +460,7 @@ namespace {
460460 void handleStoreUse (unsigned UseID);
461461 void handleLoadUse (const DIMemoryUse &Use);
462462 void handleLoadForTypeOfSelfUse (DIMemoryUse &Use);
463+ void handleTypeOfSelfUse (DIMemoryUse &Use);
463464 void handleInOutUse (const DIMemoryUse &Use);
464465 void handleEscapeUse (const DIMemoryUse &Use);
465466
@@ -530,6 +531,7 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
530531 switch (Use.Kind ) {
531532 case DIUseKind::Load:
532533 case DIUseKind::LoadForTypeOfSelf:
534+ case DIUseKind::TypeOfSelf:
533535 case DIUseKind::Escape:
534536 continue ;
535537 case DIUseKind::Assign:
@@ -787,6 +789,9 @@ void LifetimeChecker::doIt() {
787789 case DIUseKind::LoadForTypeOfSelf:
788790 handleLoadForTypeOfSelfUse (Use);
789791 break ;
792+ case DIUseKind::TypeOfSelf:
793+ handleTypeOfSelfUse (Use);
794+ break ;
790795 }
791796 }
792797
@@ -835,6 +840,35 @@ void LifetimeChecker::handleLoadUse(const DIMemoryUse &Use) {
835840 return handleLoadUseFailure (Use, IsSuperInitComplete, FailedSelfUse);
836841}
837842
843+ static void replaceValueMetatypeInstWithMetatypeArgument (
844+ ValueMetatypeInst *valueMetatype) {
845+ SILValue metatypeArgument = valueMetatype->getFunction ()->getSelfArgument ();
846+
847+ // SILFunction parameter types never have a DynamicSelfType, since it only
848+ // makes sense in the context of a given method's body. Since the
849+ // value_metatype instruction might produce a DynamicSelfType we have to
850+ // cast the metatype argument.
851+ //
852+ // FIXME: Semantically, we're "opening" the class metatype here to produce
853+ // the "opened" DynamicSelfType. Ideally it would be modeled as an opened
854+ // archetype associated with the original metatype or class instance value,
855+ // instead of as a "global" type.
856+ auto metatypeSelfType = metatypeArgument->getType ()
857+ .castTo <MetatypeType>().getInstanceType ();
858+ auto valueSelfType = valueMetatype->getType ()
859+ .castTo <MetatypeType>().getInstanceType ();
860+ if (metatypeSelfType != valueSelfType) {
861+ assert (metatypeSelfType ==
862+ cast<DynamicSelfType>(valueSelfType).getSelfType ());
863+
864+ SILBuilderWithScope B (valueMetatype);
865+ metatypeArgument = B.createUncheckedTrivialBitCast (
866+ valueMetatype->getLoc (), metatypeArgument,
867+ valueMetatype->getType ());
868+ }
869+ replaceAllSimplifiedUsesAndErase (valueMetatype, metatypeArgument);
870+ }
871+
838872void LifetimeChecker::handleLoadForTypeOfSelfUse (DIMemoryUse &Use) {
839873 bool IsSuperInitComplete, FailedSelfUse;
840874 // If the value is not definitively initialized, replace the
@@ -849,32 +883,7 @@ void LifetimeChecker::handleLoadForTypeOfSelfUse(DIMemoryUse &Use) {
849883 if (valueMetatype)
850884 break ;
851885 }
852- assert (valueMetatype);
853- SILValue metatypeArgument = load->getFunction ()->getSelfArgument ();
854-
855- // SILFunction parameter types never have a DynamicSelfType, since it only
856- // makes sense in the context of a given method's body. Since the
857- // value_metatype instruction might produce a DynamicSelfType we have to
858- // cast the metatype argument.
859- //
860- // FIXME: Semantically, we're "opening" the class metatype here to produce
861- // the "opened" DynamicSelfType. Ideally it would be modeled as an opened
862- // archetype associated with the original metatype or class instance value,
863- // instead of as a "global" type.
864- auto metatypeSelfType = metatypeArgument->getType ()
865- .castTo <MetatypeType>().getInstanceType ();
866- auto valueSelfType = valueMetatype->getType ()
867- .castTo <MetatypeType>().getInstanceType ();
868- if (metatypeSelfType != valueSelfType) {
869- assert (metatypeSelfType ==
870- cast<DynamicSelfType>(valueSelfType).getSelfType ());
871-
872- SILBuilderWithScope B (valueMetatype);
873- metatypeArgument = B.createUncheckedTrivialBitCast (
874- valueMetatype->getLoc (), metatypeArgument,
875- valueMetatype->getType ());
876- }
877- replaceAllSimplifiedUsesAndErase (valueMetatype, metatypeArgument);
886+ replaceValueMetatypeInstWithMetatypeArgument (valueMetatype);
878887
879888 // Dead loads for type-of-self must be removed.
880889 // Otherwise it's a violation of memory lifetime.
@@ -889,6 +898,20 @@ void LifetimeChecker::handleLoadForTypeOfSelfUse(DIMemoryUse &Use) {
889898 }
890899}
891900
901+ void LifetimeChecker::handleTypeOfSelfUse (DIMemoryUse &Use) {
902+ bool IsSuperInitComplete, FailedSelfUse;
903+ // If the value is not definitively initialized, replace the
904+ // value_metatype instruction with the metatype argument that was passed into
905+ // the initializer.
906+ if (!isInitializedAtUse (Use, &IsSuperInitComplete, &FailedSelfUse)) {
907+ auto *valueMetatype = cast<ValueMetatypeInst>(Use.Inst );
908+ replaceValueMetatypeInstWithMetatypeArgument (valueMetatype);
909+
910+ // Clear the Inst pointer just to be sure to avoid use-after-free.
911+ Use.Inst = nullptr ;
912+ }
913+ }
914+
892915void LifetimeChecker::emitSelfConsumedDiagnostic (SILInstruction *Inst) {
893916 if (!shouldEmitError (Inst))
894917 return ;
0 commit comments