#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Analysis/Analyses/Dominators.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/CFGStmtMap.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <deque>
#include <memory>
#include <optional>
#include <stack>
#include <string>
#include <utility>
usingnamespaceclang;
usingnamespaceento;
usingnamespacebugreporter;
static const Expr *peelOffPointerArithmetic(const BinaryOperator *B) { … }
static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N);
const Expr *bugreporter::getDerefExpr(const Stmt *S) { … }
static const VarDecl *getVarDeclForExpression(const Expr *E) { … }
static const MemRegion *
getLocationRegionIfReference(const Expr *E, const ExplodedNode *N,
bool LookingForReference = true) { … }
static bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal,
const ExplodedNode *RightNode, SVal RightVal) { … }
static std::optional<SVal> getSValForVar(const Expr *CondVarExpr,
const ExplodedNode *N) { … }
static std::optional<const llvm::APSInt *>
getConcreteIntegerValue(const Expr *CondVarExpr, const ExplodedNode *N) { … }
static bool isVarAnInterestingCondition(const Expr *CondVarExpr,
const ExplodedNode *N,
const PathSensitiveBugReport *B) { … }
static bool isInterestingExpr(const Expr *E, const ExplodedNode *N,
const PathSensitiveBugReport *B) { … }
static StringRef getMacroName(SourceLocation Loc,
BugReporterContext &BRC) { … }
static bool isFunctionMacroExpansion(SourceLocation Loc,
const SourceManager &SM) { … }
static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest,
const ExplodedNode *N,
SVal ValueAfter) { … }
PathDiagnosticPieceRef BugReporterVisitor::getEndPath(BugReporterContext &,
const ExplodedNode *,
PathSensitiveBugReport &) { … }
void BugReporterVisitor::finalizeVisitor(BugReporterContext &,
const ExplodedNode *,
PathSensitiveBugReport &) { … }
PathDiagnosticPieceRef
BugReporterVisitor::getDefaultEndPath(const BugReporterContext &BRC,
const ExplodedNode *EndPathNode,
const PathSensitiveBugReport &BR) { … }
bool NoStateChangeFuncVisitor::isModifiedInFrame(const ExplodedNode *N) { … }
void NoStateChangeFuncVisitor::markFrameAsModifying(
const StackFrameContext *SCtx) { … }
static const ExplodedNode *getMatchingCallExitEnd(const ExplodedNode *N) { … }
void NoStateChangeFuncVisitor::findModifyingFrames(
const ExplodedNode *const CallExitBeginN) { … }
PathDiagnosticPieceRef NoStateChangeFuncVisitor::VisitNode(
const ExplodedNode *N, BugReporterContext &BR, PathSensitiveBugReport &R) { … }
static bool potentiallyWritesIntoIvar(const Decl *Parent,
const ObjCIvarDecl *Ivar) { … }
const std::optional<NoStoreFuncVisitor::RegionVector>
NoStoreFuncVisitor::findRegionOfInterestInRecord(
const RecordDecl *RD, ProgramStateRef State, const MemRegion *R,
const NoStoreFuncVisitor::RegionVector &Vec ,
int depth ) { … }
PathDiagnosticPieceRef
NoStoreFuncVisitor::maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
const ObjCMethodCall &Call,
const ExplodedNode *N) { … }
PathDiagnosticPieceRef
NoStoreFuncVisitor::maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
const CXXConstructorCall &Call,
const ExplodedNode *N) { … }
static bool isPointerToConst(QualType Ty) { … }
PathDiagnosticPieceRef NoStoreFuncVisitor::maybeEmitNoteForParameters(
PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N) { … }
bool NoStoreFuncVisitor::wasModifiedBeforeCallExit(
const ExplodedNode *CurrN, const ExplodedNode *CallExitBeginN) { … }
static llvm::StringLiteral WillBeUsedForACondition = …;
PathDiagnosticPieceRef NoStoreFuncVisitor::maybeEmitNote(
PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N,
const RegionVector &FieldChain, const MemRegion *MatchedRegion,
StringRef FirstElement, bool FirstIsReferenceType,
unsigned IndirectionLevel) { … }
bool NoStoreFuncVisitor::prettyPrintRegionName(const RegionVector &FieldChain,
const MemRegion *MatchedRegion,
StringRef FirstElement,
bool FirstIsReferenceType,
unsigned IndirectionLevel,
llvm::raw_svector_ostream &os) { … }
StringRef NoStoreFuncVisitor::prettyPrintFirstElement(
StringRef FirstElement, bool MoreItemsExpected, int IndirectionLevel,
llvm::raw_svector_ostream &os) { … }
namespace {
class MacroNullReturnSuppressionVisitor final : public BugReporterVisitor { … };
}
namespace {
class ReturnVisitor : public TrackingBugReporterVisitor { … };
class StoreSiteFinder final : public TrackingBugReporterVisitor { … };
}
void StoreSiteFinder::Profile(llvm::FoldingSetNodeID &ID) const { … }
static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR) { … }
static bool isObjCPointer(const MemRegion *R) { … }
static bool isObjCPointer(const ValueDecl *D) { … }
static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI) { … }
static void showBRParamDiagnostics(llvm::raw_svector_ostream &OS,
StoreInfo SI) { … }
static void showBRDefaultDiagnostics(llvm::raw_svector_ostream &OS,
StoreInfo SI) { … }
static bool isTrivialCopyOrMoveCtor(const CXXConstructExpr *CE) { … }
static const Expr *tryExtractInitializerFromList(const InitListExpr *ILE,
const MemRegion *R) { … }
PathDiagnosticPieceRef StoreSiteFinder::VisitNode(const ExplodedNode *Succ,
BugReporterContext &BRC,
PathSensitiveBugReport &BR) { … }
void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const { … }
const char *TrackConstraintBRVisitor::getTag() { … }
bool TrackConstraintBRVisitor::isZeroCheck() const { … }
bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const { … }
PathDiagnosticPieceRef TrackConstraintBRVisitor::VisitNode(
const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &) { … }
SuppressInlineDefensiveChecksVisitor::
SuppressInlineDefensiveChecksVisitor(DefinedSVal Value, const ExplodedNode *N)
: … { … }
void SuppressInlineDefensiveChecksVisitor::Profile(
llvm::FoldingSetNodeID &ID) const { … }
const char *SuppressInlineDefensiveChecksVisitor::getTag() { … }
PathDiagnosticPieceRef
SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
BugReporterContext &BRC,
PathSensitiveBugReport &BR) { … }
namespace {
class TrackControlDependencyCondBRVisitor final
: public TrackingBugReporterVisitor { … };
}
static std::shared_ptr<PathDiagnosticEventPiece>
constructDebugPieceForTrackedCondition(const Expr *Cond,
const ExplodedNode *N,
BugReporterContext &BRC) { … }
static bool isAssertlikeBlock(const CFGBlock *B, ASTContext &Context) { … }
PathDiagnosticPieceRef
TrackControlDependencyCondBRVisitor::VisitNode(const ExplodedNode *N,
BugReporterContext &BRC,
PathSensitiveBugReport &BR) { … }
static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N) { … }
static const ExplodedNode* findNodeForExpression(const ExplodedNode *N,
const Expr *Inner) { … }
PathDiagnosticPieceRef StoreHandler::constructNote(StoreInfo SI,
BugReporterContext &BRC,
StringRef NodeText) { … }
namespace {
class DefaultStoreHandler final : public StoreHandler { … };
class ControlDependencyHandler final : public ExpressionHandler { … };
class NilReceiverHandler final : public ExpressionHandler { … };
class ArrayIndexHandler final : public ExpressionHandler { … };
class InterestingLValueHandler final : public ExpressionHandler { … };
class InlinedFunctionCallHandler final : public ExpressionHandler { … };
class DefaultExpressionHandler final : public ExpressionHandler { … };
class PRValueHandler final : public ExpressionHandler { … };
}
Tracker::Tracker(PathSensitiveBugReport &Report) : … { … }
Tracker::Result Tracker::track(const Expr *E, const ExplodedNode *N,
TrackingOptions Opts) { … }
Tracker::Result Tracker::track(SVal V, const MemRegion *R, TrackingOptions Opts,
const StackFrameContext *Origin) { … }
PathDiagnosticPieceRef Tracker::handle(StoreInfo SI, BugReporterContext &BRC,
TrackingOptions Opts) { … }
bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode,
const Expr *E,
PathSensitiveBugReport &Report,
TrackingOptions Opts) { … }
void bugreporter::trackStoredValue(SVal V, const MemRegion *R,
PathSensitiveBugReport &Report,
TrackingOptions Opts,
const StackFrameContext *Origin) { … }
const Expr *NilReceiverBRVisitor::getNilReceiver(const Stmt *S,
const ExplodedNode *N) { … }
PathDiagnosticPieceRef
NilReceiverBRVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
PathSensitiveBugReport &BR) { … }
const char *ConditionBRVisitor::getTag() { … }
PathDiagnosticPieceRef
ConditionBRVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
PathSensitiveBugReport &BR) { … }
PathDiagnosticPieceRef
ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
BugReporterContext &BRC,
PathSensitiveBugReport &BR) { … }
PathDiagnosticPieceRef ConditionBRVisitor::VisitTerminator(
const Stmt *Term, const ExplodedNode *N, const CFGBlock *srcBlk,
const CFGBlock *dstBlk, PathSensitiveBugReport &R,
BugReporterContext &BRC) { … }
PathDiagnosticPieceRef
ConditionBRVisitor::VisitTrueTest(const Expr *Cond, BugReporterContext &BRC,
PathSensitiveBugReport &R,
const ExplodedNode *N, bool TookTrue) { … }
bool ConditionBRVisitor::patternMatch(const Expr *Ex, const Expr *ParentEx,
raw_ostream &Out, BugReporterContext &BRC,
PathSensitiveBugReport &report,
const ExplodedNode *N,
std::optional<bool> &prunable,
bool IsSameFieldName) { … }
PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest(
const Expr *Cond, const BinaryOperator *BExpr, BugReporterContext &BRC,
PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue,
bool IsAssuming) { … }
PathDiagnosticPieceRef ConditionBRVisitor::VisitConditionVariable(
StringRef LhsString, const Expr *CondVarExpr, BugReporterContext &BRC,
PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue) { … }
PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest(
const Expr *Cond, const DeclRefExpr *DRE, BugReporterContext &BRC,
PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue,
bool IsAssuming) { … }
PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest(
const Expr *Cond, const MemberExpr *ME, BugReporterContext &BRC,
PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue,
bool IsAssuming) { … }
bool ConditionBRVisitor::printValue(const Expr *CondVarExpr, raw_ostream &Out,
const ExplodedNode *N, bool TookTrue,
bool IsAssuming) { … }
constexpr llvm::StringLiteral ConditionBRVisitor::GenericTrueMessage;
constexpr llvm::StringLiteral ConditionBRVisitor::GenericFalseMessage;
bool ConditionBRVisitor::isPieceMessageGeneric(
const PathDiagnosticPiece *Piece) { … }
void LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor(
BugReporterContext &BRC, const ExplodedNode *N,
PathSensitiveBugReport &BR) { … }
PathDiagnosticPieceRef
UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
PathSensitiveBugReport &BR) { … }
int NoteTag::Kind = …;
void TagVisitor::Profile(llvm::FoldingSetNodeID &ID) const { … }
PathDiagnosticPieceRef TagVisitor::VisitNode(const ExplodedNode *N,
BugReporterContext &BRC,
PathSensitiveBugReport &R) { … }