xazax.hun created this revision.
xazax.hun added reviewers: NoQ, haowei.
xazax.hun added a project: clang.
Herald added subscribers: Charusso, gamesh411, dkrupp, donat.nagy, Szelethus, 
mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware.

I found that this information is useful when trying to understand bug reports. 
Moreover other checks seem to also report parameter indices.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73229

Files:
  clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
  clang/test/Analysis/fuchsia_handle.cpp

Index: clang/test/Analysis/fuchsia_handle.cpp
===================================================================
--- clang/test/Analysis/fuchsia_handle.cpp
+++ clang/test/Analysis/fuchsia_handle.cpp
@@ -26,6 +26,9 @@
 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; 
@@ -125,7 +128,7 @@
 
 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 at 2nd parameter}}
     return;                           // expected-note@-1 {{Assuming the condition is false}}
                                       // expected-note@-2 {{Taking false branch}}
   use1(&sa);
@@ -137,9 +140,15 @@
   zx_handle_close(sb);
 }
 
+void checkLeakFromReturn01(int tag) {
+  zx_handle_t sa = return_handle(); // expected-note {{Open handle is returned here}}
+  (void)sa;
+} // expected-note {{Potential leak of handle}}
+  // expected-warning@-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 at 2nd parameter}}
     return;                           // expected-note@-1 {{Assuming the condition is false}}
                                       // expected-note@-2 {{Taking false branch}}
   zx_handle_close(sb);
@@ -169,9 +178,9 @@
 void checkDoubleRelease01(int tag) {
   zx_handle_t sa, sb;
   zx_channel_create(0, &sa, &sb);
-  // expected-note@-1 {{Handle allocated here}}
+  // expected-note@-1 {{Handle allocated at 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 at 1st parameter}}
   // expected-note@-2 {{Taking true branch}}
   zx_handle_close(sa); // expected-warning {{Releasing a previously released handle}}
   // expected-note@-1 {{Releasing a previously released handle}}
@@ -181,18 +190,18 @@
 void checkUseAfterFree01(int tag) {
   zx_handle_t sa, sb;
   zx_channel_create(0, &sa, &sb);
-  // expected-note@-1 {{Handle allocated here}}
-  // expected-note@-2 {{Handle allocated here}}
+  // expected-note@-1 {{Handle allocated at 2nd parameter}}
+  // expected-note@-2 {{Handle allocated at 3rd parameter}}
   // expected-note@+2 {{Taking true branch}}
   // expected-note@+1 {{Taking false branch}}
   if (tag) {
     // expected-note@-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 at 1st parameter}}
     use1(&sa); // expected-warning {{Using a previously released handle}}
     // expected-note@-1 {{Using a previously released handle}}
   }
   // expected-note@-6 {{Assuming 'tag' is 0}}
-  zx_handle_close(sb); // expected-note {{Handle released here}}
+  zx_handle_close(sb); // expected-note {{Handle released at 1st parameter}}
   use2(sb); // expected-warning {{Using a previously released handle}}
   // expected-note@-1 {{Using a previously released handle}}
 }
Index: clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
@@ -322,6 +322,13 @@
   // Function returns an open handle.
   if (hasFuchsiaAttr<AcquireHandleAttr>(FuncDecl)) {
     SymbolRef RetSym = Call.getReturnValue().getAsSymbol();
+    Notes.push_back([RetSym](BugReport &BR) {
+      auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
+      if (auto IsInteresting = PathBR->getInterestingnessKind(RetSym))
+        return "Open handle is returned here.";
+      else
+        return "";
+    });
     State =
         State->set<HStateMap>(RetSym, HandleState::getMaybeAllocated(nullptr));
   }
@@ -330,6 +337,7 @@
     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)
@@ -343,22 +351,30 @@
         reportDoubleRelease(Handle, Call.getArgSourceRange(Arg), C);
         return;
       } else {
-        Notes.push_back([Handle](BugReport &BR) {
+        Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) {
           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 at " << ParamDiagIdx
+               << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter.";
+            return OS.str();
           } else
-            return "";
+            return std::string{};
         });
         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) {
         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 at " << ParamDiagIdx
+             << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter.";
+          return OS.str();
         } else
-          return "";
+          return std::string{};
       });
       State = State->set<HStateMap>(
           Handle, HandleState::getMaybeAllocated(ResultSymbol));
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to