[clang] [analyzer] Modernize FuchsiaHandleChecker (PR #111588)

DonĂ¡t Nagy via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 9 03:54:23 PDT 2024


================
@@ -267,12 +286,128 @@ class FuchsiaHandleSymbolVisitor final : public SymbolVisitor {
 private:
   SmallVector<SymbolRef, 1024> Symbols;
 };
+
+class FuchsiaBugVisitor final : public BugReporterVisitor {
+  // Handle that caused a problem.
+  SymbolRef Sym;
+
+  bool IsLeak;
+
+public:
+  FuchsiaBugVisitor(SymbolRef S, bool Leak = false) : Sym(S), IsLeak(Leak) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    ID.AddPointer(Sym);
+  }
+
+  static inline bool isAllocated(const HandleState *RSCurr,
+                                 const HandleState *RSPrev, const Stmt *Stmt) {
+    return isa_and_nonnull<CallExpr>(Stmt) &&
+           ((RSCurr && (RSCurr->isAllocated() || RSCurr->maybeAllocated()) &&
+             (!RSPrev ||
+              !(RSPrev->isAllocated() || RSPrev->maybeAllocated()))));
+  }
+
+  static inline bool isAllocatedUnowned(const HandleState *RSCurr,
+                                        const HandleState *RSPrev,
+                                        const Stmt *Stmt) {
+    return isa_and_nonnull<CallExpr>(Stmt) &&
+           ((RSCurr && RSCurr->isUnowned()) &&
+            (!RSPrev || !RSPrev->isUnowned()));
+  }
+
+  static inline bool isReleased(const HandleState *RSCurr,
+                                const HandleState *RSPrev, const Stmt *Stmt) {
+    return isa_and_nonnull<CallExpr>(Stmt) &&
+           ((RSCurr && RSCurr->isReleased()) &&
+            (!RSPrev || !RSPrev->isReleased()));
+  }
+
+  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
+                                   BugReporterContext &BRC,
+                                   PathSensitiveBugReport &BR) override;
+
+  PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC,
+                                    const ExplodedNode *EndPathNode,
+                                    PathSensitiveBugReport &BR) override {
+    if (!IsLeak)
+      return nullptr;
+
+    PathDiagnosticLocation L = BR.getLocation();
+    // Do not add the statement itself as a range in case of leak.
+    return std::make_shared<PathDiagnosticEventPiece>(L, BR.getDescription(),
+                                                      false);
+  }
+};
 } // end anonymous namespace
 
+PathDiagnosticPieceRef
+FuchsiaBugVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
+                             PathSensitiveBugReport &BR) {
+  ProgramStateRef State = N->getState();
+  ProgramStateRef StatePrev = N->getFirstPred()->getState();
+
+  const HandleState *RSCurr = State->get<HStateMap>(Sym);
+  const HandleState *RSPrev = StatePrev->get<HStateMap>(Sym);
+
+  const Stmt *S = N->getStmtForDiagnostics();
+
+  StringRef Msg;
+  SmallString<256> Buf;
+  llvm::raw_svector_ostream OS(Buf);
+
+  if (isAllocated(RSCurr, RSPrev, S)) {
+    auto Index = RSCurr->getIndex();
+
+    if (Index > 0)
+      OS << "Handle allocated through " << Index
+         << llvm::getOrdinalSuffix(Index) << " parameter";
+    else
+      OS << "Function returns an open handle";
+
+    Msg = OS.str();
----------------
NagyDonat wrote:

Instead of repeating this, call this once after the `if` - `else if` blocks. 

https://github.com/llvm/llvm-project/pull/111588


More information about the cfe-commits mailing list