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();
87 State = State->BindExpr(CE,
C.getLocationContext(),
88 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();
108 State = State->BindExpr(CE,
C.getLocationContext(),
109 nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0))));
112void DebugContainerModeling::analyzerContainerBegin(
const CallExpr *CE,
113 CheckerContext &
C)
const {
114 analyzerContainerDataField(CE,
C, [](
const ContainerData *D) {
119void DebugContainerModeling::analyzerContainerEnd(
const CallExpr *CE,
120 CheckerContext &
C)
const {
121 analyzerContainerDataField(CE,
C, [](
const ContainerData *D) {
126ExplodedNode *DebugContainerModeling::reportDebugMsg(llvm::StringRef Msg,
127 CheckerContext &
C)
const {
128 ExplodedNode *N =
C.generateNonFatalErrorNode();
132 auto &BR =
C.getBugReporter();
134 std::make_unique<PathSensitiveBugReport>(DebugMsgBugType, Msg, N));
138void ento::registerDebugContainerModeling(CheckerManager &mgr) {
142bool 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