28class DebugContainerModeling
31 const BugType DebugMsgBugType{
this,
"Checking analyzer assumptions",
"debug",
34 template <
typename Getter>
35 void analyzerContainerDataField(
const CallExpr *CE, CheckerContext &
C,
37 void analyzerContainerBegin(
const CallExpr *CE, CheckerContext &
C)
const;
38 void analyzerContainerEnd(
const CallExpr *CE, CheckerContext &
C)
const;
39 ExplodedNode *reportDebugMsg(llvm::StringRef Msg, CheckerContext &
C)
const;
41 typedef void (DebugContainerModeling::*FnCheck)(
const CallExpr *,
42 CheckerContext &)
const;
44 CallDescriptionMap<FnCheck> Callbacks = {
45 {{CDM::SimpleFunc, {
"clang_analyzer_container_begin"}, 1},
46 &DebugContainerModeling::analyzerContainerBegin},
47 {{CDM::SimpleFunc, {
"clang_analyzer_container_end"}, 1},
48 &DebugContainerModeling::analyzerContainerEnd},
52 bool evalCall(
const CallEvent &
Call, CheckerContext &
C)
const;
59 const auto *CE = dyn_cast_or_null<CallExpr>(
Call.getOriginExpr());
63 const FnCheck *Handler = Callbacks.lookup(
Call);
67 (this->**Handler)(CE,
C);
71template <
typename Getter>
72void DebugContainerModeling::analyzerContainerDataField(
const CallExpr *CE,
76 reportDebugMsg(
"Missing container argument",
C);
80 auto State =
C.getState();
81 const MemRegion *Cont =
C.getSVal(CE->
getArg(0)).getAsRegion();
88 State->BindExpr(CE,
C.getStackFrame(), nonloc::SymbolVal(Field));
93 const NoteTag *InterestingTag =
95 [Cont, Field](PathSensitiveBugReport &BR) -> std::string {
101 C.addTransition(State, InterestingTag);
107 auto &BVF =
C.getSValBuilder().getBasicValueFactory();
109 State->BindExpr(CE,
C.getStackFrame(),
110 nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0))));
113void DebugContainerModeling::analyzerContainerBegin(
const CallExpr *CE,
114 CheckerContext &
C)
const {
115 analyzerContainerDataField(CE,
C, [](
const ContainerData *D) {
120void DebugContainerModeling::analyzerContainerEnd(
const CallExpr *CE,
121 CheckerContext &
C)
const {
122 analyzerContainerDataField(CE,
C, [](
const ContainerData *D) {
127ExplodedNode *DebugContainerModeling::reportDebugMsg(llvm::StringRef Msg,
128 CheckerContext &
C)
const {
129 ExplodedNode *N =
C.generateNonFatalErrorNode();
133 auto &BR =
C.getBugReporter();
135 std::make_unique<PathSensitiveBugReport>(DebugMsgBugType, Msg, N));
139void ento::registerDebugContainerModeling(CheckerManager &mgr) {
143bool ento::shouldRegisterDebugContainerModeling(
const CheckerManager &mgr) {
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Represents an abstract call to a function or method along a particular path.
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
Simple checker classes that implement one frontend (i.e.
void markInteresting(SymbolRef sym, bugreporter::TrackingKind TKind=bugreporter::TrackingKind::Thorough)
Marks a symbol as interesting.
bool isInteresting(SymbolRef sym) const
const ContainerData * getContainerData(ProgramStateRef State, const MemRegion *Cont)
const SymExpr * SymbolRef
The JSON file list parser is used to communicate input to InstallAPI.
SymbolRef getBegin() const