@@ -31,11 +31,8 @@ namespace {
3131// / A utility for verifying memory lifetime.
3232// /
3333// / The MemoryLifetime utility checks the lifetime of memory locations.
34- // / This is limited to memory locations which are guaranteed to be not aliased,
35- // / like @in or @inout parameters. Also, alloc_stack locations are handled.
36- // /
37- // / In addition to verification, the MemoryLifetime class can be used as utility
38- // / (e.g. base class) for optimizations, which need to compute memory lifetime.
34+ // / This is limited to memory locations which can be handled by
35+ // / `MemoryLocations`.
3936class MemoryLifetimeVerifier {
4037
4138 using Bits = MemoryLocations::Bits;
@@ -178,6 +175,16 @@ static bool isTrivialEnumElem(EnumElementDecl *elem, SILType enumType,
178175 enumType.getEnumElementType (elem, function).isTrivial (*function);
179176}
180177
178+ static bool injectsNoPayloadCase (InjectEnumAddrInst *IEAI) {
179+ if (!IEAI->getElement ()->hasAssociatedValues ())
180+ return true ;
181+ SILType enumType = IEAI->getOperand ()->getType ();
182+ SILFunction *function = IEAI->getFunction ();
183+ SILType elemType = enumType.getEnumElementType (IEAI->getElement (), function);
184+ // Handle empty types (e.g. the empty tuple) as no-payload.
185+ return elemType.isEmpty (*function);
186+ }
187+
181188static bool isOrHasEnum (SILType type) {
182189 return type.getASTType ().findIf ([](Type ty) {
183190 return ty->getEnumOrBoundGenericEnum () != nullptr ;
@@ -349,7 +356,7 @@ void MemoryLifetimeVerifier::initDataflowInBlock(SILBasicBlock *block,
349356 case SILInstructionKind::InjectEnumAddrInst: {
350357 auto *IEAI = cast<InjectEnumAddrInst>(&I);
351358 int enumIdx = locations.getLocationIdx (IEAI->getOperand ());
352- if (enumIdx >= 0 && !IEAI-> getElement ()-> hasAssociatedValues ( )) {
359+ if (enumIdx >= 0 && injectsNoPayloadCase (IEAI )) {
353360 // This is a bit tricky: an injected no-payload case means that the
354361 // "full" enum is initialized. So, for the purpose of dataflow, we
355362 // treat it like a full initialization of the payload data.
@@ -588,7 +595,7 @@ void MemoryLifetimeVerifier::checkBlock(SILBasicBlock *block, Bits &bits) {
588595 case SILInstructionKind::InjectEnumAddrInst: {
589596 auto *IEAI = cast<InjectEnumAddrInst>(&I);
590597 int enumIdx = locations.getLocationIdx (IEAI->getOperand ());
591- if (enumIdx >= 0 && !IEAI-> getElement ()-> hasAssociatedValues ( )) {
598+ if (enumIdx >= 0 && injectsNoPayloadCase (IEAI )) {
592599 // Again, an injected no-payload case is treated like a "full"
593600 // initialization. See initDataflowInBlock().
594601 requireBitsClear (bits & nonTrivialLocations, IEAI->getOperand (), &I);
0 commit comments