clang  15.0.0git
ExprInspectionChecker.cpp
Go to the documentation of this file.
1 //==- ExprInspectionChecker.cpp - Used for regression tests ------*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/Support/ScopedPrinter.h"
20 
21 using namespace clang;
22 using namespace ento;
23 
24 namespace {
25 class ExprInspectionChecker
26  : public Checker<eval::Call, check::DeadSymbols, check::EndAnalysis> {
27  mutable std::unique_ptr<BugType> BT;
28 
29  // These stats are per-analysis, not per-branch, hence they shouldn't
30  // stay inside the program state.
31  struct ReachedStat {
32  ExplodedNode *ExampleNode;
33  unsigned NumTimesReached;
34  };
35  mutable llvm::DenseMap<const CallExpr *, ReachedStat> ReachedStats;
36 
37  void analyzerEval(const CallExpr *CE, CheckerContext &C) const;
38  void analyzerCheckInlined(const CallExpr *CE, CheckerContext &C) const;
39  void analyzerWarnIfReached(const CallExpr *CE, CheckerContext &C) const;
40  void analyzerNumTimesReached(const CallExpr *CE, CheckerContext &C) const;
41  void analyzerCrash(const CallExpr *CE, CheckerContext &C) const;
42  void analyzerWarnOnDeadSymbol(const CallExpr *CE, CheckerContext &C) const;
43  void analyzerDumpSValType(const CallExpr *CE, CheckerContext &C) const;
44  void analyzerDump(const CallExpr *CE, CheckerContext &C) const;
45  void analyzerExplain(const CallExpr *CE, CheckerContext &C) const;
46  void analyzerPrintState(const CallExpr *CE, CheckerContext &C) const;
47  void analyzerGetExtent(const CallExpr *CE, CheckerContext &C) const;
48  void analyzerDumpExtent(const CallExpr *CE, CheckerContext &C) const;
49  void analyzerDumpElementCount(const CallExpr *CE, CheckerContext &C) const;
50  void analyzerHashDump(const CallExpr *CE, CheckerContext &C) const;
51  void analyzerDenote(const CallExpr *CE, CheckerContext &C) const;
52  void analyzerExpress(const CallExpr *CE, CheckerContext &C) const;
53  void analyzerIsTainted(const CallExpr *CE, CheckerContext &C) const;
54 
55  typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
56  CheckerContext &C) const;
57 
58  // Optional parameter `ExprVal` for expression value to be marked interesting.
59  ExplodedNode *reportBug(llvm::StringRef Msg, CheckerContext &C,
60  Optional<SVal> ExprVal = None) const;
61  ExplodedNode *reportBug(llvm::StringRef Msg, BugReporter &BR, ExplodedNode *N,
62  Optional<SVal> ExprVal = None) const;
63 
64  const Expr *getArgExpr(const CallExpr *CE, CheckerContext &C) const;
65  const MemRegion *getArgRegion(const CallExpr *CE, CheckerContext &C) const;
66 
67 public:
68  bool evalCall(const CallEvent &Call, CheckerContext &C) const;
69  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
70  void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
71  ExprEngine &Eng) const;
72 };
73 } // namespace
74 
77 
78 bool ExprInspectionChecker::evalCall(const CallEvent &Call,
79  CheckerContext &C) const {
80  const auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
81  if (!CE)
82  return false;
83 
84  // These checks should have no effect on the surrounding environment
85  // (globals should not be invalidated, etc), hence the use of evalCall.
86  FnCheck Handler =
87  llvm::StringSwitch<FnCheck>(C.getCalleeName(CE))
88  .Case("clang_analyzer_eval", &ExprInspectionChecker::analyzerEval)
89  .Case("clang_analyzer_checkInlined",
90  &ExprInspectionChecker::analyzerCheckInlined)
91  .Case("clang_analyzer_crash", &ExprInspectionChecker::analyzerCrash)
92  .Case("clang_analyzer_warnIfReached",
93  &ExprInspectionChecker::analyzerWarnIfReached)
94  .Case("clang_analyzer_warnOnDeadSymbol",
95  &ExprInspectionChecker::analyzerWarnOnDeadSymbol)
96  .StartsWith("clang_analyzer_explain",
97  &ExprInspectionChecker::analyzerExplain)
98  .Case("clang_analyzer_dumpExtent",
99  &ExprInspectionChecker::analyzerDumpExtent)
100  .Case("clang_analyzer_dumpElementCount",
101  &ExprInspectionChecker::analyzerDumpElementCount)
102  .StartsWith("clang_analyzer_dumpSvalType",
103  &ExprInspectionChecker::analyzerDumpSValType)
104  .StartsWith("clang_analyzer_dump",
105  &ExprInspectionChecker::analyzerDump)
106  .Case("clang_analyzer_getExtent",
107  &ExprInspectionChecker::analyzerGetExtent)
108  .Case("clang_analyzer_printState",
109  &ExprInspectionChecker::analyzerPrintState)
110  .Case("clang_analyzer_numTimesReached",
111  &ExprInspectionChecker::analyzerNumTimesReached)
112  .Case("clang_analyzer_hashDump",
113  &ExprInspectionChecker::analyzerHashDump)
114  .Case("clang_analyzer_denote", &ExprInspectionChecker::analyzerDenote)
115  .Case("clang_analyzer_express",
116  &ExprInspectionChecker::analyzerExpress)
117  .StartsWith("clang_analyzer_isTainted",
118  &ExprInspectionChecker::analyzerIsTainted)
119  .Default(nullptr);
120 
121  if (!Handler)
122  return false;
123 
124  (this->*Handler)(CE, C);
125  return true;
126 }
127 
128 static const char *getArgumentValueString(const CallExpr *CE,
129  CheckerContext &C) {
130  if (CE->getNumArgs() == 0)
131  return "Missing assertion argument";
132 
133  ExplodedNode *N = C.getPredecessor();
134  const LocationContext *LC = N->getLocationContext();
135  ProgramStateRef State = N->getState();
136 
137  const Expr *Assertion = CE->getArg(0);
138  SVal AssertionVal = State->getSVal(Assertion, LC);
139 
140  if (AssertionVal.isUndef())
141  return "UNDEFINED";
142 
143  ProgramStateRef StTrue, StFalse;
144  std::tie(StTrue, StFalse) =
145  State->assume(AssertionVal.castAs<DefinedOrUnknownSVal>());
146 
147  if (StTrue) {
148  if (StFalse)
149  return "UNKNOWN";
150  else
151  return "TRUE";
152  } else {
153  if (StFalse)
154  return "FALSE";
155  else
156  llvm_unreachable("Invalid constraint; neither true or false.");
157  }
158 }
159 
160 ExplodedNode *ExprInspectionChecker::reportBug(llvm::StringRef Msg,
161  CheckerContext &C,
162  Optional<SVal> ExprVal) const {
163  ExplodedNode *N = C.generateNonFatalErrorNode();
164  reportBug(Msg, C.getBugReporter(), N, ExprVal);
165  return N;
166 }
167 
168 ExplodedNode *ExprInspectionChecker::reportBug(llvm::StringRef Msg,
169  BugReporter &BR, ExplodedNode *N,
170  Optional<SVal> ExprVal) const {
171  if (!N)
172  return nullptr;
173 
174  if (!BT)
175  BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
176 
177  auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
178  if (ExprVal) {
179  R->markInteresting(*ExprVal);
180  }
181  BR.emitReport(std::move(R));
182  return N;
183 }
184 
185 const Expr *ExprInspectionChecker::getArgExpr(const CallExpr *CE,
186  CheckerContext &C) const {
187  if (CE->getNumArgs() == 0) {
188  reportBug("Missing argument", C);
189  return nullptr;
190  }
191  return CE->getArg(0);
192 }
193 
194 const MemRegion *ExprInspectionChecker::getArgRegion(const CallExpr *CE,
195  CheckerContext &C) const {
196  const Expr *Arg = getArgExpr(CE, C);
197  if (!Arg)
198  return nullptr;
199 
200  const MemRegion *MR = C.getSVal(Arg).getAsRegion();
201  if (!MR) {
202  reportBug("Cannot obtain the region", C);
203  return nullptr;
204  }
205 
206  return MR;
207 }
208 
209 void ExprInspectionChecker::analyzerEval(const CallExpr *CE,
210  CheckerContext &C) const {
211  const LocationContext *LC = C.getPredecessor()->getLocationContext();
212 
213  // A specific instantiation of an inlined function may have more constrained
214  // values than can generally be assumed. Skip the check.
215  if (LC->getStackFrame()->getParent() != nullptr)
216  return;
217 
218  reportBug(getArgumentValueString(CE, C), C);
219 }
220 
221 void ExprInspectionChecker::analyzerWarnIfReached(const CallExpr *CE,
222  CheckerContext &C) const {
223  reportBug("REACHABLE", C);
224 }
225 
226 void ExprInspectionChecker::analyzerNumTimesReached(const CallExpr *CE,
227  CheckerContext &C) const {
228  ++ReachedStats[CE].NumTimesReached;
229  if (!ReachedStats[CE].ExampleNode) {
230  // Later, in checkEndAnalysis, we'd throw a report against it.
231  ReachedStats[CE].ExampleNode = C.generateNonFatalErrorNode();
232  }
233 }
234 
235 void ExprInspectionChecker::analyzerCheckInlined(const CallExpr *CE,
236  CheckerContext &C) const {
237  const LocationContext *LC = C.getPredecessor()->getLocationContext();
238 
239  // An inlined function could conceivably also be analyzed as a top-level
240  // function. We ignore this case and only emit a message (TRUE or FALSE)
241  // when we are analyzing it as an inlined function. This means that
242  // clang_analyzer_checkInlined(true) should always print TRUE, but
243  // clang_analyzer_checkInlined(false) should never actually print anything.
244  if (LC->getStackFrame()->getParent() == nullptr)
245  return;
246 
247  reportBug(getArgumentValueString(CE, C), C);
248 }
249 
250 void ExprInspectionChecker::analyzerExplain(const CallExpr *CE,
251  CheckerContext &C) const {
252  const Expr *Arg = getArgExpr(CE, C);
253  if (!Arg)
254  return;
255 
256  SVal V = C.getSVal(Arg);
257  SValExplainer Ex(C.getASTContext());
258  reportBug(Ex.Visit(V), C);
259 }
260 
261 void ExprInspectionChecker::analyzerDumpSValType(const CallExpr *CE,
262  CheckerContext &C) const {
263  const Expr *Arg = getArgExpr(CE, C);
264  if (!Arg)
265  return;
266 
267  QualType Ty = C.getSVal(Arg).getType(C.getASTContext());
268  reportBug(Ty.getAsString(), C);
269 }
270 
271 void ExprInspectionChecker::analyzerDump(const CallExpr *CE,
272  CheckerContext &C) const {
273  const Expr *Arg = getArgExpr(CE, C);
274  if (!Arg)
275  return;
276 
277  SVal V = C.getSVal(Arg);
278 
280  llvm::raw_svector_ostream OS(Str);
281  V.dumpToStream(OS);
282  reportBug(OS.str(), C);
283 }
284 
285 void ExprInspectionChecker::analyzerGetExtent(const CallExpr *CE,
286  CheckerContext &C) const {
287  const MemRegion *MR = getArgRegion(CE, C);
288  if (!MR)
289  return;
290 
291  ProgramStateRef State = C.getState();
292  DefinedOrUnknownSVal Size = getDynamicExtent(State, MR, C.getSValBuilder());
293 
294  State = State->BindExpr(CE, C.getLocationContext(), Size);
295  C.addTransition(State);
296 }
297 
298 void ExprInspectionChecker::analyzerDumpExtent(const CallExpr *CE,
299  CheckerContext &C) const {
300  const MemRegion *MR = getArgRegion(CE, C);
301  if (!MR)
302  return;
303 
304  DefinedOrUnknownSVal Size =
305  getDynamicExtent(C.getState(), MR, C.getSValBuilder());
306 
307  SmallString<64> Msg;
308  llvm::raw_svector_ostream Out(Msg);
309  Out << Size;
310  reportBug(Out.str(), C);
311 }
312 
313 void ExprInspectionChecker::analyzerDumpElementCount(const CallExpr *CE,
314  CheckerContext &C) const {
315  const MemRegion *MR = getArgRegion(CE, C);
316  if (!MR)
317  return;
318 
319  QualType ElementTy;
320  if (const auto *TVR = MR->getAs<TypedValueRegion>()) {
321  ElementTy = TVR->getValueType();
322  } else {
323  ElementTy =
324  MR->castAs<SymbolicRegion>()->getSymbol()->getType()->getPointeeType();
325  }
326 
327  assert(!ElementTy->isPointerType());
328 
329  DefinedOrUnknownSVal ElementCount =
330  getDynamicElementCount(C.getState(), MR, C.getSValBuilder(), ElementTy);
331 
332  SmallString<128> Msg;
333  llvm::raw_svector_ostream Out(Msg);
334  Out << ElementCount;
335  reportBug(Out.str(), C);
336 }
337 
338 void ExprInspectionChecker::analyzerPrintState(const CallExpr *CE,
339  CheckerContext &C) const {
340  C.getState()->dump();
341 }
342 
343 void ExprInspectionChecker::analyzerWarnOnDeadSymbol(const CallExpr *CE,
344  CheckerContext &C) const {
345  const Expr *Arg = getArgExpr(CE, C);
346  if (!Arg)
347  return;
348 
349  SVal Val = C.getSVal(Arg);
350  SymbolRef Sym = Val.getAsSymbol();
351  if (!Sym)
352  return;
353 
354  ProgramStateRef State = C.getState();
355  State = State->add<MarkedSymbols>(Sym);
356  C.addTransition(State);
357 }
358 
359 void ExprInspectionChecker::checkDeadSymbols(SymbolReaper &SymReaper,
360  CheckerContext &C) const {
361  ProgramStateRef State = C.getState();
362  const MarkedSymbolsTy &Syms = State->get<MarkedSymbols>();
363  ExplodedNode *N = C.getPredecessor();
364  for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
365  SymbolRef Sym = *I;
366  if (!SymReaper.isDead(Sym))
367  continue;
368 
369  // The non-fatal error node should be the same for all reports.
370  if (ExplodedNode *BugNode = reportBug("SYMBOL DEAD", C))
371  N = BugNode;
372  State = State->remove<MarkedSymbols>(Sym);
373  }
374 
375  for (auto I : State->get<DenotedSymbols>()) {
376  SymbolRef Sym = I.first;
377  if (!SymReaper.isLive(Sym))
378  State = State->remove<DenotedSymbols>(Sym);
379  }
380 
381  C.addTransition(State, N);
382 }
383 
384 void ExprInspectionChecker::checkEndAnalysis(ExplodedGraph &G, BugReporter &BR,
385  ExprEngine &Eng) const {
386  for (auto Item : ReachedStats) {
387  unsigned NumTimesReached = Item.second.NumTimesReached;
388  ExplodedNode *N = Item.second.ExampleNode;
389 
390  reportBug(llvm::to_string(NumTimesReached), BR, N);
391  }
392  ReachedStats.clear();
393 }
394 
395 void ExprInspectionChecker::analyzerCrash(const CallExpr *CE,
396  CheckerContext &C) const {
397  LLVM_BUILTIN_TRAP;
398 }
399 
400 void ExprInspectionChecker::analyzerHashDump(const CallExpr *CE,
401  CheckerContext &C) const {
402  const LangOptions &Opts = C.getLangOpts();
403  const SourceManager &SM = C.getSourceManager();
404  FullSourceLoc FL(CE->getArg(0)->getBeginLoc(), SM);
405  std::string HashContent =
406  getIssueString(FL, getCheckerName().getName(), "Category",
407  C.getLocationContext()->getDecl(), Opts);
408 
409  reportBug(HashContent, C);
410 }
411 
412 void ExprInspectionChecker::analyzerDenote(const CallExpr *CE,
413  CheckerContext &C) const {
414  if (CE->getNumArgs() < 2) {
415  reportBug("clang_analyzer_denote() requires a symbol and a string literal",
416  C);
417  return;
418  }
419 
420  SymbolRef Sym = C.getSVal(CE->getArg(0)).getAsSymbol();
421  if (!Sym) {
422  reportBug("Not a symbol", C);
423  return;
424  }
425 
426  const auto *E = dyn_cast<StringLiteral>(CE->getArg(1)->IgnoreParenCasts());
427  if (!E) {
428  reportBug("Not a string literal", C);
429  return;
430  }
431 
432  ProgramStateRef State = C.getState();
433 
434  C.addTransition(C.getState()->set<DenotedSymbols>(Sym, E));
435 }
436 
437 namespace {
438 class SymbolExpressor
439  : public SymExprVisitor<SymbolExpressor, Optional<std::string>> {
441 
442 public:
443  SymbolExpressor(ProgramStateRef State) : State(State) {}
444 
445  Optional<std::string> lookup(const SymExpr *S) {
446  if (const StringLiteral *const *SLPtr = State->get<DenotedSymbols>(S)) {
447  const StringLiteral *SL = *SLPtr;
448  return std::string(SL->getBytes());
449  }
450  return None;
451  }
452 
453  Optional<std::string> VisitSymExpr(const SymExpr *S) { return lookup(S); }
454 
455  Optional<std::string> VisitSymIntExpr(const SymIntExpr *S) {
456  if (Optional<std::string> Str = lookup(S))
457  return Str;
458  if (Optional<std::string> Str = Visit(S->getLHS()))
459  return (*Str + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) + " " +
460  std::to_string(S->getRHS().getLimitedValue()) +
461  (S->getRHS().isUnsigned() ? "U" : ""))
462  .str();
463  return None;
464  }
465 
466  Optional<std::string> VisitSymSymExpr(const SymSymExpr *S) {
467  if (Optional<std::string> Str = lookup(S))
468  return Str;
469  if (Optional<std::string> Str1 = Visit(S->getLHS()))
470  if (Optional<std::string> Str2 = Visit(S->getRHS()))
471  return (*Str1 + " " + BinaryOperator::getOpcodeStr(S->getOpcode()) +
472  " " + *Str2)
473  .str();
474  return None;
475  }
476 
477  Optional<std::string> VisitSymbolCast(const SymbolCast *S) {
478  if (Optional<std::string> Str = lookup(S))
479  return Str;
480  if (Optional<std::string> Str = Visit(S->getOperand()))
481  return (Twine("(") + S->getType().getAsString() + ")" + *Str).str();
482  return None;
483  }
484 };
485 } // namespace
486 
487 void ExprInspectionChecker::analyzerExpress(const CallExpr *CE,
488  CheckerContext &C) const {
489  const Expr *Arg = getArgExpr(CE, C);
490  if (!Arg)
491  return;
492 
493  SVal ArgVal = C.getSVal(CE->getArg(0));
494  SymbolRef Sym = ArgVal.getAsSymbol();
495  if (!Sym) {
496  reportBug("Not a symbol", C);
497  return;
498  }
499 
500  SymbolExpressor V(C.getState());
501  auto Str = V.Visit(Sym);
502  if (!Str) {
503  reportBug("Unable to express", C);
504  return;
505  }
506 
507  reportBug(*Str, C, ArgVal);
508 }
509 
510 void ExprInspectionChecker::analyzerIsTainted(const CallExpr *CE,
511  CheckerContext &C) const {
512  if (CE->getNumArgs() != 1) {
513  reportBug("clang_analyzer_isTainted() requires exactly one argument", C);
514  return;
515  }
516  const bool IsTainted =
517  taint::isTainted(C.getState(), CE->getArg(0), C.getLocationContext());
518  reportBug(IsTainted ? "YES" : "NO", C);
519 }
520 
521 void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
522  Mgr.registerChecker<ExprInspectionChecker>();
523 }
524 
525 bool ento::shouldRegisterExprInspectionChecker(const CheckerManager &mgr) {
526  return true;
527 }
DynamicExtent.h
clang::LocationContext
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Definition: AnalysisDeclContext.h:215
clang::LocationContext::getStackFrame
const StackFrameContext * getStackFrame() const
Definition: AnalysisDeclContext.cpp:463
clang::FullSourceLoc
A SourceLocation and its associated SourceManager.
Definition: SourceLocation.h:368
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::getIssueString
std::string getIssueString(const FullSourceLoc &IssueLoc, llvm::StringRef CheckerName, llvm::StringRef WarningMessage, const Decl *IssueDecl, const LangOptions &LangOpts)
Get the unhashed string representation of the V1 issue hash.
clang::ento::ProgramStateRef
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Definition: ProgramState_Fwd.h:37
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:675
AttributeLangSupport::C
@ C
Definition: SemaDeclAttr.cpp:55
clang::BinaryOperator::getOpcodeStr
StringRef getOpcodeStr() const
Definition: Expr.h:3872
clang::ento::SymbolRef
const SymExpr * SymbolRef
Definition: SymExpr.h:110
llvm::Optional
Definition: LLVM.h:40
clang::QualType::getAsString
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1023
clang::ento::taint::isTainted
bool isTainted(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric)
Check if the statement has a tainted value in the given state.
clang::index::SymbolRole::Call
@ Call
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:627
clang::ento::SymSymExpr
BinarySymExprImpl< const SymExpr *, const SymExpr *, SymExpr::Kind::SymSymExprKind > SymSymExpr
Represents a symbolic expression like 'x' + 'y'.
Definition: SymbolManager.h:415
CallEvent.h
REGISTER_MAP_WITH_PROGRAMSTATE
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
Definition: ProgramStateTrait.h:84
V
#define V(N, I)
Definition: ASTContext.h:3176
BuiltinCheckerRegistration.h
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
clang::StringLiteral::getBytes
StringRef getBytes() const
Allow access to clients that need the byte representation, such as ASTWriterStmt::VisitStringLiteral(...
Definition: Expr.h:1858
IssueHash.h
clang::CallExpr::getArg
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:2992
getArgumentValueString
static const char * getArgumentValueString(const CallExpr *CE, CheckerContext &C)
Definition: ExprInspectionChecker.cpp:128
llvm::SmallString< 32 >
REGISTER_SET_WITH_PROGRAMSTATE
#define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem)
Declares an immutable set of type NameTy, suitable for placement into the ProgramState.
Definition: ProgramStateTrait.h:109
clang::StringLiteral
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1767
clang::ento::getDynamicElementCount
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB, QualType Ty)
getName
static std::string getName(const CallEvent &Call)
Definition: ReturnValueChecker.cpp:61
clang::Type::castAs
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7310
clang::LocationContext::getParent
const LocationContext * getParent() const
Definition: AnalysisDeclContext.h:243
clang::Expr::IgnoreParenCasts
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2952
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6748
clang::syntax::NodeRole::Size
@ Size
clang::ento::SymIntExpr
BinarySymExprImpl< const SymExpr *, const llvm::APSInt &, SymExpr::Kind::SymIntExprKind > SymIntExpr
Represents a symbolic expression like 'x' + 3.
Definition: SymbolManager.h:407
Taint.h
BugType.h
clang::CallExpr::getNumArgs
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:2979
State
LineState State
Definition: UnwrappedLineFormatter.cpp:1089
CheckerContext.h
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:78
clang::ento::getDynamicExtent
DefinedOrUnknownSVal getDynamicExtent(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB)
Checker.h
clang
Definition: CalledOnceCheck.h:17
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
clang::Expr
This represents one expression.
Definition: Expr.h:109
SValExplainer.h
SM
#define SM(sm)
Definition: Cuda.cpp:81
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2801
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...