Skip to content

Commit 2dc6776

Browse files
committed
[clang-analyzer] Fix addTransition misuse - consolidate state updates
Consolidate multiple state transitions into single update to avoid path splitting. Remove redundant state comparisons and simplify SVal handling.
1 parent 66bf4e6 commit 2dc6776

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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

33063305
void MallocChecker::checkPreCall(const CallEvent &Call,

0 commit comments

Comments
 (0)