diff --git a/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp b/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp index ffdad057774d1..cca78813f8db1 100644 --- a/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp +++ b/lib/SIL/Utils/FieldSensitivePrunedLiveness.cpp @@ -781,7 +781,7 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock( LLVM_DEBUG(llvm::dbgs() << "Has multiple defs!\n"); // Handle a live-out or live-within block with potentially multiple defs - // unsigned prevCount = boundary.getNumLastUsersAndDeadDefs(bitNo); + unsigned prevCount = boundary.getNumLastUsersAndDeadDefs(bitNo); bool isLive = isLiveOut; for (auto &inst : llvm::reverse(*block)) { LLVM_DEBUG(llvm::dbgs() << "Visiting: " << inst); @@ -861,6 +861,7 @@ void FieldSensitiveMultiDefPrunedLiveRange::findBoundariesInBlock( << " Live at beginning of block! No dead args!\n"); } - // assert(prevCount < boundary.getNumLastUsersAndDeadDefs(bitNo) && - // "findBoundariesInBlock must be called on a live block"); + assert((isLiveOut || + prevCount < boundary.getNumLastUsersAndDeadDefs(bitNo)) && + "findBoundariesInBlock must be called on a live block"); } diff --git a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift index 92cb1bc823325..d943ab243ce2c 100644 --- a/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift +++ b/test/SILOptimizer/moveonly_addresschecker_diagnostics.swift @@ -2299,7 +2299,7 @@ func copyableStructsInMoveOnlyStructNonConsuming() { // Field Sensitive Tests // /////////////////////////// -func fieldSensitiveTestReinitField () { +func fieldSensitiveTestReinitField() { var a = NonTrivialStruct() a = NonTrivialStruct() classConsume(a.k) @@ -2307,8 +2307,7 @@ func fieldSensitiveTestReinitField () { classUseMoveOnlyWithoutEscaping(a.k) } -#if false -func fieldSensitiveTestReinitFieldMultiBlock1 () { +func fieldSensitiveTestReinitFieldMultiBlock1() { var a = NonTrivialStruct() a = NonTrivialStruct() classConsume(a.k) @@ -2318,9 +2317,8 @@ func fieldSensitiveTestReinitFieldMultiBlock1 () { classUseMoveOnlyWithoutEscaping(a.k) } } -#endif -func fieldSensitiveTestReinitFieldMultiBlock2 () { +func fieldSensitiveTestReinitFieldMultiBlock2() { var a = NonTrivialStruct() // expected-error {{'a' used after consume. Lifetime extension of variable requires a copy}} a = NonTrivialStruct() classConsume(a.k) // expected-note {{consuming use}} @@ -2332,8 +2330,7 @@ func fieldSensitiveTestReinitFieldMultiBlock2 () { classUseMoveOnlyWithoutEscaping(a.k) // expected-note {{non-consuming use}} } -#if false -func fieldSensitiveTestReinitFieldMultiBlock3 () { +func fieldSensitiveTestReinitFieldMultiBlock3() { var a = NonTrivialStruct() a = NonTrivialStruct() classConsume(a.k) @@ -2346,10 +2343,10 @@ func fieldSensitiveTestReinitFieldMultiBlock3 () { classUseMoveOnlyWithoutEscaping(a.k) } -#endif -#if false -func fieldSensitiveTestReinitFieldMultiBlock4 () { +// This test sees what happens if we partially reinit along one path and do a +// full reinit along another path. +func fieldSensitiveTestReinitFieldMultiBlock4() { var a = NonTrivialStruct() a = NonTrivialStruct() classConsume(a.k) @@ -2362,4 +2359,43 @@ func fieldSensitiveTestReinitFieldMultiBlock4 () { classUseMoveOnlyWithoutEscaping(a.k) } -#endif + +func fieldSensitiveTestReinitEnumMultiBlock() { + var e = NonTrivialEnum.first // expected-error {{'e' used after consume. Lifetime extension of variable requires a copy}} + e = NonTrivialEnum.second(Klass()) + switch e { // expected-note {{consuming use}} + case .second: + e = NonTrivialEnum.third(NonTrivialStruct()) + default: + break + } + nonConsumingUseNonTrivialEnum(e) // expected-note {{non-consuming use}} +} + +func fieldSensitiveTestReinitEnumMultiBlock1() { + var e = NonTrivialEnum.first + e = NonTrivialEnum.second(Klass()) + switch e { + case .second: + e = NonTrivialEnum.third(NonTrivialStruct()) + default: + e = NonTrivialEnum.fourth(CopyableKlass()) + } + nonConsumingUseNonTrivialEnum(e) +} + +func fieldSensitiveTestReinitEnumMultiBlock2() { + var e = NonTrivialEnum.first + e = NonTrivialEnum.second(Klass()) + if boolValue { + switch e { + case .second: + e = NonTrivialEnum.third(NonTrivialStruct()) + default: + e = NonTrivialEnum.fourth(CopyableKlass()) + } + } else { + e = NonTrivialEnum.third(NonTrivialStruct()) + } + nonConsumingUseNonTrivialEnum(e) +}