@@ -42,8 +42,14 @@ namespace {
42
42
using BrPropUserAndBlockPair = std::pair<BranchPropagatedUser, SILBasicBlock *>;
43
43
44
44
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;
47
53
48
54
// / The result error object that use to signal either that no errors were
49
55
// / found or if errors are found the specific type of error that was found.
@@ -75,8 +81,15 @@ struct State {
75
81
State (SILValue value, SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks,
76
82
ErrorBehaviorKind errorBehavior,
77
83
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) {}
80
93
81
94
void initializeAllNonConsumingUses (
82
95
ArrayRef<BranchPropagatedUser> nonConsumingUsers);
@@ -183,7 +196,7 @@ void State::initializeAllConsumingUses(
183
196
// If this user is in the same block as the value, do not visit
184
197
// predecessors. We must be extra tolerant here since we allow for
185
198
// unreachable code.
186
- if (userBlock == value-> getParentBlock () )
199
+ if (userBlock == beginBlock )
187
200
continue ;
188
201
189
202
// Then for each predecessor of this block...
@@ -203,10 +216,15 @@ void State::initializeConsumingUse(BranchPropagatedUser consumingUser,
203
216
return ;
204
217
205
218
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 " ;
210
228
});
211
229
}
212
230
@@ -228,10 +246,16 @@ void State::checkForSameBlockUseAfterFree(BranchPropagatedUser consumingUser,
228
246
// the cond branch user is in a previous block. So just bail early.
229
247
if (consumingUser.isCondBranchUser ()) {
230
248
error.handleUseAfterFree ([&]() {
231
- llvm::errs () << " Function: '" << value->getFunction ()->getName () << " '\n "
249
+ llvm::errs () << " Function: '" << beginBlock->getParent ()->getName ()
250
+ << " '\n "
232
251
<< " 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
235
259
<< " Non Consuming User: " << *iter->second << " Block: bb"
236
260
<< userBlock->getDebugID () << " \n\n " ;
237
261
});
@@ -255,10 +279,16 @@ void State::checkForSameBlockUseAfterFree(BranchPropagatedUser consumingUser,
255
279
return nonConsumingUser == &i;
256
280
}) != userBlock->end ()) {
257
281
error.handleUseAfterFree ([&] {
258
- llvm::errs () << " Function: '" << value->getFunction ()->getName () << " '\n "
282
+ llvm::errs () << " Function: '" << beginBlock->getParent ()->getName ()
283
+ << " '\n "
259
284
<< " 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
262
292
<< " Non Consuming User: " << *iter->second << " Block: bb"
263
293
<< userBlock->getDebugID () << " \n\n " ;
264
294
});
@@ -287,10 +317,17 @@ void State::checkPredsForDoubleConsume(BranchPropagatedUser consumingUser,
287
317
}
288
318
289
319
error.handleOverConsume ([&] {
290
- llvm::errs () << " Function: '" << value-> getFunction ()->getName () << " '\n "
320
+ llvm::errs () << " Function: '" << beginBlock-> getParent ()->getName () << " '\n "
291
321
<< " 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 " ;
294
331
});
295
332
}
296
333
@@ -310,10 +347,16 @@ void State::checkPredsForDoubleConsume(SILBasicBlock *userBlock) {
310
347
}
311
348
312
349
error.handleOverConsume ([&] {
313
- llvm::errs () << " Function: '" << value-> getFunction ()->getName () << " '\n "
350
+ llvm::errs () << " Function: '" << beginBlock-> getParent ()->getName () << " '\n "
314
351
<< " 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 " ;
317
360
});
318
361
}
319
362
@@ -370,7 +413,7 @@ void State::performDataflow(DeadEndBlocks &deBlocks) {
370
413
// further to do since we do not want to visit the predecessors of our
371
414
// dominating block. On the other hand, we do want to add its successors to
372
415
// the successorBlocksThatMustBeVisited set.
373
- if (block == value-> getParentBlock () )
416
+ if (block == beginBlock )
374
417
continue ;
375
418
376
419
// Then for each predecessor of this block:
@@ -405,11 +448,16 @@ void State::checkDataflowEndState(DeadEndBlocks &deBlocks) {
405
448
406
449
// If we are supposed to error on leaks, do so now.
407
450
error.handleLeak ([&] {
408
- llvm::errs () << " Function: '" << value->getFunction ()->getName () << " '\n "
451
+ llvm::errs () << " Function: '" << beginBlock->getParent ()->getName ()
452
+ << " '\n "
409
453
<< " 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 " ;
413
461
for (auto *succBlock : successorBlocksThatMustBeVisited) {
414
462
llvm::errs () << " bb" << succBlock->getDebugID ();
415
463
}
@@ -434,10 +482,18 @@ void State::checkDataflowEndState(DeadEndBlocks &deBlocks) {
434
482
}
435
483
436
484
error.handleUseAfterFree ([&] {
437
- llvm::errs () << " Function: '" << value->getFunction ()->getName () << " '\n "
485
+ llvm::errs () << " Function: '" << beginBlock->getParent ()->getName ()
486
+ << " '\n "
438
487
<< " Found use after free due to unvisited non lifetime "
439
488
" 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 " ;
441
497
for (auto &pair : blocksWithNonConsumingUses) {
442
498
llvm::errs () << " User:" << *pair.second << " Block: bb"
443
499
<< pair.first ->getDebugID () << " \n " ;
0 commit comments