Skip to content

Commit 5911268

Browse files
committed
[analyzer] Improve FuchsiaHandleChecker's diagnostic messages
Differential Revision: https://reviews.llvm.org/D73229
1 parent 0553257 commit 5911268

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,17 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call,
314314
// Function returns an open handle.
315315
if (hasFuchsiaAttr<AcquireHandleAttr>(FuncDecl)) {
316316
SymbolRef RetSym = Call.getReturnValue().getAsSymbol();
317+
Notes.push_back([RetSym, FuncDecl](BugReport &BR) -> std::string {
318+
auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
319+
if (auto IsInteresting = PathBR->getInterestingnessKind(RetSym)) {
320+
std::string SBuf;
321+
llvm::raw_string_ostream OS(SBuf);
322+
OS << "Function '" << FuncDecl->getNameAsString()
323+
<< "' returns an open handle";
324+
return OS.str();
325+
} else
326+
return "";
327+
});
317328
State =
318329
State->set<HStateMap>(RetSym, HandleState::getMaybeAllocated(nullptr));
319330
}
@@ -322,6 +333,7 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call,
322333
if (Arg >= FuncDecl->getNumParams())
323334
break;
324335
const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
336+
unsigned ParamDiagIdx = PVD->getFunctionScopeIndex() + 1;
325337
SymbolRef Handle =
326338
getFuchsiaHandleSymbol(PVD->getType(), Call.getArgSVal(Arg), State);
327339
if (!Handle)
@@ -335,20 +347,28 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call,
335347
reportDoubleRelease(Handle, Call.getArgSourceRange(Arg), C);
336348
return;
337349
} else {
338-
Notes.push_back([Handle](BugReport &BR) {
350+
Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string {
339351
auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
340352
if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) {
341-
return "Handle released here.";
353+
std::string SBuf;
354+
llvm::raw_string_ostream OS(SBuf);
355+
OS << "Handle released through " << ParamDiagIdx
356+
<< llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
357+
return OS.str();
342358
} else
343359
return "";
344360
});
345361
State = State->set<HStateMap>(Handle, HandleState::getReleased());
346362
}
347363
} else if (hasFuchsiaAttr<AcquireHandleAttr>(PVD)) {
348-
Notes.push_back([Handle](BugReport &BR) {
364+
Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string {
349365
auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
350366
if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) {
351-
return "Handle allocated here.";
367+
std::string SBuf;
368+
llvm::raw_string_ostream OS(SBuf);
369+
OS << "Handle allocated through " << ParamDiagIdx
370+
<< llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
371+
return OS.str();
352372
} else
353373
return "";
354374
});

clang/test/Analysis/fuchsia_handle.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ zx_status_t zx_channel_create(
2626
zx_status_t zx_handle_close(
2727
zx_handle_t handle ZX_HANDLE_RELEASE);
2828

29+
ZX_HANDLE_ACQUIRE
30+
zx_handle_t return_handle();
31+
2932
void escape1(zx_handle_t *in);
3033
void escape2(zx_handle_t in);
3134
void (*escape3)(zx_handle_t) = escape2;
@@ -117,7 +120,7 @@ void checkNoLeak06() {
117120

118121
void checkLeak01(int tag) {
119122
zx_handle_t sa, sb;
120-
if (zx_channel_create(0, &sa, &sb)) // expected-note {{Handle allocated here}}
123+
if (zx_channel_create(0, &sa, &sb)) // expected-note {{Handle allocated through 2nd parameter}}
121124
return; // expected-note@-1 {{Assuming the condition is false}}
122125
// expected-note@-2 {{Taking false branch}}
123126
use1(&sa);
@@ -129,9 +132,15 @@ void checkLeak01(int tag) {
129132
zx_handle_close(sb);
130133
}
131134

135+
void checkLeakFromReturn01(int tag) {
136+
zx_handle_t sa = return_handle(); // expected-note {{Function 'return_handle' returns an open handle}}
137+
(void)sa;
138+
} // expected-note {{Potential leak of handle}}
139+
// expected-warning@-1 {{Potential leak of handle}}
140+
132141
void checkReportLeakOnOnePath(int tag) {
133142
zx_handle_t sa, sb;
134-
if (zx_channel_create(0, &sa, &sb)) // expected-note {{Handle allocated here}}
143+
if (zx_channel_create(0, &sa, &sb)) // expected-note {{Handle allocated through 2nd parameter}}
135144
return; // expected-note@-1 {{Assuming the condition is false}}
136145
// expected-note@-2 {{Taking false branch}}
137146
zx_handle_close(sb);
@@ -161,9 +170,9 @@ void checkReportLeakOnOnePath(int tag) {
161170
void checkDoubleRelease01(int tag) {
162171
zx_handle_t sa, sb;
163172
zx_channel_create(0, &sa, &sb);
164-
// expected-note@-1 {{Handle allocated here}}
173+
// expected-note@-1 {{Handle allocated through 2nd parameter}}
165174
if (tag) // expected-note {{Assuming 'tag' is not equal to 0}}
166-
zx_handle_close(sa); // expected-note {{Handle released here}}
175+
zx_handle_close(sa); // expected-note {{Handle released through 1st parameter}}
167176
// expected-note@-2 {{Taking true branch}}
168177
zx_handle_close(sa); // expected-warning {{Releasing a previously released handle}}
169178
// expected-note@-1 {{Releasing a previously released handle}}
@@ -173,18 +182,18 @@ void checkDoubleRelease01(int tag) {
173182
void checkUseAfterFree01(int tag) {
174183
zx_handle_t sa, sb;
175184
zx_channel_create(0, &sa, &sb);
176-
// expected-note@-1 {{Handle allocated here}}
177-
// expected-note@-2 {{Handle allocated here}}
185+
// expected-note@-1 {{Handle allocated through 2nd parameter}}
186+
// expected-note@-2 {{Handle allocated through 3rd parameter}}
178187
// expected-note@+2 {{Taking true branch}}
179188
// expected-note@+1 {{Taking false branch}}
180189
if (tag) {
181190
// expected-note@-1 {{Assuming 'tag' is not equal to 0}}
182-
zx_handle_close(sa); // expected-note {{Handle released here}}
191+
zx_handle_close(sa); // expected-note {{Handle released through 1st parameter}}
183192
use1(&sa); // expected-warning {{Using a previously released handle}}
184193
// expected-note@-1 {{Using a previously released handle}}
185194
}
186195
// expected-note@-6 {{Assuming 'tag' is 0}}
187-
zx_handle_close(sb); // expected-note {{Handle released here}}
196+
zx_handle_close(sb); // expected-note {{Handle released through 1st parameter}}
188197
use2(sb); // expected-warning {{Using a previously released handle}}
189198
// expected-note@-1 {{Using a previously released handle}}
190199
}

0 commit comments

Comments
 (0)