@@ -355,81 +355,43 @@ bool NoStateChangeFuncVisitor::isModifiedInFrame(const ExplodedNode *N) {
355
355
return FramesModifying.count (SCtx);
356
356
}
357
357
358
- void NoStateChangeFuncVisitor::markFrameAsModifying (
359
- const StackFrameContext *SCtx) {
360
- while (SCtx) {
361
- auto p = FramesModifying.insert (SCtx);
362
- if (!p.second )
363
- break ; // Frame and all its parents already inserted.
364
- SCtx = SCtx->getParent ()->getStackFrame ();
365
- }
366
- }
367
-
368
- static const ExplodedNode *getMatchingCallExitEnd (const ExplodedNode *N) {
369
- assert (N->getLocationAs <CallEnter>());
370
- // The stackframe of the callee is only found in the nodes succeeding
371
- // the CallEnter node. CallEnter's stack frame refers to the caller.
372
- const StackFrameContext *OrigSCtx = N->getFirstSucc ()->getStackFrame ();
373
-
374
- // Similarly, the nodes preceding CallExitEnd refer to the callee's stack
375
- // frame.
376
- auto IsMatchingCallExitEnd = [OrigSCtx](const ExplodedNode *N) {
377
- return N->getLocationAs <CallExitEnd>() &&
378
- OrigSCtx == N->getFirstPred ()->getStackFrame ();
379
- };
380
- while (N && !IsMatchingCallExitEnd (N)) {
381
- assert (N->succ_size () <= 1 &&
382
- " This function is to be used on the trimmed ExplodedGraph!" );
383
- N = N->getFirstSucc ();
384
- }
385
- return N;
386
- }
387
-
388
358
void NoStateChangeFuncVisitor::findModifyingFrames (
389
359
const ExplodedNode *const CallExitBeginN) {
390
360
391
361
assert (CallExitBeginN->getLocationAs <CallExitBegin>());
392
-
362
+ const ExplodedNode *LastReturnN = CallExitBeginN;
393
363
const StackFrameContext *const OriginalSCtx =
394
364
CallExitBeginN->getLocationContext ()->getStackFrame ();
395
365
396
- const ExplodedNode *CurrCallExitBeginN = CallExitBeginN;
397
- const StackFrameContext *CurrentSCtx = OriginalSCtx;
398
-
399
- for (const ExplodedNode *CurrN = CallExitBeginN; CurrN;
400
- CurrN = CurrN->getFirstPred ()) {
401
- // Found a new inlined call.
402
- if (CurrN->getLocationAs <CallExitBegin>()) {
403
- CurrCallExitBeginN = CurrN;
404
- CurrentSCtx = CurrN->getStackFrame ();
405
- FramesModifyingCalculated.insert (CurrentSCtx);
406
- // We won't see a change in between two identical exploded nodes: skip.
407
- continue ;
366
+ const ExplodedNode *CurrN = CallExitBeginN;
367
+
368
+ do {
369
+ ProgramStateRef State = CurrN->getState ();
370
+ auto CallExitLoc = CurrN->getLocationAs <CallExitBegin>();
371
+ if (CallExitLoc) {
372
+ LastReturnN = CurrN;
408
373
}
409
374
410
- if (auto CE = CurrN->getLocationAs <CallEnter>()) {
411
- if (const ExplodedNode *CallExitEndN = getMatchingCallExitEnd (CurrN))
412
- if (wasModifiedInFunction (CurrN, CallExitEndN))
413
- markFrameAsModifying (CurrentSCtx);
414
-
415
- // We exited this inlined call, lets actualize the stack frame.
416
- CurrentSCtx = CurrN->getStackFrame ();
417
-
418
- // Stop calculating at the current function, but always regard it as
419
- // modifying, so we can avoid notes like this:
420
- // void f(Foo &F) {
421
- // F.field = 0; // note: 0 assigned to 'F.field'
422
- // // note: returning without writing to 'F.field'
423
- // }
424
- if (CE->getCalleeContext () == OriginalSCtx) {
425
- markFrameAsModifying (CurrentSCtx);
426
- break ;
375
+ FramesModifyingCalculated.insert (
376
+ CurrN->getLocationContext ()->getStackFrame ());
377
+
378
+ if (wasModifiedBeforeCallExit (CurrN, LastReturnN)) {
379
+ const StackFrameContext *SCtx = CurrN->getStackFrame ();
380
+ while (!SCtx->inTopFrame ()) {
381
+ auto p = FramesModifying.insert (SCtx);
382
+ if (!p.second )
383
+ break ; // Frame and all its parents already inserted.
384
+ SCtx = SCtx->getParent ()->getStackFrame ();
427
385
}
428
386
}
429
387
430
- if (wasModifiedBeforeCallExit (CurrN, CurrCallExitBeginN))
431
- markFrameAsModifying (CurrentSCtx);
432
- }
388
+ // Stop calculation at the call to the current function.
389
+ if (auto CE = CurrN->getLocationAs <CallEnter>())
390
+ if (CE->getCalleeContext () == OriginalSCtx)
391
+ break ;
392
+
393
+ CurrN = CurrN->getFirstPred ();
394
+ } while (CurrN);
433
395
}
434
396
435
397
PathDiagnosticPieceRef NoStateChangeFuncVisitor::VisitNode (
0 commit comments