Skip to content

Commit d2fe619

Browse files
authored
Merge pull request #79845 from eeckstein/memory-lifetime-verifier
MemoryLifetimeVerifier: verify `inject_enum_addr`
2 parents cbba008 + 8d78f75 commit d2fe619

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

lib/SIL/Verifier/MemoryLifetimeVerifier.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -732,11 +732,15 @@ void MemoryLifetimeVerifier::checkBlock(SILBasicBlock *block, Bits &bits) {
732732
case SILInstructionKind::InjectEnumAddrInst: {
733733
auto *IEAI = cast<InjectEnumAddrInst>(&I);
734734
int enumIdx = locations.getLocationIdx(IEAI->getOperand());
735-
if (enumIdx >= 0 && injectsNoPayloadCase(IEAI)) {
736-
// Again, an injected no-payload case is treated like a "full"
737-
// initialization. See initDataflowInBlock().
738-
requireBitsClear(bits & nonTrivialLocations, IEAI->getOperand(), &I);
739-
locations.setBits(bits, IEAI->getOperand());
735+
if (enumIdx >= 0) {
736+
if (injectsNoPayloadCase(IEAI)) {
737+
// Again, an injected no-payload case is treated like a "full"
738+
// initialization. See initDataflowInBlock().
739+
requireBitsClear(bits & nonTrivialLocations, IEAI->getOperand(), &I);
740+
locations.setBits(bits, IEAI->getOperand());
741+
} else {
742+
requireBitsSet(bits, IEAI->getOperand(), &I);
743+
}
740744
}
741745
requireNoStoreBorrowLocation(IEAI->getOperand(), &I);
742746
break;

test/SIL/memory_lifetime.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,3 +850,19 @@ bb0(%0 : @owned $T, %1 : @owned $Inner):
850850
return %8
851851
}
852852

853+
sil @initfn : $@convention(thin) () -> @out T
854+
855+
sil [ossa] @inject_enum_case : $@convention(thin) () -> () {
856+
bb0:
857+
%0 = alloc_stack $Optional<T>
858+
%1 = function_ref @initfn : $@convention(thin) () -> @out T
859+
%2 = init_enum_data_addr %0, #Optional.some!enumelt
860+
%3 = apply %1(%2) : $@convention(thin) () -> @out T
861+
inject_enum_addr %0, #Optional.some!enumelt
862+
destroy_addr %0
863+
dealloc_stack %0
864+
%10 = tuple ()
865+
return %10
866+
}
867+
868+

test/SIL/memory_lifetime_failures.sil

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,3 +809,20 @@ bb0(%0 : @owned $T, %1 : @owned $Inner):
809809
return %8
810810
}
811811

812+
sil @initfn : $@convention(thin) () -> @out T
813+
814+
// CHECK: SIL memory lifetime failure in @inject_enum_case: memory is not initialized, but should be
815+
sil [ossa] @inject_enum_case : $@convention(thin) () -> () {
816+
bb0:
817+
%0 = alloc_stack $Optional<T>
818+
%1 = function_ref @initfn : $@convention(thin) () -> @out T
819+
%2 = init_enum_data_addr %0, #Optional.some!enumelt
820+
%3 = apply %1(%2) : $@convention(thin) () -> @out T
821+
destroy_addr %0
822+
inject_enum_addr %0, #Optional.some!enumelt
823+
dealloc_stack %0
824+
%10 = tuple ()
825+
return %10
826+
}
827+
828+

0 commit comments

Comments
 (0)