Skip to content

Commit dfac905

Browse files
authored
[clang][analyzer] Extend lifetime of dynamic extent information (#163562)
Symbols used for dynamic extent information of memory regions are now kept as live as long as the memory region exists.
1 parent 22968f5 commit dfac905

File tree

4 files changed

+14
-22
lines changed

4 files changed

+14
-22
lines changed

clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ SVal getDynamicExtentWithOffset(ProgramStateRef State, SVal BufV);
5858
DefinedOrUnknownSVal getDynamicElementCountWithOffset(ProgramStateRef State,
5959
SVal BufV, QualType Ty);
6060

61+
void markAllDynamicExtentLive(ProgramStateRef State, SymbolReaper &SymReaper);
62+
6163
} // namespace ento
6264
} // namespace clang
6365

clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,5 +128,12 @@ ProgramStateRef setDynamicExtent(ProgramStateRef State, const MemRegion *MR,
128128
return State->set<DynamicExtentMap>(MR->StripCasts(), Size);
129129
}
130130

131+
void markAllDynamicExtentLive(ProgramStateRef State, SymbolReaper &SymReaper) {
132+
for (const auto &I : State->get<DynamicExtentMap>())
133+
if (SymbolRef Sym = I.second.getAsSymbol())
134+
if (SymReaper.isLiveRegion(I.first))
135+
SymReaper.markLive(Sym);
136+
}
137+
131138
} // namespace ento
132139
} // namespace clang

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,6 +1079,11 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
10791079
getCheckerManager().runCheckersForDeadSymbols(CheckedSet, Pred, SymReaper,
10801080
DiagnosticStmt, *this, K);
10811081

1082+
// Extend lifetime of symbols used for dynamic extent while the parent region
1083+
// is live. In this way size information about memory allocations is not lost
1084+
// if the region remains live.
1085+
markAllDynamicExtentLive(CleanedState, SymReaper);
1086+
10821087
// For each node in CheckedSet, generate CleanedNodes that have the
10831088
// environment, the store, and the constraints cleaned up but have the
10841089
// user-supplied states as the predecessors.

clang/test/Analysis/ArrayBound/verbose-tests.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -381,30 +381,12 @@ int *symbolicExtent(int arg) {
381381
return 0;
382382
int *mem = (int*)malloc(arg);
383383

384-
// TODO: without the following reference to 'arg', the analyzer would discard
385-
// the range information about (the symbolic value of) 'arg'. This is
386-
// incorrect because while the variable itself is inaccessible, it becomes
387-
// the symbolic extent of 'mem', so we still want to reason about its
388-
// potential values.
389-
(void)arg;
390-
391384
mem[8] = -2;
392385
// expected-warning@-1 {{Out of bound access to memory after the end of the heap area}}
393386
// expected-note@-2 {{Access of 'int' element in the heap area at index 8}}
394387
return mem;
395388
}
396389

397-
int *symbolicExtentDiscardedRangeInfo(int arg) {
398-
// This is a copy of the case 'symbolicExtent' without the '(void)arg' hack.
399-
// TODO: if the analyzer can detect the out-of-bounds access within this
400-
// testcase, then remove this and the `(void)arg` hack from `symbolicExtent`.
401-
if (arg >= 5)
402-
return 0;
403-
int *mem = (int*)malloc(arg);
404-
mem[8] = -2;
405-
return mem;
406-
}
407-
408390
void symbolicIndex(int arg) {
409391
// expected-note@+2 {{Assuming 'arg' is >= 12}}
410392
// expected-note@+1 {{Taking true branch}}
@@ -426,9 +408,5 @@ int *nothingIsCertain(int x, int y) {
426408
// {{Access of 'int' element in the heap area at an overflowing index}}
427409
// but apparently the analyzer isn't smart enough to deduce this.
428410

429-
// Keep constraints alive. (Without this, the overeager garbage collection of
430-
// constraints would _also_ prevent the intended behavior in this testcase.)
431-
(void)x;
432-
433411
return mem;
434412
}

0 commit comments

Comments
 (0)