@@ -3236,6 +3236,8 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
3236
3236
}
3237
3237
3238
3238
SmallVector<const MemRegion *, 8 > SmartPtrFieldRoots;
3239
+ ProgramStateRef State = C.getState ();
3240
+ bool needsStateUpdate = false ;
3239
3241
3240
3242
for (unsigned I = 0 , E = Call.getNumArgs (); I != E; ++I) {
3241
3243
const Expr *AE = Call.getArgExpr (I);
@@ -3247,35 +3249,29 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
3247
3249
continue ;
3248
3250
3249
3251
// 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) {
3257
3255
// Fallback: if we have a by-value record with smart pointer fields but no
3258
3256
// 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 ;
3263
3259
continue ;
3264
3260
}
3265
3261
3266
3262
// Push direct smart owning pointer field regions only (precise root set).
3267
- collectDirectSmartOwningPtrFieldRegions (Base , AE->getType (), C,
3263
+ collectDirectSmartOwningPtrFieldRegions (ArgRegion , AE->getType (), C,
3268
3264
SmartPtrFieldRoots);
3269
3265
}
3270
3266
3271
3267
// Escape only from those field roots; do nothing if empty.
3272
3268
if (!SmartPtrFieldRoots.empty ()) {
3273
- ProgramStateRef State = C.getState ();
3274
3269
ProgramStateRef NewState =
3275
3270
EscapeTrackedCallback::EscapeTrackedRegionsReachableFrom (
3276
3271
SmartPtrFieldRoots, State);
3277
3272
if (NewState != State) {
3278
- C.addTransition (NewState);
3273
+ State = NewState;
3274
+ needsStateUpdate = true ;
3279
3275
} else {
3280
3276
// Fallback: if we have by-value record arguments but no smart pointer
3281
3277
// fields detected, check if any of the arguments are by-value records
@@ -3294,13 +3290,16 @@ void MallocChecker::checkPostCall(const CallEvent &Call,
3294
3290
}
3295
3291
3296
3292
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 ;
3301
3295
}
3302
3296
}
3303
3297
}
3298
+
3299
+ // Apply all state changes in a single transition
3300
+ if (needsStateUpdate) {
3301
+ C.addTransition (State);
3302
+ }
3304
3303
}
3305
3304
3306
3305
void MallocChecker::checkPreCall (const CallEvent &Call,
0 commit comments