@@ -460,6 +460,7 @@ namespace {
460
460
void handleStoreUse (unsigned UseID);
461
461
void handleLoadUse (const DIMemoryUse &Use);
462
462
void handleLoadForTypeOfSelfUse (DIMemoryUse &Use);
463
+ void handleTypeOfSelfUse (DIMemoryUse &Use);
463
464
void handleInOutUse (const DIMemoryUse &Use);
464
465
void handleEscapeUse (const DIMemoryUse &Use);
465
466
@@ -530,6 +531,7 @@ LifetimeChecker::LifetimeChecker(const DIMemoryObjectInfo &TheMemory,
530
531
switch (Use.Kind ) {
531
532
case DIUseKind::Load:
532
533
case DIUseKind::LoadForTypeOfSelf:
534
+ case DIUseKind::TypeOfSelf:
533
535
case DIUseKind::Escape:
534
536
continue ;
535
537
case DIUseKind::Assign:
@@ -787,6 +789,9 @@ void LifetimeChecker::doIt() {
787
789
case DIUseKind::LoadForTypeOfSelf:
788
790
handleLoadForTypeOfSelfUse (Use);
789
791
break ;
792
+ case DIUseKind::TypeOfSelf:
793
+ handleTypeOfSelfUse (Use);
794
+ break ;
790
795
}
791
796
}
792
797
@@ -835,6 +840,35 @@ void LifetimeChecker::handleLoadUse(const DIMemoryUse &Use) {
835
840
return handleLoadUseFailure (Use, IsSuperInitComplete, FailedSelfUse);
836
841
}
837
842
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
+
838
872
void LifetimeChecker::handleLoadForTypeOfSelfUse (DIMemoryUse &Use) {
839
873
bool IsSuperInitComplete, FailedSelfUse;
840
874
// If the value is not definitively initialized, replace the
@@ -849,32 +883,7 @@ void LifetimeChecker::handleLoadForTypeOfSelfUse(DIMemoryUse &Use) {
849
883
if (valueMetatype)
850
884
break ;
851
885
}
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);
878
887
879
888
// Dead loads for type-of-self must be removed.
880
889
// Otherwise it's a violation of memory lifetime.
@@ -889,6 +898,20 @@ void LifetimeChecker::handleLoadForTypeOfSelfUse(DIMemoryUse &Use) {
889
898
}
890
899
}
891
900
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
+
892
915
void LifetimeChecker::emitSelfConsumedDiagnostic (SILInstruction *Inst) {
893
916
if (!shouldEmitError (Inst))
894
917
return ;
0 commit comments