//===- BugReporterVisitors.h - Generate PathDiagnostics ---------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file declares BugReporterVisitors, which are used to generate enhanced // diagnostic traces. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H #define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringRef.h" #include <list> #include <memory> #include <optional> #include <utility> namespace clang { class BinaryOperator; class CFGBlock; class DeclRefExpr; class Expr; class Stmt; namespace ento { class PathSensitiveBugReport; class BugReporterContext; class ExplodedNode; class MemRegion; class PathDiagnosticPiece; PathDiagnosticPieceRef; /// BugReporterVisitors are used to add custom diagnostics along a path. class BugReporterVisitor : public llvm::FoldingSetNode { … }; namespace bugreporter { /// Specifies the type of tracking for an expression. enum class TrackingKind { … }; /// Defines a set of options altering tracking behavior. struct TrackingOptions { … }; /// Describes an event when the value got stored into a memory region. /// /// As opposed to checker checkBind API, it reacts also to binds /// generated by the checker as well. It can be useful when the binding /// happened as a result of evalCall, for example. struct StoreInfo { … }; class Tracker; TrackerRef; class ExpressionHandler; class StoreHandler; /// A generalized component for tracking expressions, values, and stores. /// /// Tracker aimes at providing a sensible set of default behaviors that can be /// used by any checker, while providing mechanisms to hook into any part of the /// tracking process and insert checker-specific logic. class Tracker : public llvm::RefCountedBase<Tracker> { … }; /// Handles expressions during the tracking. class ExpressionHandler { … }; /// Handles stores during the tracking. class StoreHandler { … }; /// Visitor that tracks expressions and values. class TrackingBugReporterVisitor : public BugReporterVisitor { … }; /// Attempts to add visitors to track expression value back to its point of /// origin. /// /// \param N A node "downstream" from the evaluation of the statement. /// \param E The expression value which we are tracking /// \param R The bug report to which visitors should be attached. /// \param Opts Tracking options specifying how we are tracking the value. /// /// \return Whether or not the function was able to add visitors for this /// statement. Note that returning \c true does not actually imply /// that any visitors were added. bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts = { … }; /// Track how the value got stored into the given region and where it came /// from. /// /// \param V We're searching for the store where \c R received this value. /// It may be either defined or undefined, but should not be unknown. /// \param R The region we're tracking. /// \param Opts Tracking options specifying how we want to track the value. /// \param Origin Only adds notes when the last store happened in a /// different stackframe to this one. Disregarded if the tracking kind /// is thorough. /// This is useful, because for non-tracked regions, notes about /// changes to its value in a nested stackframe could be pruned, and /// this visitor can prevent that without polluting the bugpath too /// much. void trackStoredValue(SVal V, const MemRegion *R, PathSensitiveBugReport &Report, TrackingOptions Opts = { … }; const Expr *getDerefExpr(const Stmt *S); } // namespace bugreporter class TrackConstraintBRVisitor final : public BugReporterVisitor { … }; /// \class NilReceiverBRVisitor /// Prints path notes when a message is sent to a nil receiver. class NilReceiverBRVisitor final : public BugReporterVisitor { … }; /// Visitor that tries to report interesting diagnostics from conditions. class ConditionBRVisitor final : public BugReporterVisitor { … }; /// Suppress reports that might lead to known false positives. /// /// Currently this suppresses reports based on locations of bugs. class LikelyFalsePositiveSuppressionBRVisitor final : public BugReporterVisitor { … }; /// When a region containing undefined value or '0' value is passed /// as an argument in a call, marks the call as interesting. /// /// As a result, BugReporter will not prune the path through the function even /// if the region's contents are not modified/accessed by the call. class UndefOrNullArgVisitor final : public BugReporterVisitor { … }; class SuppressInlineDefensiveChecksVisitor final : public BugReporterVisitor { … }; /// The visitor detects NoteTags and displays the event notes they contain. class TagVisitor : public BugReporterVisitor { … }; class ObjCMethodCall; class CXXConstructorCall; /// Put a diagnostic on return statement (or on } in its absence) of all inlined /// functions for which some property remained unchanged. /// Resulting diagnostics may read such as "Returning without writing to X". /// /// Descendants can define what a "state change is", like a change of value /// to a memory region, liveness, etc. For function calls where the state did /// not change as defined, a custom note may be constructed. /// /// For a minimal example, check out /// clang/unittests/StaticAnalyzer/NoStateChangeFuncVisitorTest.cpp. class NoStateChangeFuncVisitor : public BugReporterVisitor { … }; /// Put a diagnostic on return statement of all inlined functions /// for which the region of interest \p RegionOfInterest was passed into, /// but not written inside, and it has caused an undefined read or a null /// pointer dereference outside. class NoStoreFuncVisitor final : public NoStateChangeFuncVisitor { … }; } // namespace ento } // namespace clang #endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H