@@ -765,6 +765,14 @@ void SILCombiner::replaceWitnessMethodInst(
765
765
eraseInstFromFunction (*WMI);
766
766
}
767
767
768
+ static bool hasUse (SILValue v, Operand *op) {
769
+ for (Operand *use : v->getUses ()) {
770
+ if (use == op)
771
+ return true ;
772
+ }
773
+ return false ;
774
+ }
775
+
768
776
// This function determines concrete type of an opened existential argument
769
777
// using ProtocolConformanceAnalysis. The concrete type of the argument can be a
770
778
// class, struct, or an enum.
@@ -839,6 +847,13 @@ SILCombiner::buildConcreteOpenedExistentialInfoFromSoleConformingType(
839
847
// Prepare the code by adding UncheckedCast instructions that cast opened
840
848
// existentials to concrete types. Set the ConcreteValue of CEI.
841
849
if (auto *OER = dyn_cast<OpenExistentialRefInst>(OAI.OpenedArchetypeValue )) {
850
+ // Make sure that the existential value outlives the apply. This is the case
851
+ // if the apply uses it as argument operand.
852
+ if (OER->getOwnershipKind () == OwnershipKind::Owned &&
853
+ !hasUse (OER, &ArgOperand)) {
854
+ return std::nullopt;
855
+ }
856
+
842
857
SILBuilderWithScope b (std::next (OER->getIterator ()), Builder);
843
858
auto loc = RegularLocation::getAutoGeneratedLocation ();
844
859
SoleCEI.ConcreteValue = b.createUncheckedRefCast (loc, OER, concreteSILType);
@@ -880,6 +895,11 @@ SILCombiner::buildConcreteOpenedExistentialInfo(Operand &ArgOperand) {
880
895
auto ConcreteValue = COEI.CEI ->ConcreteValue ;
881
896
if (ConcreteValue->getFunction ()->hasOwnership () &&
882
897
ConcreteValue->getOwnershipKind () == OwnershipKind::Owned) {
898
+ // Make sure that the existential value outlives the apply. This is the case
899
+ // if the apply uses it as argument operand.
900
+ if (!hasUse (COEI.OAI .OpenedArchetypeValue , &ArgOperand))
901
+ return std::nullopt;
902
+
883
903
SILBuilderWithScope b (COEI.OAI .OpenedArchetypeValue ->getNextInstruction (),
884
904
Builder);
885
905
auto loc = RegularLocation::getAutoGeneratedLocation ();
0 commit comments