@@ -3236,6 +3236,8 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
32363236 }
32373237
32383238 SmallVector<const MemRegion *, 8 > SmartPtrFieldRoots;
3239+ ProgramStateRef State = C.getState ();
3240+ bool needsStateUpdate = false ;
32393241
32403242 for (unsigned I = 0 , E = Call.getNumArgs (); I != E; ++I) {
32413243 const Expr *AE = Call.getArgExpr (I);
@@ -3247,35 +3249,29 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
32473249 continue ;
32483250
32493251 // Find a region for the argument.
3250- SVal VCall = Call.getArgSVal (I);
3251- SVal VExpr = C.getSVal (AE);
3252- const MemRegion *RCall = VCall.getAsRegion ();
3253- const MemRegion *RExpr = VExpr.getAsRegion ();
3254-
3255- const MemRegion *Base = RCall ? RCall : RExpr;
3256- if (!Base) {
3252+ SVal ArgVal = Call.getArgSVal (I);
3253+ const MemRegion *ArgRegion = ArgVal.getAsRegion ();
3254+ if (!ArgRegion) {
32573255 // Fallback: if we have a by-value record with smart pointer fields but no
32583256 // region, mark all allocated symbols as escaped
3259- ProgramStateRef State = C.getState ();
3260- ProgramStateRef NewState = escapeAllAllocatedSymbols (State);
3261- if (NewState != State)
3262- C.addTransition (NewState);
3257+ State = escapeAllAllocatedSymbols (State);
3258+ needsStateUpdate = true ;
32633259 continue ;
32643260 }
32653261
32663262 // Push direct smart owning pointer field regions only (precise root set).
3267- collectDirectSmartOwningPtrFieldRegions (Base , AE->getType (), C,
3263+ collectDirectSmartOwningPtrFieldRegions (ArgRegion , AE->getType (), C,
32683264 SmartPtrFieldRoots);
32693265 }
32703266
32713267 // Escape only from those field roots; do nothing if empty.
32723268 if (!SmartPtrFieldRoots.empty ()) {
3273- ProgramStateRef State = C.getState ();
32743269 ProgramStateRef NewState =
32753270 EscapeTrackedCallback::EscapeTrackedRegionsReachableFrom (
32763271 SmartPtrFieldRoots, State);
32773272 if (NewState != State) {
3278- C.addTransition (NewState);
3273+ State = NewState;
3274+ needsStateUpdate = true ;
32793275 } else {
32803276 // Fallback: if we have by-value record arguments but no smart pointer
32813277 // fields detected, check if any of the arguments are by-value records
@@ -3294,13 +3290,16 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
32943290 }
32953291
32963292 if (hasByValueRecordWithSmartPtr) {
3297- ProgramStateRef State = C.getState ();
3298- ProgramStateRef NewState = escapeAllAllocatedSymbols (State);
3299- if (NewState != State)
3300- C.addTransition (NewState);
3293+ State = escapeAllAllocatedSymbols (State);
3294+ needsStateUpdate = true ;
33013295 }
33023296 }
33033297 }
3298+
3299+ // Apply all state changes in a single transition
3300+ if (needsStateUpdate) {
3301+ C.addTransition (State);
3302+ }
33043303}
33053304
33063305void MallocChecker::checkPreCall (const CallEvent &Call,
0 commit comments