#include "PrettyStackTraceLocationContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/ConstructionContext.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/SaveAndRestore.h"
#include <optional>
usingnamespaceclang;
usingnamespaceento;
#define DEBUG_TYPE …
STATISTIC(NumOfDynamicDispatchPathSplits,
"The # of times we split the path due to imprecise dynamic dispatch info");
STATISTIC(NumInlinedCalls,
"The # of times we inlined a call");
STATISTIC(NumReachedInlineCountMax,
"The # of times we reached inline count maximum");
void ExprEngine::processCallEnter(NodeBuilderContext& BC, CallEnter CE,
ExplodedNode *Pred) { … }
static std::pair<const Stmt*,
const CFGBlock*> getLastStmt(const ExplodedNode *Node) { … }
static SVal adjustReturnValue(SVal V, QualType ExpectedTy, QualType ActualTy,
StoreManager &StoreMgr) { … }
void ExprEngine::removeDeadOnEndOfFunction(NodeBuilderContext& BC,
ExplodedNode *Pred,
ExplodedNodeSet &Dst) { … }
static bool wasDifferentDeclUsedForInlining(CallEventRef<> Call,
const StackFrameContext *calleeCtx) { … }
static unsigned getElementCountOfArrayBeingDestructed(
const CallEvent &Call, const ProgramStateRef State, SValBuilder &SVB) { … }
ProgramStateRef ExprEngine::removeStateTraitsUsedForArrayEvaluation(
ProgramStateRef State, const CXXConstructExpr *E,
const LocationContext *LCtx) { … }
void ExprEngine::processCallExit(ExplodedNode *CEBNode) { … }
bool ExprEngine::isSmall(AnalysisDeclContext *ADC) const { … }
bool ExprEngine::isLarge(AnalysisDeclContext *ADC) const { … }
bool ExprEngine::isHuge(AnalysisDeclContext *ADC) const { … }
void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx,
bool &IsRecursive, unsigned &StackDepth) { … }
namespace {
enum DynamicDispatchMode { … };
}
REGISTER_MAP_WITH_PROGRAMSTATE(…) …
REGISTER_TRAIT_WITH_PROGRAMSTATE(…) …
void ExprEngine::ctuBifurcate(const CallEvent &Call, const Decl *D,
NodeBuilder &Bldr, ExplodedNode *Pred,
ProgramStateRef State) { … }
void ExprEngine::inlineCall(WorkList *WList, const CallEvent &Call,
const Decl *D, NodeBuilder &Bldr,
ExplodedNode *Pred, ProgramStateRef State) { … }
static ProgramStateRef getInlineFailedState(ProgramStateRef State,
const Stmt *CallE) { … }
void ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
ExplodedNodeSet &dst) { … }
ProgramStateRef ExprEngine::finishArgumentConstruction(ProgramStateRef State,
const CallEvent &Call) { … }
void ExprEngine::finishArgumentConstruction(ExplodedNodeSet &Dst,
ExplodedNode *Pred,
const CallEvent &Call) { … }
void ExprEngine::evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
const CallEvent &Call) { … }
ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
const LocationContext *LCtx,
ProgramStateRef State) { … }
void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
ExplodedNode *Pred, ProgramStateRef State) { … }
ExprEngine::CallInlinePolicy
ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred,
AnalyzerOptions &Opts,
const EvalCallOptions &CallOpts) { … }
static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD,
StringRef Name) { … }
static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) { … }
static bool isContainerMethod(const ASTContext &Ctx,
const FunctionDecl *FD) { … }
static bool isCXXSharedPtrDtor(const FunctionDecl *FD) { … }
bool ExprEngine::mayInlineDecl(AnalysisDeclContext *CalleeADC) const { … }
bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
const ExplodedNode *Pred,
const EvalCallOptions &CallOpts) { … }
bool ExprEngine::shouldInlineArrayConstruction(const ProgramStateRef State,
const CXXConstructExpr *CE,
const LocationContext *LCtx) { … }
bool ExprEngine::shouldInlineArrayDestruction(uint64_t Size) { … }
bool ExprEngine::shouldRepeatCtorCall(ProgramStateRef State,
const CXXConstructExpr *E,
const LocationContext *LCtx) { … }
static bool isTrivialObjectAssignment(const CallEvent &Call) { … }
void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred,
const CallEvent &CallTemplate,
const EvalCallOptions &CallOpts) { … }
void ExprEngine::BifurcateCall(const MemRegion *BifurReg,
const CallEvent &Call, const Decl *D,
NodeBuilder &Bldr, ExplodedNode *Pred) { … }
void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
ExplodedNodeSet &Dst) { … }