================ @@ -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