================
@@ -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();
----------------
pskrgag wrote:

Closing all bug visitor comments, since it was removed

https://github.com/llvm/llvm-project/pull/111588
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to