Skip to content

Commit b1b0fbe

Browse files
authored
Merge pull request #26767 from gottesmm/pr-b143026be92ec6a7185359880471760ab238040f
2 parents cfaecfc + 43ea9bf commit b1b0fbe

File tree

1 file changed

+84
-28
lines changed

1 file changed

+84
-28
lines changed

lib/SIL/LinearLifetimeChecker.cpp

Lines changed: 84 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,14 @@ namespace {
4242
using BrPropUserAndBlockPair = std::pair<BranchPropagatedUser, SILBasicBlock *>;
4343

4444
struct State {
45-
/// The value that we are checking.
46-
SILValue value;
45+
/// If we are checking for a specific value, this is that value. This is only
46+
/// used for diagnostic purposes. The algorithm if this is set works on the
47+
/// parent block of the value.
48+
Optional<SILValue> value;
49+
50+
/// The block where the live range begins. If the field value is not None,
51+
/// then this is value->getParentBlock();
52+
SILBasicBlock *beginBlock;
4753

4854
/// The result error object that use to signal either that no errors were
4955
/// found or if errors are found the specific type of error that was found.
@@ -75,8 +81,15 @@ struct State {
7581
State(SILValue value, SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks,
7682
ErrorBehaviorKind errorBehavior,
7783
SmallVectorImpl<SILBasicBlock *> *leakingBlocks)
78-
: value(value), error(errorBehavior), visitedBlocks(visitedBlocks),
79-
leakingBlocks(leakingBlocks) {}
84+
: value(value), beginBlock(value->getParentBlock()), error(errorBehavior),
85+
visitedBlocks(visitedBlocks), leakingBlocks(leakingBlocks) {}
86+
87+
State(SILBasicBlock *beginBlock,
88+
SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks,
89+
ErrorBehaviorKind errorBehavior,
90+
SmallVectorImpl<SILBasicBlock *> *leakingBlocks)
91+
: value(), beginBlock(beginBlock), error(errorBehavior),
92+
visitedBlocks(visitedBlocks), leakingBlocks(leakingBlocks) {}
8093

8194
void initializeAllNonConsumingUses(
8295
ArrayRef<BranchPropagatedUser> nonConsumingUsers);
@@ -183,7 +196,7 @@ void State::initializeAllConsumingUses(
183196
// If this user is in the same block as the value, do not visit
184197
// predecessors. We must be extra tolerant here since we allow for
185198
// unreachable code.
186-
if (userBlock == value->getParentBlock())
199+
if (userBlock == beginBlock)
187200
continue;
188201

189202
// Then for each predecessor of this block...
@@ -203,10 +216,15 @@ void State::initializeConsumingUse(BranchPropagatedUser consumingUser,
203216
return;
204217

205218
error.handleOverConsume([&] {
206-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
207-
<< "Found over consume?!\n"
208-
<< "Value: " << *value << "User: " << *consumingUser
209-
<< "Block: bb" << userBlock->getDebugID() << "\n\n";
219+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName() << "'\n"
220+
<< "Found over consume?!\n";
221+
if (auto v = value) {
222+
llvm::errs() << "Value: " << *value;
223+
} else {
224+
llvm::errs() << "Value: N/A\n";
225+
}
226+
llvm::errs() << "User: " << *consumingUser << "Block: bb"
227+
<< userBlock->getDebugID() << "\n\n";
210228
});
211229
}
212230

@@ -228,10 +246,16 @@ void State::checkForSameBlockUseAfterFree(BranchPropagatedUser consumingUser,
228246
// the cond branch user is in a previous block. So just bail early.
229247
if (consumingUser.isCondBranchUser()) {
230248
error.handleUseAfterFree([&]() {
231-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
249+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName()
250+
<< "'\n"
232251
<< "Found use after free?!\n"
233-
<< "Value: " << *value
234-
<< "Consuming User: " << *consumingUser
252+
<< "Value: ";
253+
if (auto v = value) {
254+
llvm::errs() << *v;
255+
} else {
256+
llvm::errs() << "N/A. \n";
257+
}
258+
llvm::errs() << "Consuming User: " << *consumingUser
235259
<< "Non Consuming User: " << *iter->second << "Block: bb"
236260
<< userBlock->getDebugID() << "\n\n";
237261
});
@@ -255,10 +279,16 @@ void State::checkForSameBlockUseAfterFree(BranchPropagatedUser consumingUser,
255279
return nonConsumingUser == &i;
256280
}) != userBlock->end()) {
257281
error.handleUseAfterFree([&] {
258-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
282+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName()
283+
<< "'\n"
259284
<< "Found use after free?!\n"
260-
<< "Value: " << *value
261-
<< "Consuming User: " << *consumingUser
285+
<< "Value: ";
286+
if (auto v = value) {
287+
llvm::errs() << *v;
288+
} else {
289+
llvm::errs() << "N/A. \n";
290+
}
291+
llvm::errs() << "Consuming User: " << *consumingUser
262292
<< "Non Consuming User: " << *iter->second << "Block: bb"
263293
<< userBlock->getDebugID() << "\n\n";
264294
});
@@ -287,10 +317,17 @@ void State::checkPredsForDoubleConsume(BranchPropagatedUser consumingUser,
287317
}
288318

289319
error.handleOverConsume([&] {
290-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
320+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName() << "'\n"
291321
<< "Found over consume?!\n"
292-
<< "Value: " << *value << "User: " << *consumingUser
293-
<< "Block: bb" << userBlock->getDebugID() << "\n\n";
322+
<< "Value: ";
323+
if (auto v = value) {
324+
llvm::errs() << *v;
325+
} else {
326+
llvm::errs() << "N/A. \n";
327+
}
328+
329+
llvm::errs() << "User: " << *consumingUser << "Block: bb"
330+
<< userBlock->getDebugID() << "\n\n";
294331
});
295332
}
296333

@@ -310,10 +347,16 @@ void State::checkPredsForDoubleConsume(SILBasicBlock *userBlock) {
310347
}
311348

312349
error.handleOverConsume([&] {
313-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
350+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName() << "'\n"
314351
<< "Found over consume?!\n"
315-
<< "Value: " << *value << "Block: bb"
316-
<< userBlock->getDebugID() << "\n\n";
352+
<< "Value: ";
353+
if (auto v = value) {
354+
llvm::errs() << *v;
355+
} else {
356+
llvm::errs() << "N/A. \n";
357+
}
358+
359+
llvm::errs() << "Block: bb" << userBlock->getDebugID() << "\n\n";
317360
});
318361
}
319362

@@ -370,7 +413,7 @@ void State::performDataflow(DeadEndBlocks &deBlocks) {
370413
// further to do since we do not want to visit the predecessors of our
371414
// dominating block. On the other hand, we do want to add its successors to
372415
// the successorBlocksThatMustBeVisited set.
373-
if (block == value->getParentBlock())
416+
if (block == beginBlock)
374417
continue;
375418

376419
// Then for each predecessor of this block:
@@ -405,11 +448,16 @@ void State::checkDataflowEndState(DeadEndBlocks &deBlocks) {
405448

406449
// If we are supposed to error on leaks, do so now.
407450
error.handleLeak([&] {
408-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
451+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName()
452+
<< "'\n"
409453
<< "Error! Found a leak due to a consuming post-dominance "
410-
"failure!\n"
411-
<< " Value: " << *value
412-
<< " Post Dominating Failure Blocks:\n";
454+
"failure!\n";
455+
if (auto v = value) {
456+
llvm::errs() << "Value: " << *value;
457+
} else {
458+
llvm::errs() << "Value: N/A\n";
459+
}
460+
llvm::errs() << " Post Dominating Failure Blocks:\n";
413461
for (auto *succBlock : successorBlocksThatMustBeVisited) {
414462
llvm::errs() << " bb" << succBlock->getDebugID();
415463
}
@@ -434,10 +482,18 @@ void State::checkDataflowEndState(DeadEndBlocks &deBlocks) {
434482
}
435483

436484
error.handleUseAfterFree([&] {
437-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
485+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName()
486+
<< "'\n"
438487
<< "Found use after free due to unvisited non lifetime "
439488
"ending uses?!\n"
440-
<< "Value: " << *value << " Remaining Users:\n";
489+
<< "Value: ";
490+
if (auto v = value) {
491+
llvm::errs() << *v;
492+
} else {
493+
llvm::errs() << "N/A. \n";
494+
}
495+
496+
llvm::errs() << " Remaining Users:\n";
441497
for (auto &pair : blocksWithNonConsumingUses) {
442498
llvm::errs() << "User:" << *pair.second << "Block: bb"
443499
<< pair.first->getDebugID() << "\n";

0 commit comments

Comments
 (0)