@@ -48,13 +48,14 @@ class MemoryLifetimeVerifier {
4848 // / alloc_stack memory locations which are used for store_borrow.
4949 Bits storeBorrowLocations;
5050
51- // / Returns true if the enum location \p locIdx can be proven to hold a
52- // / hold a trivial value (e non-payload case) at \p atInst.
53- bool isEnumTrivialAt (int locIdx, SILInstruction *atInst);
51+ // / Returns true if the location \p locIdx can be proven to hold a
52+ // / hold a trivial value (e.g. non-payload case or thin function) at
53+ // / \p atInst.
54+ bool isValueTrivialAt (int locIdx, SILInstruction *atInst);
5455
5556 // / Returns true if an instruction in the range between \p start and \p end
5657 // / stores a trivial enum case into the enum location \p loc.
57- bool storesTrivialEnum (int locIdx,
58+ bool storesTrivialValue (int locIdx,
5859 SILBasicBlock::reverse_iterator start,
5960 SILBasicBlock::reverse_iterator end);
6061
@@ -70,7 +71,7 @@ class MemoryLifetimeVerifier {
7071
7172 // / Issue an error if any bit in \p wrongBits is set.
7273 void require (const Bits &wrongBits, const Twine &complaint,
73- SILInstruction *where, bool excludeTrivialEnums = false );
74+ SILInstruction *where, bool excludeTrivialValues = false );
7475
7576 // / Require that all the subLocation bits of the location, associated with
7677 // / \p addr, are clear in \p bits.
@@ -149,7 +150,7 @@ class MemoryLifetimeVerifier {
149150 void verify ();
150151};
151152
152- bool MemoryLifetimeVerifier::isEnumTrivialAt (int locIdx,
153+ bool MemoryLifetimeVerifier::isValueTrivialAt (int locIdx,
153154 SILInstruction *atInst) {
154155 SILBasicBlock *startBlock = atInst->getParent ();
155156
@@ -158,7 +159,7 @@ bool MemoryLifetimeVerifier::isEnumTrivialAt(int locIdx,
158159 while (SILBasicBlock *block = worklist.pop ()) {
159160 auto start = (block == atInst->getParent () ? atInst->getReverseIterator ()
160161 : block->rbegin ());
161- if (storesTrivialEnum (locIdx, start, block->rend ())) {
162+ if (storesTrivialValue (locIdx, start, block->rend ())) {
162163 // Stop at trivial stores to the enum.
163164 continue ;
164165 }
@@ -191,21 +192,25 @@ static bool injectsNoPayloadCase(InjectEnumAddrInst *IEAI) {
191192 return elemType.isEmpty (*function);
192193}
193194
194- bool MemoryLifetimeVerifier::storesTrivialEnum (int locIdx,
195+ bool MemoryLifetimeVerifier::storesTrivialValue (int locIdx,
195196 SILBasicBlock::reverse_iterator start,
196197 SILBasicBlock::reverse_iterator end) {
197198 for (SILInstruction &inst : make_range (start, end)) {
198199 if (auto *IEI = dyn_cast<InjectEnumAddrInst>(&inst)) {
199200 const Location *loc = locations.getLocation (IEI->getOperand ());
200201 if (loc && loc->isSubLocation (locIdx))
201- return isTrivialEnumElem (IEI->getElement (), IEI->getOperand ()->getType (),
202+ return isTrivialEnumElem (IEI->getElement (),
203+ IEI->getOperand ()->getType (),
202204 function);
203205 }
204206 if (auto *SI = dyn_cast<StoreInst>(&inst)) {
205207 const Location *loc = locations.getLocation (SI->getDest ());
206- if (loc && loc->isSubLocation (locIdx) &&
207- SI->getSrc ()->getType ().isOrHasEnum ()) {
208- return SI->getOwnershipQualifier () == StoreOwnershipQualifier::Trivial;
208+ if (loc && loc->isSubLocation (locIdx)) {
209+ auto ty = SI->getSrc ()->getType ();
210+ if (ty.isOrHasEnum () || ty.isFunction ()) {
211+ return
212+ SI->getOwnershipQualifier () == StoreOwnershipQualifier::Trivial;
213+ }
209214 }
210215 }
211216 }
@@ -256,7 +261,7 @@ void MemoryLifetimeVerifier::require(const Bits &wrongBits,
256261 bool excludeTrivialEnums) {
257262 for (int errorLocIdx = wrongBits.find_first (); errorLocIdx >= 0 ;
258263 errorLocIdx = wrongBits.find_next (errorLocIdx)) {
259- if (!excludeTrivialEnums || !isEnumTrivialAt (errorLocIdx, where))
264+ if (!excludeTrivialEnums || !isValueTrivialAt (errorLocIdx, where))
260265 reportError (complaint, errorLocIdx, where);
261266 }
262267}
0 commit comments