Skip to content

Commit c98d98b

Browse files
committed
[analyzer] Fix handle leak false positive when the handle dies too early
Differential Revision: https://reviews.llvm.org/D73151
1 parent fc90222 commit c98d98b

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ class HandleState {
149149
CASE(Kind::Released)
150150
CASE(Kind::Escaped)
151151
}
152+
if (ErrorSym) {
153+
OS << " ErrorSym: ";
154+
ErrorSym->dumpToStream(OS);
155+
}
152156
}
153157

154158
LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
@@ -401,7 +405,13 @@ void FuchsiaHandleChecker::checkDeadSymbols(SymbolReaper &SymReaper,
401405
SmallVector<SymbolRef, 2> LeakedSyms;
402406
HStateMapTy TrackedHandles = State->get<HStateMap>();
403407
for (auto &CurItem : TrackedHandles) {
404-
if (!SymReaper.isDead(CurItem.first))
408+
SymbolRef ErrorSym = CurItem.second.getErrorSym();
409+
// Keeping zombie handle symbols. In case the error symbol is dying later
410+
// than the handle symbol we might produce spurious leak warnings (in case
411+
// we find out later from the status code that the handle allocation failed
412+
// in the first place).
413+
if (!SymReaper.isDead(CurItem.first) ||
414+
(ErrorSym && !SymReaper.isDead(ErrorSym)))
405415
continue;
406416
if (CurItem.second.isAllocated() || CurItem.second.maybeAllocated())
407417
LeakedSyms.push_back(CurItem.first);

clang/test/Analysis/fuchsia_handle.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,26 @@ void checkInvalidHandle2() {
6666
zx_handle_close(sa);
6767
}
6868

69+
void handleDieBeforeErrorSymbol01() {
70+
zx_handle_t sa, sb;
71+
zx_status_t status = zx_channel_create(0, &sa, &sb);
72+
if (status < 0)
73+
return;
74+
__builtin_trap();
75+
}
76+
77+
void handleDieBeforeErrorSymbol02() {
78+
zx_handle_t sa, sb;
79+
zx_status_t status = zx_channel_create(0, &sa, &sb);
80+
// expected-note@-1 {{Handle allocated through 2nd parameter}}
81+
if (status == 0) { // expected-note {{Assuming 'status' is equal to 0}}
82+
// expected-note@-1 {{Taking true branch}}
83+
return; // expected-warning {{Potential leak of handle}}
84+
// expected-note@-1 {{Potential leak of handle}}
85+
}
86+
__builtin_trap();
87+
}
88+
6989
void checkNoCrash01() {
7090
zx_handle_t sa, sb;
7191
zx_channel_create(0, &sa, &sb);

0 commit comments

Comments
 (0)