[clang] 5911268 - [analyzer] Improve FuchsiaHandleChecker's diagnostic messages
Gabor Horvath via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 23 09:17:11 PST 2020
Author: Gabor Horvath
Date: 2020-01-23T09:16:40-08:00
New Revision: 5911268e441cc78f7c81f931dd64ed2c63078e8e
URL: https://github.com/llvm/llvm-project/commit/5911268e441cc78f7c81f931dd64ed2c63078e8e
DIFF: https://github.com/llvm/llvm-project/commit/5911268e441cc78f7c81f931dd64ed2c63078e8e.diff
LOG: [analyzer] Improve FuchsiaHandleChecker's diagnostic messages
Differential Revision: https://reviews.llvm.org/D73229
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
clang/test/Analysis/fuchsia_handle.cpp
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
index 3c04983df443..36d4f489214e 100644
--- a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
@@ -314,6 +314,17 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call,
// Function returns an open handle.
if (hasFuchsiaAttr<AcquireHandleAttr>(FuncDecl)) {
SymbolRef RetSym = Call.getReturnValue().getAsSymbol();
+ Notes.push_back([RetSym, FuncDecl](BugReport &BR) -> std::string {
+ auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
+ if (auto IsInteresting = PathBR->getInterestingnessKind(RetSym)) {
+ std::string SBuf;
+ llvm::raw_string_ostream OS(SBuf);
+ OS << "Function '" << FuncDecl->getNameAsString()
+ << "' returns an open handle";
+ return OS.str();
+ } else
+ return "";
+ });
State =
State->set<HStateMap>(RetSym, HandleState::getMaybeAllocated(nullptr));
}
@@ -322,6 +333,7 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call,
if (Arg >= FuncDecl->getNumParams())
break;
const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
+ unsigned ParamDiagIdx = PVD->getFunctionScopeIndex() + 1;
SymbolRef Handle =
getFuchsiaHandleSymbol(PVD->getType(), Call.getArgSVal(Arg), State);
if (!Handle)
@@ -335,20 +347,28 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call,
reportDoubleRelease(Handle, Call.getArgSourceRange(Arg), C);
return;
} else {
- Notes.push_back([Handle](BugReport &BR) {
+ Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string {
auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) {
- return "Handle released here.";
+ std::string SBuf;
+ llvm::raw_string_ostream OS(SBuf);
+ OS << "Handle released through " << ParamDiagIdx
+ << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
+ return OS.str();
} else
return "";
});
State = State->set<HStateMap>(Handle, HandleState::getReleased());
}
} else if (hasFuchsiaAttr<AcquireHandleAttr>(PVD)) {
- Notes.push_back([Handle](BugReport &BR) {
+ Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string {
auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) {
- return "Handle allocated here.";
+ std::string SBuf;
+ llvm::raw_string_ostream OS(SBuf);
+ OS << "Handle allocated through " << ParamDiagIdx
+ << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
+ return OS.str();
} else
return "";
});
diff --git a/clang/test/Analysis/fuchsia_handle.cpp b/clang/test/Analysis/fuchsia_handle.cpp
index 0543eb92d01f..ed8b695a1915 100644
--- a/clang/test/Analysis/fuchsia_handle.cpp
+++ b/clang/test/Analysis/fuchsia_handle.cpp
@@ -26,6 +26,9 @@ zx_status_t zx_channel_create(
zx_status_t zx_handle_close(
zx_handle_t handle ZX_HANDLE_RELEASE);
+ZX_HANDLE_ACQUIRE
+zx_handle_t return_handle();
+
void escape1(zx_handle_t *in);
void escape2(zx_handle_t in);
void (*escape3)(zx_handle_t) = escape2;
@@ -117,7 +120,7 @@ void checkNoLeak06() {
void checkLeak01(int tag) {
zx_handle_t sa, sb;
- if (zx_channel_create(0, &sa, &sb)) // expected-note {{Handle allocated here}}
+ if (zx_channel_create(0, &sa, &sb)) // expected-note {{Handle allocated through 2nd parameter}}
return; // expected-note at -1 {{Assuming the condition is false}}
// expected-note at -2 {{Taking false branch}}
use1(&sa);
@@ -129,9 +132,15 @@ void checkLeak01(int tag) {
zx_handle_close(sb);
}
+void checkLeakFromReturn01(int tag) {
+ zx_handle_t sa = return_handle(); // expected-note {{Function 'return_handle' returns an open handle}}
+ (void)sa;
+} // expected-note {{Potential leak of handle}}
+ // expected-warning at -1 {{Potential leak of handle}}
+
void checkReportLeakOnOnePath(int tag) {
zx_handle_t sa, sb;
- if (zx_channel_create(0, &sa, &sb)) // expected-note {{Handle allocated here}}
+ if (zx_channel_create(0, &sa, &sb)) // expected-note {{Handle allocated through 2nd parameter}}
return; // expected-note at -1 {{Assuming the condition is false}}
// expected-note at -2 {{Taking false branch}}
zx_handle_close(sb);
@@ -161,9 +170,9 @@ void checkReportLeakOnOnePath(int tag) {
void checkDoubleRelease01(int tag) {
zx_handle_t sa, sb;
zx_channel_create(0, &sa, &sb);
- // expected-note at -1 {{Handle allocated here}}
+ // expected-note at -1 {{Handle allocated through 2nd parameter}}
if (tag) // expected-note {{Assuming 'tag' is not equal to 0}}
- zx_handle_close(sa); // expected-note {{Handle released here}}
+ zx_handle_close(sa); // expected-note {{Handle released through 1st parameter}}
// expected-note at -2 {{Taking true branch}}
zx_handle_close(sa); // expected-warning {{Releasing a previously released handle}}
// expected-note at -1 {{Releasing a previously released handle}}
@@ -173,18 +182,18 @@ void checkDoubleRelease01(int tag) {
void checkUseAfterFree01(int tag) {
zx_handle_t sa, sb;
zx_channel_create(0, &sa, &sb);
- // expected-note at -1 {{Handle allocated here}}
- // expected-note at -2 {{Handle allocated here}}
+ // expected-note at -1 {{Handle allocated through 2nd parameter}}
+ // expected-note at -2 {{Handle allocated through 3rd parameter}}
// expected-note at +2 {{Taking true branch}}
// expected-note at +1 {{Taking false branch}}
if (tag) {
// expected-note at -1 {{Assuming 'tag' is not equal to 0}}
- zx_handle_close(sa); // expected-note {{Handle released here}}
+ zx_handle_close(sa); // expected-note {{Handle released through 1st parameter}}
use1(&sa); // expected-warning {{Using a previously released handle}}
// expected-note at -1 {{Using a previously released handle}}
}
// expected-note at -6 {{Assuming 'tag' is 0}}
- zx_handle_close(sb); // expected-note {{Handle released here}}
+ zx_handle_close(sb); // expected-note {{Handle released through 1st parameter}}
use2(sb); // expected-warning {{Using a previously released handle}}
// expected-note at -1 {{Using a previously released handle}}
}
More information about the cfe-commits
mailing list