@@ -47,13 +47,14 @@ class MemoryLifetimeVerifier {
47
47
// / alloc_stack memory locations which are used for store_borrow.
48
48
Bits storeBorrowLocations;
49
49
50
- // / Returns true if the enum location \p locIdx can be proven to hold a
51
- // / hold a trivial value (e non-payload case) at \p atInst.
52
- bool isEnumTrivialAt (int locIdx, SILInstruction *atInst);
50
+ // / Returns true if the location \p locIdx can be proven to hold a
51
+ // / hold a trivial value (e.g. non-payload case or thin function) at
52
+ // / \p atInst.
53
+ bool isValueTrivialAt (int locIdx, SILInstruction *atInst);
53
54
54
55
// / Returns true if an instruction in the range between \p start and \p end
55
56
// / stores a trivial enum case into the enum location \p loc.
56
- bool storesTrivialEnum (int locIdx,
57
+ bool storesTrivialValue (int locIdx,
57
58
SILBasicBlock::reverse_iterator start,
58
59
SILBasicBlock::reverse_iterator end);
59
60
@@ -69,7 +70,7 @@ class MemoryLifetimeVerifier {
69
70
70
71
// / Issue an error if any bit in \p wrongBits is set.
71
72
void require (const Bits &wrongBits, const Twine &complaint,
72
- SILInstruction *where, bool excludeTrivialEnums = false );
73
+ SILInstruction *where, bool excludeTrivialValues = false );
73
74
74
75
// / Require that all the subLocation bits of the location, associated with
75
76
// / \p addr, are clear in \p bits.
@@ -149,7 +150,7 @@ class MemoryLifetimeVerifier {
149
150
void verify ();
150
151
};
151
152
152
- bool MemoryLifetimeVerifier::isEnumTrivialAt (int locIdx,
153
+ bool MemoryLifetimeVerifier::isValueTrivialAt (int locIdx,
153
154
SILInstruction *atInst) {
154
155
SILBasicBlock *startBlock = atInst->getParent ();
155
156
@@ -158,7 +159,7 @@ bool MemoryLifetimeVerifier::isEnumTrivialAt(int locIdx,
158
159
while (SILBasicBlock *block = worklist.pop ()) {
159
160
auto start = (block == atInst->getParent () ? atInst->getReverseIterator ()
160
161
: block->rbegin ());
161
- if (storesTrivialEnum (locIdx, start, block->rend ())) {
162
+ if (storesTrivialValue (locIdx, start, block->rend ())) {
162
163
// Stop at trivial stores to the enum.
163
164
continue ;
164
165
}
@@ -191,21 +192,25 @@ static bool injectsNoPayloadCase(InjectEnumAddrInst *IEAI) {
191
192
return elemType.isEmpty (*function);
192
193
}
193
194
194
- bool MemoryLifetimeVerifier::storesTrivialEnum (int locIdx,
195
+ bool MemoryLifetimeVerifier::storesTrivialValue (int locIdx,
195
196
SILBasicBlock::reverse_iterator start,
196
197
SILBasicBlock::reverse_iterator end) {
197
198
for (SILInstruction &inst : make_range (start, end)) {
198
199
if (auto *IEI = dyn_cast<InjectEnumAddrInst>(&inst)) {
199
200
const Location *loc = locations.getLocation (IEI->getOperand ());
200
201
if (loc && loc->isSubLocation (locIdx))
201
- return isTrivialEnumElem (IEI->getElement (), IEI->getOperand ()->getType (),
202
+ return isTrivialEnumElem (IEI->getElement (),
203
+ IEI->getOperand ()->getType (),
202
204
function);
203
205
}
204
206
if (auto *SI = dyn_cast<StoreInst>(&inst)) {
205
207
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
+ }
209
214
}
210
215
}
211
216
}
@@ -256,7 +261,7 @@ void MemoryLifetimeVerifier::require(const Bits &wrongBits,
256
261
bool excludeTrivialEnums) {
257
262
for (int errorLocIdx = wrongBits.find_first (); errorLocIdx >= 0 ;
258
263
errorLocIdx = wrongBits.find_next (errorLocIdx)) {
259
- if (!excludeTrivialEnums || !isEnumTrivialAt (errorLocIdx, where))
264
+ if (!excludeTrivialEnums || !isValueTrivialAt (errorLocIdx, where))
260
265
reportError (complaint, errorLocIdx, where);
261
266
}
262
267
}
0 commit comments