clang  15.0.0git
BugReporterVisitors.cpp
Go to the documentation of this file.
1 //===- BugReporterVisitors.cpp - Helpers for reporting bugs ---------------===//
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 //
9 // This file defines a set of BugReporter "visitors" which can be used to
10 // enhance the diagnostics reported for a bug.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclBase.h"
18 #include "clang/AST/DeclCXX.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/ExprObjC.h"
22 #include "clang/AST/Stmt.h"
23 #include "clang/AST/Type.h"
27 #include "clang/Analysis/CFG.h"
32 #include "clang/Basic/LLVM.h"
35 #include "clang/Lex/Lexer.h"
48 #include "llvm/ADT/ArrayRef.h"
49 #include "llvm/ADT/None.h"
50 #include "llvm/ADT/Optional.h"
51 #include "llvm/ADT/STLExtras.h"
52 #include "llvm/ADT/SmallPtrSet.h"
53 #include "llvm/ADT/SmallString.h"
54 #include "llvm/ADT/SmallVector.h"
55 #include "llvm/ADT/StringExtras.h"
56 #include "llvm/ADT/StringRef.h"
57 #include "llvm/Support/Casting.h"
58 #include "llvm/Support/ErrorHandling.h"
59 #include "llvm/Support/raw_ostream.h"
60 #include <cassert>
61 #include <deque>
62 #include <memory>
63 #include <string>
64 #include <utility>
65 
66 using namespace clang;
67 using namespace ento;
68 using namespace bugreporter;
69 
70 //===----------------------------------------------------------------------===//
71 // Utility functions.
72 //===----------------------------------------------------------------------===//
73 
74 static const Expr *peelOffPointerArithmetic(const BinaryOperator *B) {
75  if (B->isAdditiveOp() && B->getType()->isPointerType()) {
76  if (B->getLHS()->getType()->isPointerType()) {
77  return B->getLHS();
78  } else if (B->getRHS()->getType()->isPointerType()) {
79  return B->getRHS();
80  }
81  }
82  return nullptr;
83 }
84 
85 /// \return A subexpression of @c Ex which represents the
86 /// expression-of-interest.
87 static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N);
88 
89 /// Given that expression S represents a pointer that would be dereferenced,
90 /// try to find a sub-expression from which the pointer came from.
91 /// This is used for tracking down origins of a null or undefined value:
92 /// "this is null because that is null because that is null" etc.
93 /// We wipe away field and element offsets because they merely add offsets.
94 /// We also wipe away all casts except lvalue-to-rvalue casts, because the
95 /// latter represent an actual pointer dereference; however, we remove
96 /// the final lvalue-to-rvalue cast before returning from this function
97 /// because it demonstrates more clearly from where the pointer rvalue was
98 /// loaded. Examples:
99 /// x->y.z ==> x (lvalue)
100 /// foo()->y.z ==> foo() (rvalue)
101 const Expr *bugreporter::getDerefExpr(const Stmt *S) {
102  const auto *E = dyn_cast<Expr>(S);
103  if (!E)
104  return nullptr;
105 
106  while (true) {
107  if (const auto *CE = dyn_cast<CastExpr>(E)) {
108  if (CE->getCastKind() == CK_LValueToRValue) {
109  // This cast represents the load we're looking for.
110  break;
111  }
112  E = CE->getSubExpr();
113  } else if (const auto *B = dyn_cast<BinaryOperator>(E)) {
114  // Pointer arithmetic: '*(x + 2)' -> 'x') etc.
115  if (const Expr *Inner = peelOffPointerArithmetic(B)) {
116  E = Inner;
117  } else {
118  // Probably more arithmetic can be pattern-matched here,
119  // but for now give up.
120  break;
121  }
122  } else if (const auto *U = dyn_cast<UnaryOperator>(E)) {
123  if (U->getOpcode() == UO_Deref || U->getOpcode() == UO_AddrOf ||
124  (U->isIncrementDecrementOp() && U->getType()->isPointerType())) {
125  // Operators '*' and '&' don't actually mean anything.
126  // We look at casts instead.
127  E = U->getSubExpr();
128  } else {
129  // Probably more arithmetic can be pattern-matched here,
130  // but for now give up.
131  break;
132  }
133  }
134  // Pattern match for a few useful cases: a[0], p->f, *p etc.
135  else if (const auto *ME = dyn_cast<MemberExpr>(E)) {
136  E = ME->getBase();
137  } else if (const auto *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
138  E = IvarRef->getBase();
139  } else if (const auto *AE = dyn_cast<ArraySubscriptExpr>(E)) {
140  E = AE->getBase();
141  } else if (const auto *PE = dyn_cast<ParenExpr>(E)) {
142  E = PE->getSubExpr();
143  } else if (const auto *FE = dyn_cast<FullExpr>(E)) {
144  E = FE->getSubExpr();
145  } else {
146  // Other arbitrary stuff.
147  break;
148  }
149  }
150 
151  // Special case: remove the final lvalue-to-rvalue cast, but do not recurse
152  // deeper into the sub-expression. This way we return the lvalue from which
153  // our pointer rvalue was loaded.
154  if (const auto *CE = dyn_cast<ImplicitCastExpr>(E))
155  if (CE->getCastKind() == CK_LValueToRValue)
156  E = CE->getSubExpr();
157 
158  return E;
159 }
160 
161 static const MemRegion *
162 getLocationRegionIfReference(const Expr *E, const ExplodedNode *N,
163  bool LookingForReference = true) {
164  if (const auto *DR = dyn_cast<DeclRefExpr>(E)) {
165  if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
166  if (LookingForReference && !VD->getType()->isReferenceType())
167  return nullptr;
168  return N->getState()
169  ->getLValue(VD, N->getLocationContext())
170  .getAsRegion();
171  }
172  }
173 
174  // FIXME: This does not handle other kinds of null references,
175  // for example, references from FieldRegions:
176  // struct Wrapper { int &ref; };
177  // Wrapper w = { *(int *)0 };
178  // w.ref = 1;
179 
180  return nullptr;
181 }
182 
183 /// Comparing internal representations of symbolic values (via
184 /// SVal::operator==()) is a valid way to check if the value was updated,
185 /// unless it's a LazyCompoundVal that may have a different internal
186 /// representation every time it is loaded from the state. In this function we
187 /// do an approximate comparison for lazy compound values, checking that they
188 /// are the immediate snapshots of the tracked region's bindings within the
189 /// node's respective states but not really checking that these snapshots
190 /// actually contain the same set of bindings.
191 static bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal,
192  const ExplodedNode *RightNode, SVal RightVal) {
193  if (LeftVal == RightVal)
194  return true;
195 
196  const auto LLCV = LeftVal.getAs<nonloc::LazyCompoundVal>();
197  if (!LLCV)
198  return false;
199 
200  const auto RLCV = RightVal.getAs<nonloc::LazyCompoundVal>();
201  if (!RLCV)
202  return false;
203 
204  return LLCV->getRegion() == RLCV->getRegion() &&
205  LLCV->getStore() == LeftNode->getState()->getStore() &&
206  RLCV->getStore() == RightNode->getState()->getStore();
207 }
208 
209 static Optional<SVal> getSValForVar(const Expr *CondVarExpr,
210  const ExplodedNode *N) {
211  ProgramStateRef State = N->getState();
212  const LocationContext *LCtx = N->getLocationContext();
213 
214  assert(CondVarExpr);
215  CondVarExpr = CondVarExpr->IgnoreImpCasts();
216 
217  // The declaration of the value may rely on a pointer so take its l-value.
218  // FIXME: As seen in VisitCommonDeclRefExpr, sometimes DeclRefExpr may
219  // evaluate to a FieldRegion when it refers to a declaration of a lambda
220  // capture variable. We most likely need to duplicate that logic here.
221  if (const auto *DRE = dyn_cast<DeclRefExpr>(CondVarExpr))
222  if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
223  return State->getSVal(State->getLValue(VD, LCtx));
224 
225  if (const auto *ME = dyn_cast<MemberExpr>(CondVarExpr))
226  if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
227  if (auto FieldL = State->getSVal(ME, LCtx).getAs<Loc>())
228  return State->getRawSVal(*FieldL, FD->getType());
229 
230  return None;
231 }
232 
234 getConcreteIntegerValue(const Expr *CondVarExpr, const ExplodedNode *N) {
235 
236  if (Optional<SVal> V = getSValForVar(CondVarExpr, N))
237  if (auto CI = V->getAs<nonloc::ConcreteInt>())
238  return &CI->getValue();
239  return None;
240 }
241 
242 static bool isVarAnInterestingCondition(const Expr *CondVarExpr,
243  const ExplodedNode *N,
244  const PathSensitiveBugReport *B) {
245  // Even if this condition is marked as interesting, it isn't *that*
246  // interesting if it didn't happen in a nested stackframe, the user could just
247  // follow the arrows.
248  if (!B->getErrorNode()->getStackFrame()->isParentOf(N->getStackFrame()))
249  return false;
250 
251  if (Optional<SVal> V = getSValForVar(CondVarExpr, N))
252  if (Optional<bugreporter::TrackingKind> K = B->getInterestingnessKind(*V))
254 
255  return false;
256 }
257 
258 static bool isInterestingExpr(const Expr *E, const ExplodedNode *N,
259  const PathSensitiveBugReport *B) {
260  if (Optional<SVal> V = getSValForVar(E, N))
261  return B->getInterestingnessKind(*V).has_value();
262  return false;
263 }
264 
265 /// \return name of the macro inside the location \p Loc.
266 static StringRef getMacroName(SourceLocation Loc,
267  BugReporterContext &BRC) {
269  Loc,
270  BRC.getSourceManager(),
271  BRC.getASTContext().getLangOpts());
272 }
273 
274 /// \return Whether given spelling location corresponds to an expansion
275 /// of a function-like macro.
277  const SourceManager &SM) {
278  if (!Loc.isMacroID())
279  return false;
280  while (SM.isMacroArgExpansion(Loc))
281  Loc = SM.getImmediateExpansionRange(Loc).getBegin();
282  std::pair<FileID, unsigned> TLInfo = SM.getDecomposedLoc(Loc);
283  SrcMgr::SLocEntry SE = SM.getSLocEntry(TLInfo.first);
284  const SrcMgr::ExpansionInfo &EInfo = SE.getExpansion();
285  return EInfo.isFunctionMacroExpansion();
286 }
287 
288 /// \return Whether \c RegionOfInterest was modified at \p N,
289 /// where \p ValueAfter is \c RegionOfInterest's value at the end of the
290 /// stack frame.
291 static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest,
292  const ExplodedNode *N,
293  SVal ValueAfter) {
294  ProgramStateRef State = N->getState();
295  ProgramStateManager &Mgr = N->getState()->getStateManager();
296 
297  if (!N->getLocationAs<PostStore>() && !N->getLocationAs<PostInitializer>() &&
298  !N->getLocationAs<PostStmt>())
299  return false;
300 
301  // Writing into region of interest.
302  if (auto PS = N->getLocationAs<PostStmt>())
303  if (auto *BO = PS->getStmtAs<BinaryOperator>())
304  if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(
305  N->getSVal(BO->getLHS()).getAsRegion()))
306  return true;
307 
308  // SVal after the state is possibly different.
309  SVal ValueAtN = N->getState()->getSVal(RegionOfInterest);
310  if (!Mgr.getSValBuilder()
311  .areEqual(State, ValueAtN, ValueAfter)
312  .isConstrainedTrue() &&
313  (!ValueAtN.isUndef() || !ValueAfter.isUndef()))
314  return true;
315 
316  return false;
317 }
318 
319 //===----------------------------------------------------------------------===//
320 // Implementation of BugReporterVisitor.
321 //===----------------------------------------------------------------------===//
322 
324  const ExplodedNode *,
326  return nullptr;
327 }
328 
330  const ExplodedNode *,
332 
335  const ExplodedNode *EndPathNode,
336  const PathSensitiveBugReport &BR) {
338  const auto &Ranges = BR.getRanges();
339 
340  // Only add the statement itself as a range if we didn't specify any
341  // special ranges for this report.
342  auto P = std::make_shared<PathDiagnosticEventPiece>(
343  L, BR.getDescription(), Ranges.begin() == Ranges.end());
344  for (SourceRange Range : Ranges)
345  P->addRange(Range);
346 
347  return P;
348 }
349 
350 //===----------------------------------------------------------------------===//
351 // Implementation of NoStateChangeFuncVisitor.
352 //===----------------------------------------------------------------------===//
353 
354 bool NoStateChangeFuncVisitor::isModifiedInFrame(const ExplodedNode *N) {
355  const LocationContext *Ctx = N->getLocationContext();
356  const StackFrameContext *SCtx = Ctx->getStackFrame();
357  if (!FramesModifyingCalculated.count(SCtx))
358  findModifyingFrames(N);
359  return FramesModifying.count(SCtx);
360 }
361 
362 void NoStateChangeFuncVisitor::markFrameAsModifying(
363  const StackFrameContext *SCtx) {
364  while (!SCtx->inTopFrame()) {
365  auto p = FramesModifying.insert(SCtx);
366  if (!p.second)
367  break; // Frame and all its parents already inserted.
368 
369  SCtx = SCtx->getParent()->getStackFrame();
370  }
371 }
372 
373 static const ExplodedNode *getMatchingCallExitEnd(const ExplodedNode *N) {
374  assert(N->getLocationAs<CallEnter>());
375  // The stackframe of the callee is only found in the nodes succeeding
376  // the CallEnter node. CallEnter's stack frame refers to the caller.
377  const StackFrameContext *OrigSCtx = N->getFirstSucc()->getStackFrame();
378 
379  // Similarly, the nodes preceding CallExitEnd refer to the callee's stack
380  // frame.
381  auto IsMatchingCallExitEnd = [OrigSCtx](const ExplodedNode *N) {
382  return N->getLocationAs<CallExitEnd>() &&
383  OrigSCtx == N->getFirstPred()->getStackFrame();
384  };
385  while (N && !IsMatchingCallExitEnd(N)) {
386  assert(N->succ_size() <= 1 &&
387  "This function is to be used on the trimmed ExplodedGraph!");
388  N = N->getFirstSucc();
389  }
390  return N;
391 }
392 
393 void NoStateChangeFuncVisitor::findModifyingFrames(
394  const ExplodedNode *const CallExitBeginN) {
395 
396  assert(CallExitBeginN->getLocationAs<CallExitBegin>());
397 
398  const StackFrameContext *const OriginalSCtx =
399  CallExitBeginN->getLocationContext()->getStackFrame();
400 
401  const ExplodedNode *CurrCallExitBeginN = CallExitBeginN;
402  const StackFrameContext *CurrentSCtx = OriginalSCtx;
403 
404  for (const ExplodedNode *CurrN = CallExitBeginN; CurrN;
405  CurrN = CurrN->getFirstPred()) {
406  // Found a new inlined call.
407  if (CurrN->getLocationAs<CallExitBegin>()) {
408  CurrCallExitBeginN = CurrN;
409  CurrentSCtx = CurrN->getStackFrame();
410  FramesModifyingCalculated.insert(CurrentSCtx);
411  // We won't see a change in between two identical exploded nodes: skip.
412  continue;
413  }
414 
415  if (auto CE = CurrN->getLocationAs<CallEnter>()) {
416  if (const ExplodedNode *CallExitEndN = getMatchingCallExitEnd(CurrN))
417  if (wasModifiedInFunction(CurrN, CallExitEndN))
418  markFrameAsModifying(CurrentSCtx);
419 
420  // We exited this inlined call, lets actualize the stack frame.
421  CurrentSCtx = CurrN->getStackFrame();
422 
423  // Stop calculating at the current function, but always regard it as
424  // modifying, so we can avoid notes like this:
425  // void f(Foo &F) {
426  // F.field = 0; // note: 0 assigned to 'F.field'
427  // // note: returning without writing to 'F.field'
428  // }
429  if (CE->getCalleeContext() == OriginalSCtx) {
430  markFrameAsModifying(CurrentSCtx);
431  break;
432  }
433  }
434 
435  if (wasModifiedBeforeCallExit(CurrN, CurrCallExitBeginN))
436  markFrameAsModifying(CurrentSCtx);
437  }
438 }
439 
442 
443  const LocationContext *Ctx = N->getLocationContext();
444  const StackFrameContext *SCtx = Ctx->getStackFrame();
446  auto CallExitLoc = N->getLocationAs<CallExitBegin>();
447 
448  // No diagnostic if region was modified inside the frame.
449  if (!CallExitLoc || isModifiedInFrame(N))
450  return nullptr;
451 
452  CallEventRef<> Call =
454 
455  // Optimistically suppress uninitialized value bugs that result
456  // from system headers having a chance to initialize the value
457  // but failing to do so. It's too unlikely a system header's fault.
458  // It's much more likely a situation in which the function has a failure
459  // mode that the user decided not to check. If we want to hunt such
460  // omitted checks, we should provide an explicit function-specific note
461  // describing the precondition under which the function isn't supposed to
462  // initialize its out-parameter, and additionally check that such
463  // precondition can actually be fulfilled on the current path.
464  if (Call->isInSystemHeader()) {
465  // We make an exception for system header functions that have no branches.
466  // Such functions unconditionally fail to initialize the variable.
467  // If they call other functions that have more paths within them,
468  // this suppression would still apply when we visit these inner functions.
469  // One common example of a standard function that doesn't ever initialize
470  // its out parameter is operator placement new; it's up to the follow-up
471  // constructor (if any) to initialize the memory.
472  if (!N->getStackFrame()->getCFG()->isLinear()) {
473  static int i = 0;
474  R.markInvalid(&i, nullptr);
475  }
476  return nullptr;
477  }
478 
479  if (const auto *MC = dyn_cast<ObjCMethodCall>(Call)) {
480  // If we failed to construct a piece for self, we still want to check
481  // whether the entity of interest is in a parameter.
482  if (PathDiagnosticPieceRef Piece = maybeEmitNoteForObjCSelf(R, *MC, N))
483  return Piece;
484  }
485 
486  if (const auto *CCall = dyn_cast<CXXConstructorCall>(Call)) {
487  // Do not generate diagnostics for not modified parameters in
488  // constructors.
489  return maybeEmitNoteForCXXThis(R, *CCall, N);
490  }
491 
492  return maybeEmitNoteForParameters(R, *Call, N);
493 }
494 
495 //===----------------------------------------------------------------------===//
496 // Implementation of NoStoreFuncVisitor.
497 //===----------------------------------------------------------------------===//
498 
499 namespace {
500 /// Put a diagnostic on return statement of all inlined functions
501 /// for which the region of interest \p RegionOfInterest was passed into,
502 /// but not written inside, and it has caused an undefined read or a null
503 /// pointer dereference outside.
504 class NoStoreFuncVisitor final : public NoStateChangeFuncVisitor {
505  const SubRegion *RegionOfInterest;
506  MemRegionManager &MmrMgr;
507  const SourceManager &SM;
508  const PrintingPolicy &PP;
509 
510  /// Recursion limit for dereferencing fields when looking for the
511  /// region of interest.
512  /// The limit of two indicates that we will dereference fields only once.
513  static const unsigned DEREFERENCE_LIMIT = 2;
514 
515  using RegionVector = SmallVector<const MemRegion *, 5>;
516 
517 public:
518  NoStoreFuncVisitor(const SubRegion *R, bugreporter::TrackingKind TKind)
519  : NoStateChangeFuncVisitor(TKind), RegionOfInterest(R),
520  MmrMgr(R->getMemRegionManager()),
521  SM(MmrMgr.getContext().getSourceManager()),
522  PP(MmrMgr.getContext().getPrintingPolicy()) {}
523 
524  void Profile(llvm::FoldingSetNodeID &ID) const override {
525  static int Tag = 0;
526  ID.AddPointer(&Tag);
527  ID.AddPointer(RegionOfInterest);
528  }
529 
530 private:
531  /// \return Whether \c RegionOfInterest was modified at \p CurrN compared to
532  /// the value it holds in \p CallExitBeginN.
533  virtual bool
534  wasModifiedBeforeCallExit(const ExplodedNode *CurrN,
535  const ExplodedNode *CallExitBeginN) override;
536 
537  /// Attempts to find the region of interest in a given record decl,
538  /// by either following the base classes or fields.
539  /// Dereferences fields up to a given recursion limit.
540  /// Note that \p Vec is passed by value, leading to quadratic copying cost,
541  /// but it's OK in practice since its length is limited to DEREFERENCE_LIMIT.
542  /// \return A chain fields leading to the region of interest or None.
544  findRegionOfInterestInRecord(const RecordDecl *RD, ProgramStateRef State,
545  const MemRegion *R, const RegionVector &Vec = {},
546  int depth = 0);
547 
548  // Region of interest corresponds to an IVar, exiting a method
549  // which could have written into that IVar, but did not.
550  virtual PathDiagnosticPieceRef
551  maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
552  const ObjCMethodCall &Call,
553  const ExplodedNode *N) override final;
554 
555  virtual PathDiagnosticPieceRef
556  maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
557  const CXXConstructorCall &Call,
558  const ExplodedNode *N) override final;
559 
560  virtual PathDiagnosticPieceRef
561  maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call,
562  const ExplodedNode *N) override final;
563 
564  /// Consume the information on the no-store stack frame in order to
565  /// either emit a note or suppress the report enirely.
566  /// \return Diagnostics piece for region not modified in the current function,
567  /// if it decides to emit one.
569  maybeEmitNote(PathSensitiveBugReport &R, const CallEvent &Call,
570  const ExplodedNode *N, const RegionVector &FieldChain,
571  const MemRegion *MatchedRegion, StringRef FirstElement,
572  bool FirstIsReferenceType, unsigned IndirectionLevel);
573 
574  bool prettyPrintRegionName(const RegionVector &FieldChain,
575  const MemRegion *MatchedRegion,
576  StringRef FirstElement, bool FirstIsReferenceType,
577  unsigned IndirectionLevel,
578  llvm::raw_svector_ostream &os);
579 
580  StringRef prettyPrintFirstElement(StringRef FirstElement,
581  bool MoreItemsExpected,
582  int IndirectionLevel,
583  llvm::raw_svector_ostream &os);
584 };
585 } // namespace
586 
587 /// \return Whether the method declaration \p Parent
588 /// syntactically has a binary operation writing into the ivar \p Ivar.
590  const ObjCIvarDecl *Ivar) {
591  using namespace ast_matchers;
592  const char *IvarBind = "Ivar";
593  if (!Parent || !Parent->hasBody())
594  return false;
595  StatementMatcher WriteIntoIvarM = binaryOperator(
596  hasOperatorName("="),
597  hasLHS(ignoringParenImpCasts(
598  objcIvarRefExpr(hasDeclaration(equalsNode(Ivar))).bind(IvarBind))));
599  StatementMatcher ParentM = stmt(hasDescendant(WriteIntoIvarM));
600  auto Matches = match(ParentM, *Parent->getBody(), Parent->getASTContext());
601  for (BoundNodes &Match : Matches) {
602  auto IvarRef = Match.getNodeAs<ObjCIvarRefExpr>(IvarBind);
603  if (IvarRef->isFreeIvar())
604  return true;
605 
606  const Expr *Base = IvarRef->getBase();
607  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(Base))
608  Base = ICE->getSubExpr();
609 
610  if (const auto *DRE = dyn_cast<DeclRefExpr>(Base))
611  if (const auto *ID = dyn_cast<ImplicitParamDecl>(DRE->getDecl()))
612  if (ID->getParameterKind() == ImplicitParamDecl::ObjCSelf)
613  return true;
614 
615  return false;
616  }
617  return false;
618 }
619 
620 /// Attempts to find the region of interest in a given CXX decl,
621 /// by either following the base classes or fields.
622 /// Dereferences fields up to a given recursion limit.
623 /// Note that \p Vec is passed by value, leading to quadratic copying cost,
624 /// but it's OK in practice since its length is limited to DEREFERENCE_LIMIT.
625 /// \return A chain fields leading to the region of interest or None.
627 NoStoreFuncVisitor::findRegionOfInterestInRecord(
628  const RecordDecl *RD, ProgramStateRef State, const MemRegion *R,
629  const NoStoreFuncVisitor::RegionVector &Vec /* = {} */,
630  int depth /* = 0 */) {
631 
632  if (depth == DEREFERENCE_LIMIT) // Limit the recursion depth.
633  return None;
634 
635  if (const auto *RDX = dyn_cast<CXXRecordDecl>(RD))
636  if (!RDX->hasDefinition())
637  return None;
638 
639  // Recursively examine the base classes.
640  // Note that following base classes does not increase the recursion depth.
641  if (const auto *RDX = dyn_cast<CXXRecordDecl>(RD))
642  for (const auto &II : RDX->bases())
643  if (const RecordDecl *RRD = II.getType()->getAsRecordDecl())
644  if (Optional<RegionVector> Out =
645  findRegionOfInterestInRecord(RRD, State, R, Vec, depth))
646  return Out;
647 
648  for (const FieldDecl *I : RD->fields()) {
649  QualType FT = I->getType();
650  const FieldRegion *FR = MmrMgr.getFieldRegion(I, cast<SubRegion>(R));
651  const SVal V = State->getSVal(FR);
652  const MemRegion *VR = V.getAsRegion();
653 
654  RegionVector VecF = Vec;
655  VecF.push_back(FR);
656 
657  if (RegionOfInterest == VR)
658  return VecF;
659 
660  if (const RecordDecl *RRD = FT->getAsRecordDecl())
661  if (auto Out =
662  findRegionOfInterestInRecord(RRD, State, FR, VecF, depth + 1))
663  return Out;
664 
665  QualType PT = FT->getPointeeType();
666  if (PT.isNull() || PT->isVoidType() || !VR)
667  continue;
668 
669  if (const RecordDecl *RRD = PT->getAsRecordDecl())
670  if (Optional<RegionVector> Out =
671  findRegionOfInterestInRecord(RRD, State, VR, VecF, depth + 1))
672  return Out;
673  }
674 
675  return None;
676 }
677 
679 NoStoreFuncVisitor::maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
680  const ObjCMethodCall &Call,
681  const ExplodedNode *N) {
682  if (const auto *IvarR = dyn_cast<ObjCIvarRegion>(RegionOfInterest)) {
683  const MemRegion *SelfRegion = Call.getReceiverSVal().getAsRegion();
684  if (RegionOfInterest->isSubRegionOf(SelfRegion) &&
685  potentiallyWritesIntoIvar(Call.getRuntimeDefinition().getDecl(),
686  IvarR->getDecl()))
687  return maybeEmitNote(R, Call, N, {}, SelfRegion, "self",
688  /*FirstIsReferenceType=*/false, 1);
689  }
690  return nullptr;
691 }
692 
694 NoStoreFuncVisitor::maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
695  const CXXConstructorCall &Call,
696  const ExplodedNode *N) {
697  const MemRegion *ThisR = Call.getCXXThisVal().getAsRegion();
698  if (RegionOfInterest->isSubRegionOf(ThisR) && !Call.getDecl()->isImplicit())
699  return maybeEmitNote(R, Call, N, {}, ThisR, "this",
700  /*FirstIsReferenceType=*/false, 1);
701 
702  // Do not generate diagnostics for not modified parameters in
703  // constructors.
704  return nullptr;
705 }
706 
707 /// \return whether \p Ty points to a const type, or is a const reference.
708 static bool isPointerToConst(QualType Ty) {
709  return !Ty->getPointeeType().isNull() &&
711 }
712 
713 PathDiagnosticPieceRef NoStoreFuncVisitor::maybeEmitNoteForParameters(
714  PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N) {
715  ArrayRef<ParmVarDecl *> Parameters = Call.parameters();
716  for (unsigned I = 0; I < Call.getNumArgs() && I < Parameters.size(); ++I) {
717  const ParmVarDecl *PVD = Parameters[I];
718  SVal V = Call.getArgSVal(I);
719  bool ParamIsReferenceType = PVD->getType()->isReferenceType();
720  std::string ParamName = PVD->getNameAsString();
721 
722  unsigned IndirectionLevel = 1;
723  QualType T = PVD->getType();
724  while (const MemRegion *MR = V.getAsRegion()) {
725  if (RegionOfInterest->isSubRegionOf(MR) && !isPointerToConst(T))
726  return maybeEmitNote(R, Call, N, {}, MR, ParamName,
727  ParamIsReferenceType, IndirectionLevel);
728 
729  QualType PT = T->getPointeeType();
730  if (PT.isNull() || PT->isVoidType())
731  break;
732 
733  ProgramStateRef State = N->getState();
734 
735  if (const RecordDecl *RD = PT->getAsRecordDecl())
737  findRegionOfInterestInRecord(RD, State, MR))
738  return maybeEmitNote(R, Call, N, *P, RegionOfInterest, ParamName,
739  ParamIsReferenceType, IndirectionLevel);
740 
741  V = State->getSVal(MR, PT);
742  T = PT;
743  IndirectionLevel++;
744  }
745  }
746 
747  return nullptr;
748 }
749 
750 bool NoStoreFuncVisitor::wasModifiedBeforeCallExit(
751  const ExplodedNode *CurrN, const ExplodedNode *CallExitBeginN) {
753  RegionOfInterest, CurrN,
754  CallExitBeginN->getState()->getSVal(RegionOfInterest));
755 }
756 
757 static llvm::StringLiteral WillBeUsedForACondition =
758  ", which participates in a condition later";
759 
760 PathDiagnosticPieceRef NoStoreFuncVisitor::maybeEmitNote(
761  PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N,
762  const RegionVector &FieldChain, const MemRegion *MatchedRegion,
763  StringRef FirstElement, bool FirstIsReferenceType,
764  unsigned IndirectionLevel) {
765 
766  PathDiagnosticLocation L =
767  PathDiagnosticLocation::create(N->getLocation(), SM);
768 
769  // For now this shouldn't trigger, but once it does (as we add more
770  // functions to the body farm), we'll need to decide if these reports
771  // are worth suppressing as well.
772  if (!L.hasValidLocation())
773  return nullptr;
774 
775  SmallString<256> sbuf;
776  llvm::raw_svector_ostream os(sbuf);
777  os << "Returning without writing to '";
778 
779  // Do not generate the note if failed to pretty-print.
780  if (!prettyPrintRegionName(FieldChain, MatchedRegion, FirstElement,
781  FirstIsReferenceType, IndirectionLevel, os))
782  return nullptr;
783 
784  os << "'";
787  return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
788 }
789 
790 bool NoStoreFuncVisitor::prettyPrintRegionName(const RegionVector &FieldChain,
791  const MemRegion *MatchedRegion,
792  StringRef FirstElement,
793  bool FirstIsReferenceType,
794  unsigned IndirectionLevel,
795  llvm::raw_svector_ostream &os) {
796 
797  if (FirstIsReferenceType)
798  IndirectionLevel--;
799 
800  RegionVector RegionSequence;
801 
802  // Add the regions in the reverse order, then reverse the resulting array.
803  assert(RegionOfInterest->isSubRegionOf(MatchedRegion));
804  const MemRegion *R = RegionOfInterest;
805  while (R != MatchedRegion) {
806  RegionSequence.push_back(R);
807  R = cast<SubRegion>(R)->getSuperRegion();
808  }
809  std::reverse(RegionSequence.begin(), RegionSequence.end());
810  RegionSequence.append(FieldChain.begin(), FieldChain.end());
811 
812  StringRef Sep;
813  for (const MemRegion *R : RegionSequence) {
814 
815  // Just keep going up to the base region.
816  // Element regions may appear due to casts.
817  if (isa<CXXBaseObjectRegion, CXXTempObjectRegion>(R))
818  continue;
819 
820  if (Sep.empty())
821  Sep = prettyPrintFirstElement(FirstElement,
822  /*MoreItemsExpected=*/true,
823  IndirectionLevel, os);
824 
825  os << Sep;
826 
827  // Can only reasonably pretty-print DeclRegions.
828  if (!isa<DeclRegion>(R))
829  return false;
830 
831  const auto *DR = cast<DeclRegion>(R);
832  Sep = DR->getValueType()->isAnyPointerType() ? "->" : ".";
833  DR->getDecl()->getDeclName().print(os, PP);
834  }
835 
836  if (Sep.empty())
837  prettyPrintFirstElement(FirstElement,
838  /*MoreItemsExpected=*/false, IndirectionLevel, os);
839  return true;
840 }
841 
842 StringRef NoStoreFuncVisitor::prettyPrintFirstElement(
843  StringRef FirstElement, bool MoreItemsExpected, int IndirectionLevel,
844  llvm::raw_svector_ostream &os) {
845  StringRef Out = ".";
846 
847  if (IndirectionLevel > 0 && MoreItemsExpected) {
848  IndirectionLevel--;
849  Out = "->";
850  }
851 
852  if (IndirectionLevel > 0 && MoreItemsExpected)
853  os << "(";
854 
855  for (int i = 0; i < IndirectionLevel; i++)
856  os << "*";
857  os << FirstElement;
858 
859  if (IndirectionLevel > 0 && MoreItemsExpected)
860  os << ")";
861 
862  return Out;
863 }
864 
865 //===----------------------------------------------------------------------===//
866 // Implementation of MacroNullReturnSuppressionVisitor.
867 //===----------------------------------------------------------------------===//
868 
869 namespace {
870 
871 /// Suppress null-pointer-dereference bugs where dereferenced null was returned
872 /// the macro.
873 class MacroNullReturnSuppressionVisitor final : public BugReporterVisitor {
874  const SubRegion *RegionOfInterest;
875  const SVal ValueAtDereference;
876 
877  // Do not invalidate the reports where the value was modified
878  // after it got assigned to from the macro.
879  bool WasModified = false;
880 
881 public:
882  MacroNullReturnSuppressionVisitor(const SubRegion *R, const SVal V)
883  : RegionOfInterest(R), ValueAtDereference(V) {}
884 
885  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
886  BugReporterContext &BRC,
887  PathSensitiveBugReport &BR) override {
888  if (WasModified)
889  return nullptr;
890 
891  auto BugPoint = BR.getErrorNode()->getLocation().getAs<StmtPoint>();
892  if (!BugPoint)
893  return nullptr;
894 
895  const SourceManager &SMgr = BRC.getSourceManager();
896  if (auto Loc = matchAssignment(N)) {
897  if (isFunctionMacroExpansion(*Loc, SMgr)) {
898  std::string MacroName = std::string(getMacroName(*Loc, BRC));
899  SourceLocation BugLoc = BugPoint->getStmt()->getBeginLoc();
900  if (!BugLoc.isMacroID() || getMacroName(BugLoc, BRC) != MacroName)
901  BR.markInvalid(getTag(), MacroName.c_str());
902  }
903  }
904 
905  if (wasRegionOfInterestModifiedAt(RegionOfInterest, N, ValueAtDereference))
906  WasModified = true;
907 
908  return nullptr;
909  }
910 
911  static void addMacroVisitorIfNecessary(
912  const ExplodedNode *N, const MemRegion *R,
913  bool EnableNullFPSuppression, PathSensitiveBugReport &BR,
914  const SVal V) {
915  AnalyzerOptions &Options = N->getState()->getAnalysisManager().options;
916  if (EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths &&
917  isa<Loc>(V))
918  BR.addVisitor<MacroNullReturnSuppressionVisitor>(R->getAs<SubRegion>(),
919  V);
920  }
921 
922  void* getTag() const {
923  static int Tag = 0;
924  return static_cast<void *>(&Tag);
925  }
926 
927  void Profile(llvm::FoldingSetNodeID &ID) const override {
928  ID.AddPointer(getTag());
929  }
930 
931 private:
932  /// \return Source location of right hand side of an assignment
933  /// into \c RegionOfInterest, empty optional if none found.
934  Optional<SourceLocation> matchAssignment(const ExplodedNode *N) {
935  const Stmt *S = N->getStmtForDiagnostics();
936  ProgramStateRef State = N->getState();
937  auto *LCtx = N->getLocationContext();
938  if (!S)
939  return None;
940 
941  if (const auto *DS = dyn_cast<DeclStmt>(S)) {
942  if (const auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl()))
943  if (const Expr *RHS = VD->getInit())
944  if (RegionOfInterest->isSubRegionOf(
945  State->getLValue(VD, LCtx).getAsRegion()))
946  return RHS->getBeginLoc();
947  } else if (const auto *BO = dyn_cast<BinaryOperator>(S)) {
948  const MemRegion *R = N->getSVal(BO->getLHS()).getAsRegion();
949  const Expr *RHS = BO->getRHS();
950  if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(R)) {
951  return RHS->getBeginLoc();
952  }
953  }
954  return None;
955  }
956 };
957 
958 } // end of anonymous namespace
959 
960 namespace {
961 
962 /// Emits an extra note at the return statement of an interesting stack frame.
963 ///
964 /// The returned value is marked as an interesting value, and if it's null,
965 /// adds a visitor to track where it became null.
966 ///
967 /// This visitor is intended to be used when another visitor discovers that an
968 /// interesting value comes from an inlined function call.
969 class ReturnVisitor : public TrackingBugReporterVisitor {
970  const StackFrameContext *CalleeSFC;
971  enum {
972  Initial,
973  MaybeUnsuppress,
974  Satisfied
975  } Mode = Initial;
976 
977  bool EnableNullFPSuppression;
978  bool ShouldInvalidate = true;
979  AnalyzerOptions& Options;
981 
982 public:
983  ReturnVisitor(TrackerRef ParentTracker, const StackFrameContext *Frame,
984  bool Suppressed, AnalyzerOptions &Options,
986  : TrackingBugReporterVisitor(ParentTracker), CalleeSFC(Frame),
987  EnableNullFPSuppression(Suppressed), Options(Options), TKind(TKind) {}
988 
989  static void *getTag() {
990  static int Tag = 0;
991  return static_cast<void *>(&Tag);
992  }
993 
994  void Profile(llvm::FoldingSetNodeID &ID) const override {
995  ID.AddPointer(ReturnVisitor::getTag());
996  ID.AddPointer(CalleeSFC);
997  ID.AddBoolean(EnableNullFPSuppression);
998  }
999 
1000  PathDiagnosticPieceRef visitNodeInitial(const ExplodedNode *N,
1001  BugReporterContext &BRC,
1002  PathSensitiveBugReport &BR) {
1003  // Only print a message at the interesting return statement.
1004  if (N->getLocationContext() != CalleeSFC)
1005  return nullptr;
1006 
1007  Optional<StmtPoint> SP = N->getLocationAs<StmtPoint>();
1008  if (!SP)
1009  return nullptr;
1010 
1011  const auto *Ret = dyn_cast<ReturnStmt>(SP->getStmt());
1012  if (!Ret)
1013  return nullptr;
1014 
1015  // Okay, we're at the right return statement, but do we have the return
1016  // value available?
1017  ProgramStateRef State = N->getState();
1018  SVal V = State->getSVal(Ret, CalleeSFC);
1019  if (V.isUnknownOrUndef())
1020  return nullptr;
1021 
1022  // Don't print any more notes after this one.
1023  Mode = Satisfied;
1024 
1025  const Expr *RetE = Ret->getRetValue();
1026  assert(RetE && "Tracking a return value for a void function");
1027 
1028  // Handle cases where a reference is returned and then immediately used.
1029  Optional<Loc> LValue;
1030  if (RetE->isGLValue()) {
1031  if ((LValue = V.getAs<Loc>())) {
1032  SVal RValue = State->getRawSVal(*LValue, RetE->getType());
1033  if (isa<DefinedSVal>(RValue))
1034  V = RValue;
1035  }
1036  }
1037 
1038  // Ignore aggregate rvalues.
1039  if (isa<nonloc::LazyCompoundVal, nonloc::CompoundVal>(V))
1040  return nullptr;
1041 
1042  RetE = RetE->IgnoreParenCasts();
1043 
1044  // Let's track the return value.
1045  getParentTracker().track(RetE, N, {TKind, EnableNullFPSuppression});
1046 
1047  // Build an appropriate message based on the return value.
1048  SmallString<64> Msg;
1049  llvm::raw_svector_ostream Out(Msg);
1050 
1051  bool WouldEventBeMeaningless = false;
1052 
1053  if (State->isNull(V).isConstrainedTrue()) {
1054  if (isa<Loc>(V)) {
1055 
1056  // If we have counter-suppression enabled, make sure we keep visiting
1057  // future nodes. We want to emit a path note as well, in case
1058  // the report is resurrected as valid later on.
1059  if (EnableNullFPSuppression &&
1060  Options.ShouldAvoidSuppressingNullArgumentPaths)
1061  Mode = MaybeUnsuppress;
1062 
1063  if (RetE->getType()->isObjCObjectPointerType()) {
1064  Out << "Returning nil";
1065  } else {
1066  Out << "Returning null pointer";
1067  }
1068  } else {
1069  Out << "Returning zero";
1070  }
1071 
1072  } else {
1073  if (auto CI = V.getAs<nonloc::ConcreteInt>()) {
1074  Out << "Returning the value " << CI->getValue();
1075  } else {
1076  // There is nothing interesting about returning a value, when it is
1077  // plain value without any constraints, and the function is guaranteed
1078  // to return that every time. We could use CFG::isLinear() here, but
1079  // constexpr branches are obvious to the compiler, not necesserily to
1080  // the programmer.
1081  if (N->getCFG().size() == 3)
1082  WouldEventBeMeaningless = true;
1083 
1084  Out << (isa<Loc>(V) ? "Returning pointer" : "Returning value");
1085  }
1086  }
1087 
1088  if (LValue) {
1089  if (const MemRegion *MR = LValue->getAsRegion()) {
1090  if (MR->canPrintPretty()) {
1091  Out << " (reference to ";
1092  MR->printPretty(Out);
1093  Out << ")";
1094  }
1095  }
1096  } else {
1097  // FIXME: We should have a more generalized location printing mechanism.
1098  if (const auto *DR = dyn_cast<DeclRefExpr>(RetE))
1099  if (const auto *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
1100  Out << " (loaded from '" << *DD << "')";
1101  }
1102 
1103  PathDiagnosticLocation L(Ret, BRC.getSourceManager(), CalleeSFC);
1104  if (!L.isValid() || !L.asLocation().isValid())
1105  return nullptr;
1106 
1108  Out << WillBeUsedForACondition;
1109 
1110  auto EventPiece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
1111 
1112  // If we determined that the note is meaningless, make it prunable, and
1113  // don't mark the stackframe interesting.
1114  if (WouldEventBeMeaningless)
1115  EventPiece->setPrunable(true);
1116  else
1117  BR.markInteresting(CalleeSFC);
1118 
1119  return EventPiece;
1120  }
1121 
1122  PathDiagnosticPieceRef visitNodeMaybeUnsuppress(const ExplodedNode *N,
1123  BugReporterContext &BRC,
1124  PathSensitiveBugReport &BR) {
1125  assert(Options.ShouldAvoidSuppressingNullArgumentPaths);
1126 
1127  // Are we at the entry node for this call?
1128  Optional<CallEnter> CE = N->getLocationAs<CallEnter>();
1129  if (!CE)
1130  return nullptr;
1131 
1132  if (CE->getCalleeContext() != CalleeSFC)
1133  return nullptr;
1134 
1135  Mode = Satisfied;
1136 
1137  // Don't automatically suppress a report if one of the arguments is
1138  // known to be a null pointer. Instead, start tracking /that/ null
1139  // value back to its origin.
1140  ProgramStateManager &StateMgr = BRC.getStateManager();
1141  CallEventManager &CallMgr = StateMgr.getCallEventManager();
1142 
1143  ProgramStateRef State = N->getState();
1144  CallEventRef<> Call = CallMgr.getCaller(CalleeSFC, State);
1145  for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
1146  Optional<Loc> ArgV = Call->getArgSVal(I).getAs<Loc>();
1147  if (!ArgV)
1148  continue;
1149 
1150  const Expr *ArgE = Call->getArgExpr(I);
1151  if (!ArgE)
1152  continue;
1153 
1154  // Is it possible for this argument to be non-null?
1155  if (!State->isNull(*ArgV).isConstrainedTrue())
1156  continue;
1157 
1158  if (getParentTracker()
1159  .track(ArgE, N, {TKind, EnableNullFPSuppression})
1160  .FoundSomethingToTrack)
1161  ShouldInvalidate = false;
1162 
1163  // If we /can't/ track the null pointer, we should err on the side of
1164  // false negatives, and continue towards marking this report invalid.
1165  // (We will still look at the other arguments, though.)
1166  }
1167 
1168  return nullptr;
1169  }
1170 
1171  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
1172  BugReporterContext &BRC,
1173  PathSensitiveBugReport &BR) override {
1174  switch (Mode) {
1175  case Initial:
1176  return visitNodeInitial(N, BRC, BR);
1177  case MaybeUnsuppress:
1178  return visitNodeMaybeUnsuppress(N, BRC, BR);
1179  case Satisfied:
1180  return nullptr;
1181  }
1182 
1183  llvm_unreachable("Invalid visit mode!");
1184  }
1185 
1186  void finalizeVisitor(BugReporterContext &, const ExplodedNode *,
1187  PathSensitiveBugReport &BR) override {
1188  if (EnableNullFPSuppression && ShouldInvalidate)
1189  BR.markInvalid(ReturnVisitor::getTag(), CalleeSFC);
1190  }
1191 };
1192 
1193 } // end of anonymous namespace
1194 
1195 //===----------------------------------------------------------------------===//
1196 // StoreSiteFinder
1197 //===----------------------------------------------------------------------===//
1198 
1199 /// Finds last store into the given region,
1200 /// which is different from a given symbolic value.
1202  const MemRegion *R;
1203  SVal V;
1204  bool Satisfied = false;
1205 
1206  TrackingOptions Options;
1207  const StackFrameContext *OriginSFC;
1208 
1209 public:
1210  /// \param V We're searching for the store where \c R received this value.
1211  /// \param R The region we're tracking.
1212  /// \param Options Tracking behavior options.
1213  /// \param OriginSFC Only adds notes when the last store happened in a
1214  /// different stackframe to this one. Disregarded if the tracking kind
1215  /// is thorough.
1216  /// This is useful, because for non-tracked regions, notes about
1217  /// changes to its value in a nested stackframe could be pruned, and
1218  /// this visitor can prevent that without polluting the bugpath too
1219  /// much.
1220  StoreSiteFinder(bugreporter::TrackerRef ParentTracker, KnownSVal V,
1221  const MemRegion *R, TrackingOptions Options,
1222  const StackFrameContext *OriginSFC = nullptr)
1223  : TrackingBugReporterVisitor(ParentTracker), R(R), V(V), Options(Options),
1224  OriginSFC(OriginSFC) {
1225  assert(R);
1226  }
1227 
1228  void Profile(llvm::FoldingSetNodeID &ID) const override;
1229 
1230  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
1231  BugReporterContext &BRC,
1232  PathSensitiveBugReport &BR) override;
1233 };
1234 
1235 void StoreSiteFinder::Profile(llvm::FoldingSetNodeID &ID) const {
1236  static int tag = 0;
1237  ID.AddPointer(&tag);
1238  ID.AddPointer(R);
1239  ID.Add(V);
1240  ID.AddInteger(static_cast<int>(Options.Kind));
1241  ID.AddBoolean(Options.EnableNullFPSuppression);
1242 }
1243 
1244 /// Returns true if \p N represents the DeclStmt declaring and initializing
1245 /// \p VR.
1246 static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR) {
1247  Optional<PostStmt> P = N->getLocationAs<PostStmt>();
1248  if (!P)
1249  return false;
1250 
1251  const DeclStmt *DS = P->getStmtAs<DeclStmt>();
1252  if (!DS)
1253  return false;
1254 
1255  if (DS->getSingleDecl() != VR->getDecl())
1256  return false;
1257 
1258  const MemSpaceRegion *VarSpace = VR->getMemorySpace();
1259  const auto *FrameSpace = dyn_cast<StackSpaceRegion>(VarSpace);
1260  if (!FrameSpace) {
1261  // If we ever directly evaluate global DeclStmts, this assertion will be
1262  // invalid, but this still seems preferable to silently accepting an
1263  // initialization that may be for a path-sensitive variable.
1264  assert(VR->getDecl()->isStaticLocal() && "non-static stackless VarRegion");
1265  return true;
1266  }
1267 
1268  assert(VR->getDecl()->hasLocalStorage());
1269  const LocationContext *LCtx = N->getLocationContext();
1270  return FrameSpace->getStackFrame() == LCtx->getStackFrame();
1271 }
1272 
1273 static bool isObjCPointer(const MemRegion *R) {
1274  if (R->isBoundable())
1275  if (const auto *TR = dyn_cast<TypedValueRegion>(R))
1276  return TR->getValueType()->isObjCObjectPointerType();
1277 
1278  return false;
1279 }
1280 
1281 static bool isObjCPointer(const ValueDecl *D) {
1282  return D->getType()->isObjCObjectPointerType();
1283 }
1284 
1285 /// Show diagnostics for initializing or declaring a region \p R with a bad value.
1286 static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI) {
1287  const bool HasPrefix = SI.Dest->canPrintPretty();
1288 
1289  if (HasPrefix) {
1290  SI.Dest->printPretty(OS);
1291  OS << " ";
1292  }
1293 
1294  const char *Action = nullptr;
1295 
1296  switch (SI.StoreKind) {
1298  Action = HasPrefix ? "initialized to " : "Initializing to ";
1299  break;
1301  Action = HasPrefix ? "captured by block as " : "Captured by block as ";
1302  break;
1303  default:
1304  llvm_unreachable("Unexpected store kind");
1305  }
1306 
1307  if (isa<loc::ConcreteInt>(SI.Value)) {
1308  OS << Action << (isObjCPointer(SI.Dest) ? "nil" : "a null pointer value");
1309 
1310  } else if (auto CVal = SI.Value.getAs<nonloc::ConcreteInt>()) {
1311  OS << Action << CVal->getValue();
1312 
1313  } else if (SI.Origin && SI.Origin->canPrintPretty()) {
1314  OS << Action << "the value of ";
1315  SI.Origin->printPretty(OS);
1316 
1317  } else if (SI.StoreKind == StoreInfo::Initialization) {
1318  // We don't need to check here, all these conditions were
1319  // checked by StoreSiteFinder, when it figured out that it is
1320  // initialization.
1321  const auto *DS =
1322  cast<DeclStmt>(SI.StoreSite->getLocationAs<PostStmt>()->getStmt());
1323 
1324  if (SI.Value.isUndef()) {
1325  if (isa<VarRegion>(SI.Dest)) {
1326  const auto *VD = cast<VarDecl>(DS->getSingleDecl());
1327 
1328  if (VD->getInit()) {
1329  OS << (HasPrefix ? "initialized" : "Initializing")
1330  << " to a garbage value";
1331  } else {
1332  OS << (HasPrefix ? "declared" : "Declaring")
1333  << " without an initial value";
1334  }
1335  }
1336  } else {
1337  OS << (HasPrefix ? "initialized" : "Initialized") << " here";
1338  }
1339  }
1340 }
1341 
1342 /// Display diagnostics for passing bad region as a parameter.
1343 static void showBRParamDiagnostics(llvm::raw_svector_ostream &OS,
1344  StoreInfo SI) {
1345  const auto *VR = cast<VarRegion>(SI.Dest);
1346  const auto *Param = cast<ParmVarDecl>(VR->getDecl());
1347 
1348  OS << "Passing ";
1349 
1350  if (isa<loc::ConcreteInt>(SI.Value)) {
1351  OS << (isObjCPointer(Param) ? "nil object reference"
1352  : "null pointer value");
1353 
1354  } else if (SI.Value.isUndef()) {
1355  OS << "uninitialized value";
1356 
1357  } else if (auto CI = SI.Value.getAs<nonloc::ConcreteInt>()) {
1358  OS << "the value " << CI->getValue();
1359 
1360  } else if (SI.Origin && SI.Origin->canPrintPretty()) {
1361  SI.Origin->printPretty(OS);
1362 
1363  } else {
1364  OS << "value";
1365  }
1366 
1367  // Printed parameter indexes are 1-based, not 0-based.
1368  unsigned Idx = Param->getFunctionScopeIndex() + 1;
1369  OS << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter";
1370  if (VR->canPrintPretty()) {
1371  OS << " ";
1372  VR->printPretty(OS);
1373  }
1374 }
1375 
1376 /// Show default diagnostics for storing bad region.
1377 static void showBRDefaultDiagnostics(llvm::raw_svector_ostream &OS,
1378  StoreInfo SI) {
1379  const bool HasSuffix = SI.Dest->canPrintPretty();
1380 
1381  if (isa<loc::ConcreteInt>(SI.Value)) {
1382  OS << (isObjCPointer(SI.Dest) ? "nil object reference stored"
1383  : (HasSuffix ? "Null pointer value stored"
1384  : "Storing null pointer value"));
1385 
1386  } else if (SI.Value.isUndef()) {
1387  OS << (HasSuffix ? "Uninitialized value stored"
1388  : "Storing uninitialized value");
1389 
1390  } else if (auto CV = SI.Value.getAs<nonloc::ConcreteInt>()) {
1391  if (HasSuffix)
1392  OS << "The value " << CV->getValue() << " is assigned";
1393  else
1394  OS << "Assigning " << CV->getValue();
1395 
1396  } else if (SI.Origin && SI.Origin->canPrintPretty()) {
1397  if (HasSuffix) {
1398  OS << "The value of ";
1399  SI.Origin->printPretty(OS);
1400  OS << " is assigned";
1401  } else {
1402  OS << "Assigning the value of ";
1403  SI.Origin->printPretty(OS);
1404  }
1405 
1406  } else {
1407  OS << (HasSuffix ? "Value assigned" : "Assigning value");
1408  }
1409 
1410  if (HasSuffix) {
1411  OS << " to ";
1412  SI.Dest->printPretty(OS);
1413  }
1414 }
1415 
1417  BugReporterContext &BRC,
1418  PathSensitiveBugReport &BR) {
1419  if (Satisfied)
1420  return nullptr;
1421 
1422  const ExplodedNode *StoreSite = nullptr;
1423  const ExplodedNode *Pred = Succ->getFirstPred();
1424  const Expr *InitE = nullptr;
1425  bool IsParam = false;
1426 
1427  // First see if we reached the declaration of the region.
1428  if (const auto *VR = dyn_cast<VarRegion>(R)) {
1429  if (isInitializationOfVar(Pred, VR)) {
1430  StoreSite = Pred;
1431  InitE = VR->getDecl()->getInit();
1432  }
1433  }
1434 
1435  // If this is a post initializer expression, initializing the region, we
1436  // should track the initializer expression.
1437  if (Optional<PostInitializer> PIP = Pred->getLocationAs<PostInitializer>()) {
1438  const MemRegion *FieldReg = (const MemRegion *)PIP->getLocationValue();
1439  if (FieldReg == R) {
1440  StoreSite = Pred;
1441  InitE = PIP->getInitializer()->getInit();
1442  }
1443  }
1444 
1445  // Otherwise, see if this is the store site:
1446  // (1) Succ has this binding and Pred does not, i.e. this is
1447  // where the binding first occurred.
1448  // (2) Succ has this binding and is a PostStore node for this region, i.e.
1449  // the same binding was re-assigned here.
1450  if (!StoreSite) {
1451  if (Succ->getState()->getSVal(R) != V)
1452  return nullptr;
1453 
1454  if (hasVisibleUpdate(Pred, Pred->getState()->getSVal(R), Succ, V)) {
1455  Optional<PostStore> PS = Succ->getLocationAs<PostStore>();
1456  if (!PS || PS->getLocationValue() != R)
1457  return nullptr;
1458  }
1459 
1460  StoreSite = Succ;
1461 
1462  // If this is an assignment expression, we can track the value
1463  // being assigned.
1464  if (Optional<PostStmt> P = Succ->getLocationAs<PostStmt>())
1465  if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>())
1466  if (BO->isAssignmentOp())
1467  InitE = BO->getRHS();
1468 
1469  // If this is a call entry, the variable should be a parameter.
1470  // FIXME: Handle CXXThisRegion as well. (This is not a priority because
1471  // 'this' should never be NULL, but this visitor isn't just for NULL and
1472  // UndefinedVal.)
1473  if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
1474  if (const auto *VR = dyn_cast<VarRegion>(R)) {
1475 
1476  if (const auto *Param = dyn_cast<ParmVarDecl>(VR->getDecl())) {
1477  ProgramStateManager &StateMgr = BRC.getStateManager();
1478  CallEventManager &CallMgr = StateMgr.getCallEventManager();
1479 
1480  CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
1481  Succ->getState());
1482  InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
1483  } else {
1484  // Handle Objective-C 'self'.
1485  assert(isa<ImplicitParamDecl>(VR->getDecl()));
1486  InitE = cast<ObjCMessageExpr>(CE->getCalleeContext()->getCallSite())
1487  ->getInstanceReceiver()->IgnoreParenCasts();
1488  }
1489  IsParam = true;
1490  }
1491  }
1492 
1493  // If this is a CXXTempObjectRegion, the Expr responsible for its creation
1494  // is wrapped inside of it.
1495  if (const auto *TmpR = dyn_cast<CXXTempObjectRegion>(R))
1496  InitE = TmpR->getExpr();
1497  }
1498 
1499  if (!StoreSite)
1500  return nullptr;
1501 
1502  Satisfied = true;
1503 
1504  // If we have an expression that provided the value, try to track where it
1505  // came from.
1506  if (InitE) {
1507  if (!IsParam)
1508  InitE = InitE->IgnoreParenCasts();
1509 
1510  getParentTracker().track(InitE, StoreSite, Options);
1511  }
1512 
1513  // Let's try to find the region where the value came from.
1514  const MemRegion *OldRegion = nullptr;
1515 
1516  // If we have init expression, it might be simply a reference
1517  // to a variable, so we can use it.
1518  if (InitE) {
1519  // That region might still be not exactly what we are looking for.
1520  // In situations like `int &ref = val;`, we can't say that
1521  // `ref` is initialized with `val`, rather refers to `val`.
1522  //
1523  // In order, to mitigate situations like this, we check if the last
1524  // stored value in that region is the value that we track.
1525  //
1526  // TODO: support other situations better.
1527  if (const MemRegion *Candidate =
1528  getLocationRegionIfReference(InitE, Succ, false)) {
1529  const StoreManager &SM = BRC.getStateManager().getStoreManager();
1530 
1531  // Here we traverse the graph up to find the last node where the
1532  // candidate region is still in the store.
1533  for (const ExplodedNode *N = StoreSite; N; N = N->getFirstPred()) {
1534  if (SM.includedInBindings(N->getState()->getStore(), Candidate)) {
1535  // And if it was bound to the target value, we can use it.
1536  if (N->getState()->getSVal(Candidate) == V) {
1537  OldRegion = Candidate;
1538  }
1539  break;
1540  }
1541  }
1542  }
1543  }
1544 
1545  // Otherwise, if the current region does indeed contain the value
1546  // we are looking for, we can look for a region where this value
1547  // was before.
1548  //
1549  // It can be useful for situations like:
1550  // new = identity(old)
1551  // where the analyzer knows that 'identity' returns the value of its
1552  // first argument.
1553  //
1554  // NOTE: If the region R is not a simple var region, it can contain
1555  // V in one of its subregions.
1556  if (!OldRegion && StoreSite->getState()->getSVal(R) == V) {
1557  // Let's go up the graph to find the node where the region is
1558  // bound to V.
1559  const ExplodedNode *NodeWithoutBinding = StoreSite->getFirstPred();
1560  for (;
1561  NodeWithoutBinding && NodeWithoutBinding->getState()->getSVal(R) == V;
1562  NodeWithoutBinding = NodeWithoutBinding->getFirstPred()) {
1563  }
1564 
1565  if (NodeWithoutBinding) {
1566  // Let's try to find a unique binding for the value in that node.
1567  // We want to use this to find unique bindings because of the following
1568  // situations:
1569  // b = a;
1570  // c = identity(b);
1571  //
1572  // Telling the user that the value of 'a' is assigned to 'c', while
1573  // correct, can be confusing.
1574  StoreManager::FindUniqueBinding FB(V.getAsLocSymbol());
1575  BRC.getStateManager().iterBindings(NodeWithoutBinding->getState(), FB);
1576  if (FB)
1577  OldRegion = FB.getRegion();
1578  }
1579  }
1580 
1581  if (Options.Kind == TrackingKind::Condition && OriginSFC &&
1582  !OriginSFC->isParentOf(StoreSite->getStackFrame()))
1583  return nullptr;
1584 
1585  // Okay, we've found the binding. Emit an appropriate message.
1586  SmallString<256> sbuf;
1587  llvm::raw_svector_ostream os(sbuf);
1588 
1589  StoreInfo SI = {StoreInfo::Assignment, // default kind
1590  StoreSite,
1591  InitE,
1592  V,
1593  R,
1594  OldRegion};
1595 
1596  if (Optional<PostStmt> PS = StoreSite->getLocationAs<PostStmt>()) {
1597  const Stmt *S = PS->getStmt();
1598  const auto *DS = dyn_cast<DeclStmt>(S);
1599  const auto *VR = dyn_cast<VarRegion>(R);
1600 
1601  if (DS) {
1602  SI.StoreKind = StoreInfo::Initialization;
1603  } else if (isa<BlockExpr>(S)) {
1604  SI.StoreKind = StoreInfo::BlockCapture;
1605  if (VR) {
1606  // See if we can get the BlockVarRegion.
1607  ProgramStateRef State = StoreSite->getState();
1608  SVal V = StoreSite->getSVal(S);
1609  if (const auto *BDR =
1610  dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
1611  if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
1612  getParentTracker().track(State->getSVal(OriginalR), OriginalR,
1613  Options, OriginSFC);
1614  }
1615  }
1616  }
1617  }
1618  } else if (SI.StoreSite->getLocation().getAs<CallEnter>() &&
1619  isa<VarRegion>(SI.Dest)) {
1620  SI.StoreKind = StoreInfo::CallArgument;
1621  }
1622 
1623  return getParentTracker().handle(SI, BRC, Options);
1624 }
1625 
1626 //===----------------------------------------------------------------------===//
1627 // Implementation of TrackConstraintBRVisitor.
1628 //===----------------------------------------------------------------------===//
1629 
1630 void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
1631  static int tag = 0;
1632  ID.AddPointer(&tag);
1633  ID.AddBoolean(Assumption);
1634  ID.Add(Constraint);
1635 }
1636 
1637 /// Return the tag associated with this visitor. This tag will be used
1638 /// to make all PathDiagnosticPieces created by this visitor.
1640  return "TrackConstraintBRVisitor";
1641 }
1642 
1643 bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const {
1644  if (IsZeroCheck)
1645  return N->getState()->isNull(Constraint).isUnderconstrained();
1646  return (bool)N->getState()->assume(Constraint, !Assumption);
1647 }
1648 
1651  const ExplodedNode *PrevN = N->getFirstPred();
1652  if (IsSatisfied)
1653  return nullptr;
1654 
1655  // Start tracking after we see the first state in which the value is
1656  // constrained.
1657  if (!IsTrackingTurnedOn)
1658  if (!isUnderconstrained(N))
1659  IsTrackingTurnedOn = true;
1660  if (!IsTrackingTurnedOn)
1661  return nullptr;
1662 
1663  // Check if in the previous state it was feasible for this constraint
1664  // to *not* be true.
1665  if (isUnderconstrained(PrevN)) {
1666  IsSatisfied = true;
1667 
1668  // At this point, the negation of the constraint should be infeasible. If it
1669  // is feasible, make sure that the negation of the constrainti was
1670  // infeasible in the current state. If it is feasible, we somehow missed
1671  // the transition point.
1672  assert(!isUnderconstrained(N));
1673 
1674  // We found the transition point for the constraint. We now need to
1675  // pretty-print the constraint. (work-in-progress)
1676  SmallString<64> sbuf;
1677  llvm::raw_svector_ostream os(sbuf);
1678 
1679  if (isa<Loc>(Constraint)) {
1680  os << "Assuming pointer value is ";
1681  os << (Assumption ? "non-null" : "null");
1682  }
1683 
1684  if (os.str().empty())
1685  return nullptr;
1686 
1687  // Construct a new PathDiagnosticPiece.
1688  ProgramPoint P = N->getLocation();
1689 
1690  // If this node already have a specialized note, it's probably better
1691  // than our generic note.
1692  // FIXME: This only looks for note tags, not for other ways to add a note.
1693  if (isa_and_nonnull<NoteTag>(P.getTag()))
1694  return nullptr;
1695 
1698  if (!L.isValid())
1699  return nullptr;
1700 
1701  auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
1702  X->setTag(getTag());
1703  return std::move(X);
1704  }
1705 
1706  return nullptr;
1707 }
1708 
1709 //===----------------------------------------------------------------------===//
1710 // Implementation of SuppressInlineDefensiveChecksVisitor.
1711 //===----------------------------------------------------------------------===//
1712 
1715  : V(Value) {
1716  // Check if the visitor is disabled.
1717  AnalyzerOptions &Options = N->getState()->getAnalysisManager().options;
1718  if (!Options.ShouldSuppressInlinedDefensiveChecks)
1719  IsSatisfied = true;
1720 }
1721 
1723  llvm::FoldingSetNodeID &ID) const {
1724  static int id = 0;
1725  ID.AddPointer(&id);
1726  ID.Add(V);
1727 }
1728 
1730  return "IDCVisitor";
1731 }
1732 
1735  BugReporterContext &BRC,
1736  PathSensitiveBugReport &BR) {
1737  const ExplodedNode *Pred = Succ->getFirstPred();
1738  if (IsSatisfied)
1739  return nullptr;
1740 
1741  // Start tracking after we see the first state in which the value is null.
1742  if (!IsTrackingTurnedOn)
1743  if (Succ->getState()->isNull(V).isConstrainedTrue())
1744  IsTrackingTurnedOn = true;
1745  if (!IsTrackingTurnedOn)
1746  return nullptr;
1747 
1748  // Check if in the previous state it was feasible for this value
1749  // to *not* be null.
1750  if (!Pred->getState()->isNull(V).isConstrainedTrue() &&
1751  Succ->getState()->isNull(V).isConstrainedTrue()) {
1752  IsSatisfied = true;
1753 
1754  // Check if this is inlined defensive checks.
1755  const LocationContext *CurLC = Succ->getLocationContext();
1756  const LocationContext *ReportLC = BR.getErrorNode()->getLocationContext();
1757  if (CurLC != ReportLC && !CurLC->isParentOf(ReportLC)) {
1758  BR.markInvalid("Suppress IDC", CurLC);
1759  return nullptr;
1760  }
1761 
1762  // Treat defensive checks in function-like macros as if they were an inlined
1763  // defensive check. If the bug location is not in a macro and the
1764  // terminator for the current location is in a macro then suppress the
1765  // warning.
1766  auto BugPoint = BR.getErrorNode()->getLocation().getAs<StmtPoint>();
1767 
1768  if (!BugPoint)
1769  return nullptr;
1770 
1771  ProgramPoint CurPoint = Succ->getLocation();
1772  const Stmt *CurTerminatorStmt = nullptr;
1773  if (auto BE = CurPoint.getAs<BlockEdge>()) {
1774  CurTerminatorStmt = BE->getSrc()->getTerminator().getStmt();
1775  } else if (auto SP = CurPoint.getAs<StmtPoint>()) {
1776  const Stmt *CurStmt = SP->getStmt();
1777  if (!CurStmt->getBeginLoc().isMacroID())
1778  return nullptr;
1779 
1780  CFGStmtMap *Map = CurLC->getAnalysisDeclContext()->getCFGStmtMap();
1781  CurTerminatorStmt = Map->getBlock(CurStmt)->getTerminatorStmt();
1782  } else {
1783  return nullptr;
1784  }
1785 
1786  if (!CurTerminatorStmt)
1787  return nullptr;
1788 
1789  SourceLocation TerminatorLoc = CurTerminatorStmt->getBeginLoc();
1790  if (TerminatorLoc.isMacroID()) {
1791  SourceLocation BugLoc = BugPoint->getStmt()->getBeginLoc();
1792 
1793  // Suppress reports unless we are in that same macro.
1794  if (!BugLoc.isMacroID() ||
1795  getMacroName(BugLoc, BRC) != getMacroName(TerminatorLoc, BRC)) {
1796  BR.markInvalid("Suppress Macro IDC", CurLC);
1797  }
1798  return nullptr;
1799  }
1800  }
1801  return nullptr;
1802 }
1803 
1804 //===----------------------------------------------------------------------===//
1805 // TrackControlDependencyCondBRVisitor.
1806 //===----------------------------------------------------------------------===//
1807 
1808 namespace {
1809 /// Tracks the expressions that are a control dependency of the node that was
1810 /// supplied to the constructor.
1811 /// For example:
1812 ///
1813 /// cond = 1;
1814 /// if (cond)
1815 /// 10 / 0;
1816 ///
1817 /// An error is emitted at line 3. This visitor realizes that the branch
1818 /// on line 2 is a control dependency of line 3, and tracks it's condition via
1819 /// trackExpressionValue().
1820 class TrackControlDependencyCondBRVisitor final
1821  : public TrackingBugReporterVisitor {
1822  const ExplodedNode *Origin;
1823  ControlDependencyCalculator ControlDeps;
1824  llvm::SmallSet<const CFGBlock *, 32> VisitedBlocks;
1825 
1826 public:
1827  TrackControlDependencyCondBRVisitor(TrackerRef ParentTracker,
1828  const ExplodedNode *O)
1829  : TrackingBugReporterVisitor(ParentTracker), Origin(O),
1830  ControlDeps(&O->getCFG()) {}
1831 
1832  void Profile(llvm::FoldingSetNodeID &ID) const override {
1833  static int x = 0;
1834  ID.AddPointer(&x);
1835  }
1836 
1837  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
1838  BugReporterContext &BRC,
1839  PathSensitiveBugReport &BR) override;
1840 };
1841 } // end of anonymous namespace
1842 
1843 static std::shared_ptr<PathDiagnosticEventPiece>
1845  const ExplodedNode *N,
1846  BugReporterContext &BRC) {
1847 
1848  if (BRC.getAnalyzerOptions().AnalysisDiagOpt == PD_NONE ||
1849  !BRC.getAnalyzerOptions().ShouldTrackConditionsDebug)
1850  return nullptr;
1851 
1854  BRC.getSourceManager(), BRC.getASTContext().getLangOpts()));
1855 
1856  return std::make_shared<PathDiagnosticEventPiece>(
1858  Cond, BRC.getSourceManager(), N->getLocationContext()),
1859  (Twine() + "Tracking condition '" + ConditionText + "'").str());
1860 }
1861 
1862 static bool isAssertlikeBlock(const CFGBlock *B, ASTContext &Context) {
1863  if (B->succ_size() != 2)
1864  return false;
1865 
1866  const CFGBlock *Then = B->succ_begin()->getReachableBlock();
1867  const CFGBlock *Else = (B->succ_begin() + 1)->getReachableBlock();
1868 
1869  if (!Then || !Else)
1870  return false;
1871 
1872  if (Then->isInevitablySinking() != Else->isInevitablySinking())
1873  return true;
1874 
1875  // For the following condition the following CFG would be built:
1876  //
1877  // ------------->
1878  // / \
1879  // [B1] -> [B2] -> [B3] -> [sink]
1880  // assert(A && B || C); \ \
1881  // -----------> [go on with the execution]
1882  //
1883  // It so happens that CFGBlock::getTerminatorCondition returns 'A' for block
1884  // B1, 'A && B' for B2, and 'A && B || C' for B3. Let's check whether we
1885  // reached the end of the condition!
1886  if (const Stmt *ElseCond = Else->getTerminatorCondition())
1887  if (const auto *BinOp = dyn_cast<BinaryOperator>(ElseCond))
1888  if (BinOp->isLogicalOp())
1889  return isAssertlikeBlock(Else, Context);
1890 
1891  return false;
1892 }
1893 
1895 TrackControlDependencyCondBRVisitor::VisitNode(const ExplodedNode *N,
1896  BugReporterContext &BRC,
1897  PathSensitiveBugReport &BR) {
1898  // We can only reason about control dependencies within the same stack frame.
1899  if (Origin->getStackFrame() != N->getStackFrame())
1900  return nullptr;
1901 
1902  CFGBlock *NB = const_cast<CFGBlock *>(N->getCFGBlock());
1903 
1904  // Skip if we already inspected this block.
1905  if (!VisitedBlocks.insert(NB).second)
1906  return nullptr;
1907 
1908  CFGBlock *OriginB = const_cast<CFGBlock *>(Origin->getCFGBlock());
1909 
1910  // TODO: Cache CFGBlocks for each ExplodedNode.
1911  if (!OriginB || !NB)
1912  return nullptr;
1913 
1914  if (isAssertlikeBlock(NB, BRC.getASTContext()))
1915  return nullptr;
1916 
1917  if (ControlDeps.isControlDependent(OriginB, NB)) {
1918  // We don't really want to explain for range loops. Evidence suggests that
1919  // the only thing that leads to is the addition of calls to operator!=.
1920  if (llvm::isa_and_nonnull<CXXForRangeStmt>(NB->getTerminatorStmt()))
1921  return nullptr;
1922 
1923  if (const Expr *Condition = NB->getLastCondition()) {
1924 
1925  // If we can't retrieve a sensible condition, just bail out.
1926  const Expr *InnerExpr = peelOffOuterExpr(Condition, N);
1927  if (!InnerExpr)
1928  return nullptr;
1929 
1930  // If the condition was a function call, we likely won't gain much from
1931  // tracking it either. Evidence suggests that it will mostly trigger in
1932  // scenarios like this:
1933  //
1934  // void f(int *x) {
1935  // x = nullptr;
1936  // if (alwaysTrue()) // We don't need a whole lot of explanation
1937  // // here, the function name is good enough.
1938  // *x = 5;
1939  // }
1940  //
1941  // Its easy to create a counterexample where this heuristic would make us
1942  // lose valuable information, but we've never really seen one in practice.
1943  if (isa<CallExpr>(InnerExpr))
1944  return nullptr;
1945 
1946  // Keeping track of the already tracked conditions on a visitor level
1947  // isn't sufficient, because a new visitor is created for each tracked
1948  // expression, hence the BugReport level set.
1949  if (BR.addTrackedCondition(N)) {
1950  getParentTracker().track(InnerExpr, N,
1952  /*EnableNullFPSuppression=*/false});
1953  return constructDebugPieceForTrackedCondition(Condition, N, BRC);
1954  }
1955  }
1956  }
1957 
1958  return nullptr;
1959 }
1960 
1961 //===----------------------------------------------------------------------===//
1962 // Implementation of trackExpressionValue.
1963 //===----------------------------------------------------------------------===//
1964 
1965 static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N) {
1966 
1967  Ex = Ex->IgnoreParenCasts();
1968  if (const auto *FE = dyn_cast<FullExpr>(Ex))
1969  return peelOffOuterExpr(FE->getSubExpr(), N);
1970  if (const auto *OVE = dyn_cast<OpaqueValueExpr>(Ex))
1971  return peelOffOuterExpr(OVE->getSourceExpr(), N);
1972  if (const auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
1973  const auto *PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
1974  if (PropRef && PropRef->isMessagingGetter()) {
1975  const Expr *GetterMessageSend =
1976  POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);
1977  assert(isa<ObjCMessageExpr>(GetterMessageSend->IgnoreParenCasts()));
1978  return peelOffOuterExpr(GetterMessageSend, N);
1979  }
1980  }
1981 
1982  // Peel off the ternary operator.
1983  if (const auto *CO = dyn_cast<ConditionalOperator>(Ex)) {
1984  // Find a node where the branching occurred and find out which branch
1985  // we took (true/false) by looking at the ExplodedGraph.
1986  const ExplodedNode *NI = N;
1987  do {
1988  ProgramPoint ProgPoint = NI->getLocation();
1989  if (Optional<BlockEdge> BE = ProgPoint.getAs<BlockEdge>()) {
1990  const CFGBlock *srcBlk = BE->getSrc();
1991  if (const Stmt *term = srcBlk->getTerminatorStmt()) {
1992  if (term == CO) {
1993  bool TookTrueBranch = (*(srcBlk->succ_begin()) == BE->getDst());
1994  if (TookTrueBranch)
1995  return peelOffOuterExpr(CO->getTrueExpr(), N);
1996  else
1997  return peelOffOuterExpr(CO->getFalseExpr(), N);
1998  }
1999  }
2000  }
2001  NI = NI->getFirstPred();
2002  } while (NI);
2003  }
2004 
2005  if (auto *BO = dyn_cast<BinaryOperator>(Ex))
2006  if (const Expr *SubEx = peelOffPointerArithmetic(BO))
2007  return peelOffOuterExpr(SubEx, N);
2008 
2009  if (auto *UO = dyn_cast<UnaryOperator>(Ex)) {
2010  if (UO->getOpcode() == UO_LNot)
2011  return peelOffOuterExpr(UO->getSubExpr(), N);
2012 
2013  // FIXME: There's a hack in our Store implementation that always computes
2014  // field offsets around null pointers as if they are always equal to 0.
2015  // The idea here is to report accesses to fields as null dereferences
2016  // even though the pointer value that's being dereferenced is actually
2017  // the offset of the field rather than exactly 0.
2018  // See the FIXME in StoreManager's getLValueFieldOrIvar() method.
2019  // This code interacts heavily with this hack; otherwise the value
2020  // would not be null at all for most fields, so we'd be unable to track it.
2021  if (UO->getOpcode() == UO_AddrOf && UO->getSubExpr()->isLValue())
2022  if (const Expr *DerefEx = bugreporter::getDerefExpr(UO->getSubExpr()))
2023  return peelOffOuterExpr(DerefEx, N);
2024  }
2025 
2026  return Ex;
2027 }
2028 
2029 /// Find the ExplodedNode where the lvalue (the value of 'Ex')
2030 /// was computed.
2031 static const ExplodedNode* findNodeForExpression(const ExplodedNode *N,
2032  const Expr *Inner) {
2033  while (N) {
2034  if (N->getStmtForDiagnostics() == Inner)
2035  return N;
2036  N = N->getFirstPred();
2037  }
2038  return N;
2039 }
2040 
2041 //===----------------------------------------------------------------------===//
2042 // Tracker implementation
2043 //===----------------------------------------------------------------------===//
2044 
2045 PathDiagnosticPieceRef StoreHandler::constructNote(StoreInfo SI,
2046  BugReporterContext &BRC,
2047  StringRef NodeText) {
2048  // Construct a new PathDiagnosticPiece.
2051  if (P.getAs<CallEnter>() && SI.SourceOfTheValue)
2053  P.getLocationContext());
2054 
2055  if (!L.isValid() || !L.asLocation().isValid())
2057 
2058  if (!L.isValid() || !L.asLocation().isValid())
2059  return nullptr;
2060 
2061  return std::make_shared<PathDiagnosticEventPiece>(L, NodeText);
2062 }
2063 
2064 class DefaultStoreHandler final : public StoreHandler {
2065 public:
2066  using StoreHandler::StoreHandler;
2067 
2068  PathDiagnosticPieceRef handle(StoreInfo SI, BugReporterContext &BRC,
2069  TrackingOptions Opts) override {
2070  // Okay, we've found the binding. Emit an appropriate message.
2071  SmallString<256> Buffer;
2072  llvm::raw_svector_ostream OS(Buffer);
2073 
2074  switch (SI.StoreKind) {
2075  case StoreInfo::Initialization:
2076  case StoreInfo::BlockCapture:
2077  showBRDiagnostics(OS, SI);
2078  break;
2079  case StoreInfo::CallArgument:
2080  showBRParamDiagnostics(OS, SI);
2081  break;
2082  case StoreInfo::Assignment:
2083  showBRDefaultDiagnostics(OS, SI);
2084  break;
2085  }
2086 
2087  if (Opts.Kind == bugreporter::TrackingKind::Condition)
2089 
2090  return constructNote(SI, BRC, OS.str());
2091  }
2092 };
2093 
2095 public:
2096  using ExpressionHandler::ExpressionHandler;
2097 
2098  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2099  const ExplodedNode *LVNode,
2100  TrackingOptions Opts) override {
2101  PathSensitiveBugReport &Report = getParentTracker().getReport();
2102 
2103  // We only track expressions if we believe that they are important. Chances
2104  // are good that control dependencies to the tracking point are also
2105  // important because of this, let's explain why we believe control reached
2106  // this point.
2107  // TODO: Shouldn't we track control dependencies of every bug location,
2108  // rather than only tracked expressions?
2109  if (LVNode->getState()
2110  ->getAnalysisManager()
2111  .getAnalyzerOptions()
2112  .ShouldTrackConditions) {
2113  Report.addVisitor<TrackControlDependencyCondBRVisitor>(
2114  &getParentTracker(), InputNode);
2115  return {/*FoundSomethingToTrack=*/true};
2116  }
2117 
2118  return {};
2119  }
2120 };
2121 
2123 public:
2124  using ExpressionHandler::ExpressionHandler;
2125 
2126  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2127  const ExplodedNode *LVNode,
2128  TrackingOptions Opts) override {
2129  // The message send could be nil due to the receiver being nil.
2130  // At this point in the path, the receiver should be live since we are at
2131  // the message send expr. If it is nil, start tracking it.
2132  if (const Expr *Receiver =
2133  NilReceiverBRVisitor::getNilReceiver(Inner, LVNode))
2134  return getParentTracker().track(Receiver, LVNode, Opts);
2135 
2136  return {};
2137  }
2138 };
2139 
2140 class ArrayIndexHandler final : public ExpressionHandler {
2141 public:
2142  using ExpressionHandler::ExpressionHandler;
2143 
2144  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2145  const ExplodedNode *LVNode,
2146  TrackingOptions Opts) override {
2147  // Track the index if this is an array subscript.
2148  if (const auto *Arr = dyn_cast<ArraySubscriptExpr>(Inner))
2149  return getParentTracker().track(
2150  Arr->getIdx(), LVNode,
2151  {Opts.Kind, /*EnableNullFPSuppression*/ false});
2152 
2153  return {};
2154  }
2155 };
2156 
2157 // TODO: extract it into more handlers
2159 public:
2160  using ExpressionHandler::ExpressionHandler;
2161 
2162  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2163  const ExplodedNode *LVNode,
2164  TrackingOptions Opts) override {
2165  ProgramStateRef LVState = LVNode->getState();
2166  const StackFrameContext *SFC = LVNode->getStackFrame();
2167  PathSensitiveBugReport &Report = getParentTracker().getReport();
2168  Tracker::Result Result;
2169 
2170  // See if the expression we're interested refers to a variable.
2171  // If so, we can track both its contents and constraints on its value.
2173  SVal LVal = LVNode->getSVal(Inner);
2174 
2175  const MemRegion *RR = getLocationRegionIfReference(Inner, LVNode);
2176  bool LVIsNull = LVState->isNull(LVal).isConstrainedTrue();
2177 
2178  // If this is a C++ reference to a null pointer, we are tracking the
2179  // pointer. In addition, we should find the store at which the reference
2180  // got initialized.
2181  if (RR && !LVIsNull)
2182  Result.combineWith(getParentTracker().track(LVal, RR, Opts, SFC));
2183 
2184  // In case of C++ references, we want to differentiate between a null
2185  // reference and reference to null pointer.
2186  // If the LVal is null, check if we are dealing with null reference.
2187  // For those, we want to track the location of the reference.
2188  const MemRegion *R =
2189  (RR && LVIsNull) ? RR : LVNode->getSVal(Inner).getAsRegion();
2190 
2191  if (R) {
2192 
2193  // Mark both the variable region and its contents as interesting.
2194  SVal V = LVState->getRawSVal(loc::MemRegionVal(R));
2195  Report.addVisitor<NoStoreFuncVisitor>(cast<SubRegion>(R), Opts.Kind);
2196 
2197  // When we got here, we do have something to track, and we will
2198  // interrupt.
2199  Result.FoundSomethingToTrack = true;
2200  Result.WasInterrupted = true;
2201 
2202  MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary(
2203  LVNode, R, Opts.EnableNullFPSuppression, Report, V);
2204 
2205  Report.markInteresting(V, Opts.Kind);
2206  Report.addVisitor<UndefOrNullArgVisitor>(R);
2207 
2208  // If the contents are symbolic and null, find out when they became
2209  // null.
2210  if (V.getAsLocSymbol(/*IncludeBaseRegions=*/true))
2211  if (LVState->isNull(V).isConstrainedTrue())
2212  Report.addVisitor<TrackConstraintBRVisitor>(V.castAs<DefinedSVal>(),
2213  false);
2214 
2215  // Add visitor, which will suppress inline defensive checks.
2216  if (auto DV = V.getAs<DefinedSVal>())
2217  if (!DV->isZeroConstant() && Opts.EnableNullFPSuppression)
2218  // Note that LVNode may be too late (i.e., too far from the
2219  // InputNode) because the lvalue may have been computed before the
2220  // inlined call was evaluated. InputNode may as well be too early
2221  // here, because the symbol is already dead; this, however, is fine
2222  // because we can still find the node in which it collapsed to null
2223  // previously.
2224  Report.addVisitor<SuppressInlineDefensiveChecksVisitor>(*DV,
2225  InputNode);
2226  getParentTracker().track(V, R, Opts, SFC);
2227  }
2228  }
2229 
2230  return Result;
2231  }
2232 };
2233 
2234 /// Adds a ReturnVisitor if the given statement represents a call that was
2235 /// inlined.
2236 ///
2237 /// This will search back through the ExplodedGraph, starting from the given
2238 /// node, looking for when the given statement was processed. If it turns out
2239 /// the statement is a call that was inlined, we add the visitor to the
2240 /// bug report, so it can print a note later.
2242  using ExpressionHandler::ExpressionHandler;
2243 
2244  Tracker::Result handle(const Expr *E, const ExplodedNode *InputNode,
2245  const ExplodedNode *ExprNode,
2246  TrackingOptions Opts) override {
2247  if (!CallEvent::isCallStmt(E))
2248  return {};
2249 
2250  // First, find when we processed the statement.
2251  // If we work with a 'CXXNewExpr' that is going to be purged away before
2252  // its call take place. We would catch that purge in the last condition
2253  // as a 'StmtPoint' so we have to bypass it.
2254  const bool BypassCXXNewExprEval = isa<CXXNewExpr>(E);
2255 
2256  // This is moving forward when we enter into another context.
2257  const StackFrameContext *CurrentSFC = ExprNode->getStackFrame();
2258 
2259  do {
2260  // If that is satisfied we found our statement as an inlined call.
2261  if (Optional<CallExitEnd> CEE = ExprNode->getLocationAs<CallExitEnd>())
2262  if (CEE->getCalleeContext()->getCallSite() == E)
2263  break;
2264 
2265  // Try to move forward to the end of the call-chain.
2266  ExprNode = ExprNode->getFirstPred();
2267  if (!ExprNode)
2268  break;
2269 
2270  const StackFrameContext *PredSFC = ExprNode->getStackFrame();
2271 
2272  // If that is satisfied we found our statement.
2273  // FIXME: This code currently bypasses the call site for the
2274  // conservatively evaluated allocator.
2275  if (!BypassCXXNewExprEval)
2276  if (Optional<StmtPoint> SP = ExprNode->getLocationAs<StmtPoint>())
2277  // See if we do not enter into another context.
2278  if (SP->getStmt() == E && CurrentSFC == PredSFC)
2279  break;
2280 
2281  CurrentSFC = PredSFC;
2282  } while (ExprNode->getStackFrame() == CurrentSFC);
2283 
2284  // Next, step over any post-statement checks.
2285  while (ExprNode && ExprNode->getLocation().getAs<PostStmt>())
2286  ExprNode = ExprNode->getFirstPred();
2287  if (!ExprNode)
2288  return {};
2289 
2290  // Finally, see if we inlined the call.
2291  Optional<CallExitEnd> CEE = ExprNode->getLocationAs<CallExitEnd>();
2292  if (!CEE)
2293  return {};
2294 
2295  const StackFrameContext *CalleeContext = CEE->getCalleeContext();
2296  if (CalleeContext->getCallSite() != E)
2297  return {};
2298 
2299  // Check the return value.
2300  ProgramStateRef State = ExprNode->getState();
2301  SVal RetVal = ExprNode->getSVal(E);
2302 
2303  // Handle cases where a reference is returned and then immediately used.
2304  if (cast<Expr>(E)->isGLValue())
2305  if (Optional<Loc> LValue = RetVal.getAs<Loc>())
2306  RetVal = State->getSVal(*LValue);
2307 
2308  // See if the return value is NULL. If so, suppress the report.
2309  AnalyzerOptions &Options = State->getAnalysisManager().options;
2310 
2311  bool EnableNullFPSuppression = false;
2312  if (Opts.EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths)
2313  if (Optional<Loc> RetLoc = RetVal.getAs<Loc>())
2314  EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
2315 
2316  PathSensitiveBugReport &Report = getParentTracker().getReport();
2317  Report.addVisitor<ReturnVisitor>(&getParentTracker(), CalleeContext,
2318  EnableNullFPSuppression, Options,
2319  Opts.Kind);
2320  return {true};
2321  }
2322 };
2323 
2325 public:
2326  using ExpressionHandler::ExpressionHandler;
2327 
2328  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2329  const ExplodedNode *LVNode,
2330  TrackingOptions Opts) override {
2331  ProgramStateRef LVState = LVNode->getState();
2332  const StackFrameContext *SFC = LVNode->getStackFrame();
2333  PathSensitiveBugReport &Report = getParentTracker().getReport();
2334  Tracker::Result Result;
2335 
2336  // If the expression is not an "lvalue expression", we can still
2337  // track the constraints on its contents.
2338  SVal V = LVState->getSValAsScalarOrLoc(Inner, LVNode->getLocationContext());
2339 
2340  // Is it a symbolic value?
2341  if (auto L = V.getAs<loc::MemRegionVal>()) {
2342  // FIXME: this is a hack for fixing a later crash when attempting to
2343  // dereference a void* pointer.
2344  // We should not try to dereference pointers at all when we don't care
2345  // what is written inside the pointer.
2346  bool CanDereference = true;
2347  if (const auto *SR = L->getRegionAs<SymbolicRegion>()) {
2348  if (SR->getSymbol()->getType()->getPointeeType()->isVoidType())
2349  CanDereference = false;
2350  } else if (L->getRegionAs<AllocaRegion>())
2351  CanDereference = false;
2352 
2353  // At this point we are dealing with the region's LValue.
2354  // However, if the rvalue is a symbolic region, we should track it as
2355  // well. Try to use the correct type when looking up the value.
2356  SVal RVal;
2358  RVal = LVState->getRawSVal(*L, Inner->getType());
2359  else if (CanDereference)
2360  RVal = LVState->getSVal(L->getRegion());
2361 
2362  if (CanDereference) {
2363  Report.addVisitor<UndefOrNullArgVisitor>(L->getRegion());
2364  Result.FoundSomethingToTrack = true;
2365 
2366  if (auto KV = RVal.getAs<KnownSVal>())
2367  Result.combineWith(
2368  getParentTracker().track(*KV, L->getRegion(), Opts, SFC));
2369  }
2370 
2371  const MemRegion *RegionRVal = RVal.getAsRegion();
2372  if (isa_and_nonnull<SymbolicRegion>(RegionRVal)) {
2373  Report.markInteresting(RegionRVal, Opts.Kind);
2374  Report.addVisitor<TrackConstraintBRVisitor>(
2375  loc::MemRegionVal(RegionRVal),
2376  /*assumption=*/false);
2377  Result.FoundSomethingToTrack = true;
2378  }
2379  }
2380 
2381  return Result;
2382  }
2383 };
2384 
2385 /// Attempts to add visitors to track an RValue expression back to its point of
2386 /// origin.
2387 class PRValueHandler final : public ExpressionHandler {
2388 public:
2389  using ExpressionHandler::ExpressionHandler;
2390 
2391  Tracker::Result handle(const Expr *E, const ExplodedNode *InputNode,
2392  const ExplodedNode *ExprNode,
2393  TrackingOptions Opts) override {
2394  if (!E->isPRValue())
2395  return {};
2396 
2397  const ExplodedNode *RVNode = findNodeForExpression(ExprNode, E);
2398  if (!RVNode)
2399  return {};
2400 
2401  ProgramStateRef RVState = RVNode->getState();
2402  SVal V = RVState->getSValAsScalarOrLoc(E, RVNode->getLocationContext());
2403  const auto *BO = dyn_cast<BinaryOperator>(E);
2404 
2405  if (!BO || !BO->isMultiplicativeOp() || !V.isZeroConstant())
2406  return {};
2407 
2408  SVal RHSV = RVState->getSVal(BO->getRHS(), RVNode->getLocationContext());
2409  SVal LHSV = RVState->getSVal(BO->getLHS(), RVNode->getLocationContext());
2410 
2411  // Track both LHS and RHS of a multiplication.
2412  Tracker::Result CombinedResult;
2413  Tracker &Parent = getParentTracker();
2414 
2415  const auto track = [&CombinedResult, &Parent, ExprNode, Opts](Expr *Inner) {
2416  CombinedResult.combineWith(Parent.track(Inner, ExprNode, Opts));
2417  };
2418 
2419  if (BO->getOpcode() == BO_Mul) {
2420  if (LHSV.isZeroConstant())
2421  track(BO->getLHS());
2422  if (RHSV.isZeroConstant())
2423  track(BO->getRHS());
2424  } else { // Track only the LHS of a division or a modulo.
2425  if (LHSV.isZeroConstant())
2426  track(BO->getLHS());
2427  }
2428 
2429  return CombinedResult;
2430  }
2431 };
2432 
2433 Tracker::Tracker(PathSensitiveBugReport &Report) : Report(Report) {
2434  // Default expression handlers.
2435  addLowPriorityHandler<ControlDependencyHandler>();
2436  addLowPriorityHandler<NilReceiverHandler>();
2437  addLowPriorityHandler<ArrayIndexHandler>();
2438  addLowPriorityHandler<InterestingLValueHandler>();
2439  addLowPriorityHandler<InlinedFunctionCallHandler>();
2440  addLowPriorityHandler<DefaultExpressionHandler>();
2441  addLowPriorityHandler<PRValueHandler>();
2442  // Default store handlers.
2443  addHighPriorityHandler<DefaultStoreHandler>();
2444 }
2445 
2446 Tracker::Result Tracker::track(const Expr *E, const ExplodedNode *N,
2447  TrackingOptions Opts) {
2448  if (!E || !N)
2449  return {};
2450 
2451  const Expr *Inner = peelOffOuterExpr(E, N);
2452  const ExplodedNode *LVNode = findNodeForExpression(N, Inner);
2453  if (!LVNode)
2454  return {};
2455 
2456  Result CombinedResult;
2457  // Iterate through the handlers in the order according to their priorities.
2458  for (ExpressionHandlerPtr &Handler : ExpressionHandlers) {
2459  CombinedResult.combineWith(Handler->handle(Inner, N, LVNode, Opts));
2460  if (CombinedResult.WasInterrupted) {
2461  // There is no need to confuse our users here.
2462  // We got interrupted, but our users don't need to know about it.
2463  CombinedResult.WasInterrupted = false;
2464  break;
2465  }
2466  }
2467 
2468  return CombinedResult;
2469 }
2470 
2471 Tracker::Result Tracker::track(SVal V, const MemRegion *R, TrackingOptions Opts,
2472  const StackFrameContext *Origin) {
2473  if (auto KV = V.getAs<KnownSVal>()) {
2474  Report.addVisitor<StoreSiteFinder>(this, *KV, R, Opts, Origin);
2475  return {true};
2476  }
2477  return {};
2478 }
2479 
2481  TrackingOptions Opts) {
2482  // Iterate through the handlers in the order according to their priorities.
2483  for (StoreHandlerPtr &Handler : StoreHandlers) {
2484  if (PathDiagnosticPieceRef Result = Handler->handle(SI, BRC, Opts))
2485  // If the handler produced a non-null piece, return it.
2486  // There is no need in asking other handlers.
2487  return Result;
2488  }
2489  return {};
2490 }
2491 
2492 bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode,
2493  const Expr *E,
2494 
2495  PathSensitiveBugReport &Report,
2496  TrackingOptions Opts) {
2497  return Tracker::create(Report)
2498  ->track(E, InputNode, Opts)
2499  .FoundSomethingToTrack;
2500 }
2501 
2503  PathSensitiveBugReport &Report,
2504  TrackingOptions Opts,
2505  const StackFrameContext *Origin) {
2506  Tracker::create(Report)->track(V, R, Opts, Origin);
2507 }
2508 
2509 //===----------------------------------------------------------------------===//
2510 // Implementation of NulReceiverBRVisitor.
2511 //===----------------------------------------------------------------------===//
2512 
2514  const ExplodedNode *N) {
2515  const auto *ME = dyn_cast<ObjCMessageExpr>(S);
2516  if (!ME)
2517  return nullptr;
2518  if (const Expr *Receiver = ME->getInstanceReceiver()) {
2520  SVal V = N->getSVal(Receiver);
2521  if (state->isNull(V).isConstrainedTrue())
2522  return Receiver;
2523  }
2524  return nullptr;
2525 }
2526 
2529  PathSensitiveBugReport &BR) {
2531  if (!P)
2532  return nullptr;
2533 
2534  const Stmt *S = P->getStmt();
2535  const Expr *Receiver = getNilReceiver(S, N);
2536  if (!Receiver)
2537  return nullptr;
2538 
2540  llvm::raw_svector_ostream OS(Buf);
2541 
2542  if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
2543  OS << "'";
2544  ME->getSelector().print(OS);
2545  OS << "' not called";
2546  }
2547  else {
2548  OS << "No method is called";
2549  }
2550  OS << " because the receiver is nil";
2551 
2552  // The receiver was nil, and hence the method was skipped.
2553  // Register a BugReporterVisitor to issue a message telling us how
2554  // the receiver was null.
2555  bugreporter::trackExpressionValue(N, Receiver, BR,
2557  /*EnableNullFPSuppression*/ false});
2558  // Issue a message saying that the method was skipped.
2559  PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
2560  N->getLocationContext());
2561  return std::make_shared<PathDiagnosticEventPiece>(L, OS.str());
2562 }
2563 
2564 //===----------------------------------------------------------------------===//
2565 // Visitor that tries to report interesting diagnostics from conditions.
2566 //===----------------------------------------------------------------------===//
2567 
2568 /// Return the tag associated with this visitor. This tag will be used
2569 /// to make all PathDiagnosticPieces created by this visitor.
2570 const char *ConditionBRVisitor::getTag() { return "ConditionBRVisitor"; }
2571 
2574  PathSensitiveBugReport &BR) {
2575  auto piece = VisitNodeImpl(N, BRC, BR);
2576  if (piece) {
2577  piece->setTag(getTag());
2578  if (auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))
2579  ev->setPrunable(true, /* override */ false);
2580  }
2581  return piece;
2582 }
2583 
2586  BugReporterContext &BRC,
2587  PathSensitiveBugReport &BR) {
2588  ProgramPoint ProgPoint = N->getLocation();
2589  const std::pair<const ProgramPointTag *, const ProgramPointTag *> &Tags =
2591 
2592  // If an assumption was made on a branch, it should be caught
2593  // here by looking at the state transition.
2594  if (Optional<BlockEdge> BE = ProgPoint.getAs<BlockEdge>()) {
2595  const CFGBlock *SrcBlock = BE->getSrc();
2596  if (const Stmt *Term = SrcBlock->getTerminatorStmt()) {
2597  // If the tag of the previous node is 'Eagerly Assume...' the current
2598  // 'BlockEdge' has the same constraint information. We do not want to
2599  // report the value as it is just an assumption on the predecessor node
2600  // which will be caught in the next VisitNode() iteration as a 'PostStmt'.
2601  const ProgramPointTag *PreviousNodeTag =
2602  N->getFirstPred()->getLocation().getTag();
2603  if (PreviousNodeTag == Tags.first || PreviousNodeTag == Tags.second)
2604  return nullptr;
2605 
2606  return VisitTerminator(Term, N, SrcBlock, BE->getDst(), BR, BRC);
2607  }
2608  return nullptr;
2609  }
2610 
2611  if (Optional<PostStmt> PS = ProgPoint.getAs<PostStmt>()) {
2612  const ProgramPointTag *CurrentNodeTag = PS->getTag();
2613  if (CurrentNodeTag != Tags.first && CurrentNodeTag != Tags.second)
2614  return nullptr;
2615 
2616  bool TookTrue = CurrentNodeTag == Tags.first;
2617  return VisitTrueTest(cast<Expr>(PS->getStmt()), BRC, BR, N, TookTrue);
2618  }
2619 
2620  return nullptr;
2621 }
2622 
2624  const Stmt *Term, const ExplodedNode *N, const CFGBlock *srcBlk,
2625  const CFGBlock *dstBlk, PathSensitiveBugReport &R,
2626  BugReporterContext &BRC) {
2627  const Expr *Cond = nullptr;
2628 
2629  // In the code below, Term is a CFG terminator and Cond is a branch condition
2630  // expression upon which the decision is made on this terminator.
2631  //
2632  // For example, in "if (x == 0)", the "if (x == 0)" statement is a terminator,
2633  // and "x == 0" is the respective condition.
2634  //
2635  // Another example: in "if (x && y)", we've got two terminators and two
2636  // conditions due to short-circuit nature of operator "&&":
2637  // 1. The "if (x && y)" statement is a terminator,
2638  // and "y" is the respective condition.
2639  // 2. Also "x && ..." is another terminator,
2640  // and "x" is its condition.
2641 
2642  switch (Term->getStmtClass()) {
2643  // FIXME: Stmt::SwitchStmtClass is worth handling, however it is a bit
2644  // more tricky because there are more than two branches to account for.
2645  default:
2646  return nullptr;
2647  case Stmt::IfStmtClass:
2648  Cond = cast<IfStmt>(Term)->getCond();
2649  break;
2650  case Stmt::ConditionalOperatorClass:
2651  Cond = cast<ConditionalOperator>(Term)->getCond();
2652  break;
2653  case Stmt::BinaryOperatorClass:
2654  // When we encounter a logical operator (&& or ||) as a CFG terminator,
2655  // then the condition is actually its LHS; otherwise, we'd encounter
2656  // the parent, such as if-statement, as a terminator.
2657  const auto *BO = cast<BinaryOperator>(Term);
2658  assert(BO->isLogicalOp() &&
2659  "CFG terminator is not a short-circuit operator!");
2660  Cond = BO->getLHS();
2661  break;
2662  }
2663 
2664  Cond = Cond->IgnoreParens();
2665 
2666  // However, when we encounter a logical operator as a branch condition,
2667  // then the condition is actually its RHS, because LHS would be
2668  // the condition for the logical operator terminator.
2669  while (const auto *InnerBO = dyn_cast<BinaryOperator>(Cond)) {
2670  if (!InnerBO->isLogicalOp())
2671  break;
2672  Cond = InnerBO->getRHS()->IgnoreParens();
2673  }
2674 
2675  assert(Cond);
2676  assert(srcBlk->succ_size() == 2);
2677  const bool TookTrue = *(srcBlk->succ_begin()) == dstBlk;
2678  return VisitTrueTest(Cond, BRC, R, N, TookTrue);
2679 }
2680 
2684  const ExplodedNode *N, bool TookTrue) {
2685  ProgramStateRef CurrentState = N->getState();
2686  ProgramStateRef PrevState = N->getFirstPred()->getState();
2687  const LocationContext *LCtx = N->getLocationContext();
2688 
2689  // If the constraint information is changed between the current and the
2690  // previous program state we assuming the newly seen constraint information.
2691  // If we cannot evaluate the condition (and the constraints are the same)
2692  // the analyzer has no information about the value and just assuming it.
2693  bool IsAssuming =
2694  !BRC.getStateManager().haveEqualConstraints(CurrentState, PrevState) ||
2695  CurrentState->getSVal(Cond, LCtx).isUnknownOrUndef();
2696 
2697  // These will be modified in code below, but we need to preserve the original
2698  // values in case we want to throw the generic message.
2699  const Expr *CondTmp = Cond;
2700  bool TookTrueTmp = TookTrue;
2701 
2702  while (true) {
2703  CondTmp = CondTmp->IgnoreParenCasts();
2704  switch (CondTmp->getStmtClass()) {
2705  default:
2706  break;
2707  case Stmt::BinaryOperatorClass:
2708  if (auto P = VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp),
2709  BRC, R, N, TookTrueTmp, IsAssuming))
2710  return P;
2711  break;
2712  case Stmt::DeclRefExprClass:
2713  if (auto P = VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp),
2714  BRC, R, N, TookTrueTmp, IsAssuming))
2715  return P;
2716  break;
2717  case Stmt::MemberExprClass:
2718  if (auto P = VisitTrueTest(Cond, cast<MemberExpr>(CondTmp),
2719  BRC, R, N, TookTrueTmp, IsAssuming))
2720  return P;
2721  break;
2722  case Stmt::UnaryOperatorClass: {
2723  const auto *UO = cast<UnaryOperator>(CondTmp);
2724  if (UO->getOpcode() == UO_LNot) {
2725  TookTrueTmp = !TookTrueTmp;
2726  CondTmp = UO->getSubExpr();
2727  continue;
2728  }
2729  break;
2730  }
2731  }
2732  break;
2733  }
2734 
2735  // Condition too complex to explain? Just say something so that the user
2736  // knew we've made some path decision at this point.
2737  // If it is too complex and we know the evaluation of the condition do not
2738  // repeat the note from 'BugReporter.cpp'
2739  if (!IsAssuming)
2740  return nullptr;
2741 
2742  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
2743  if (!Loc.isValid() || !Loc.asLocation().isValid())
2744  return nullptr;
2745 
2746  return std::make_shared<PathDiagnosticEventPiece>(
2747  Loc, TookTrue ? GenericTrueMessage : GenericFalseMessage);
2748 }
2749 
2751  const Expr *ParentEx,
2752  raw_ostream &Out,
2753  BugReporterContext &BRC,
2754  PathSensitiveBugReport &report,
2755  const ExplodedNode *N,
2756  Optional<bool> &prunable,
2757  bool IsSameFieldName) {
2758  const Expr *OriginalExpr = Ex;
2759  Ex = Ex->IgnoreParenCasts();
2760 
2762  FloatingLiteral>(Ex)) {
2763  // Use heuristics to determine if the expression is a macro
2764  // expanding to a literal and if so, use the macro's name.
2765  SourceLocation BeginLoc = OriginalExpr->getBeginLoc();
2766  SourceLocation EndLoc = OriginalExpr->getEndLoc();
2767  if (BeginLoc.isMacroID() && EndLoc.isMacroID()) {
2768  const SourceManager &SM = BRC.getSourceManager();
2769  const LangOptions &LO = BRC.getASTContext().getLangOpts();
2770  if (Lexer::isAtStartOfMacroExpansion(BeginLoc, SM, LO) &&
2771  Lexer::isAtEndOfMacroExpansion(EndLoc, SM, LO)) {
2772  CharSourceRange R = Lexer::getAsCharRange({BeginLoc, EndLoc}, SM, LO);
2773  Out << Lexer::getSourceText(R, SM, LO);
2774  return false;
2775  }
2776  }
2777  }
2778 
2779  if (const auto *DR = dyn_cast<DeclRefExpr>(Ex)) {
2780  const bool quotes = isa<VarDecl>(DR->getDecl());
2781  if (quotes) {
2782  Out << '\'';
2783  const LocationContext *LCtx = N->getLocationContext();
2784  const ProgramState *state = N->getState().get();
2785  if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
2786  LCtx).getAsRegion()) {
2787  if (report.isInteresting(R))
2788  prunable = false;
2789  else {
2790  const ProgramState *state = N->getState().get();
2791  SVal V = state->getSVal(R);
2792  if (report.isInteresting(V))
2793  prunable = false;
2794  }
2795  }
2796  }
2797  Out << DR->getDecl()->getDeclName().getAsString();
2798  if (quotes)
2799  Out << '\'';
2800  return quotes;
2801  }
2802 
2803  if (const auto *IL = dyn_cast<IntegerLiteral>(Ex)) {
2804  QualType OriginalTy = OriginalExpr->getType();
2805  if (OriginalTy->isPointerType()) {
2806  if (IL->getValue() == 0) {
2807  Out << "null";
2808  return false;
2809  }
2810  }
2811  else if (OriginalTy->isObjCObjectPointerType()) {
2812  if (IL->getValue() == 0) {
2813  Out << "nil";
2814  return false;
2815  }
2816  }
2817 
2818  Out << IL->getValue();
2819  return false;
2820  }
2821 
2822  if (const auto *ME = dyn_cast<MemberExpr>(Ex)) {
2823  if (!IsSameFieldName)
2824  Out << "field '" << ME->getMemberDecl()->getName() << '\'';
2825  else
2826  Out << '\''
2830  nullptr)
2831  << '\'';
2832  }
2833 
2834  return false;
2835 }
2836 
2838  const Expr *Cond, const BinaryOperator *BExpr, BugReporterContext &BRC,
2839  PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue,
2840  bool IsAssuming) {
2841  bool shouldInvert = false;
2842  Optional<bool> shouldPrune;
2843 
2844  // Check if the field name of the MemberExprs is ambiguous. Example:
2845  // " 'a.d' is equal to 'h.d' " in 'test/Analysis/null-deref-path-notes.cpp'.
2846  bool IsSameFieldName = false;
2847  const auto *LhsME = dyn_cast<MemberExpr>(BExpr->getLHS()->IgnoreParenCasts());
2848  const auto *RhsME = dyn_cast<MemberExpr>(BExpr->getRHS()->IgnoreParenCasts());
2849 
2850  if (LhsME && RhsME)
2851  IsSameFieldName =
2852  LhsME->getMemberDecl()->getName() == RhsME->getMemberDecl()->getName();
2853 
2854  SmallString<128> LhsString, RhsString;
2855  {
2856  llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
2857  const bool isVarLHS = patternMatch(BExpr->getLHS(), BExpr, OutLHS, BRC, R,
2858  N, shouldPrune, IsSameFieldName);
2859  const bool isVarRHS = patternMatch(BExpr->getRHS(), BExpr, OutRHS, BRC, R,
2860  N, shouldPrune, IsSameFieldName);
2861 
2862  shouldInvert = !isVarLHS && isVarRHS;
2863  }
2864 
2865  BinaryOperator::Opcode Op = BExpr->getOpcode();
2866 
2868  // For assignment operators, all that we care about is that the LHS
2869  // evaluates to "true" or "false".
2870  return VisitConditionVariable(LhsString, BExpr->getLHS(), BRC, R, N,
2871  TookTrue);
2872  }
2873 
2874  // For non-assignment operations, we require that we can understand
2875  // both the LHS and RHS.
2876  if (LhsString.empty() || RhsString.empty() ||
2877  !BinaryOperator::isComparisonOp(Op) || Op == BO_Cmp)
2878  return nullptr;
2879 
2880  // Should we invert the strings if the LHS is not a variable name?
2881  SmallString<256> buf;
2882  llvm::raw_svector_ostream Out(buf);
2883  Out << (IsAssuming ? "Assuming " : "")
2884  << (shouldInvert ? RhsString : LhsString) << " is ";
2885 
2886  // Do we need to invert the opcode?
2887  if (shouldInvert)
2888  switch (Op) {
2889  default: break;
2890  case BO_LT: Op = BO_GT; break;
2891  case BO_GT: Op = BO_LT; break;
2892  case BO_LE: Op = BO_GE; break;
2893  case BO_GE: Op = BO_LE; break;
2894  }
2895 
2896  if (!TookTrue)
2897  switch (Op) {
2898  case BO_EQ: Op = BO_NE; break;
2899  case BO_NE: Op = BO_EQ; break;
2900  case BO_LT: Op = BO_GE; break;
2901  case BO_GT: Op = BO_LE; break;
2902  case BO_LE: Op = BO_GT; break;
2903  case BO_GE: Op = BO_LT; break;
2904  default:
2905  return nullptr;
2906  }
2907 
2908  switch (Op) {
2909  case BO_EQ:
2910  Out << "equal to ";
2911  break;
2912  case BO_NE:
2913  Out << "not equal to ";
2914  break;
2915  default:
2916  Out << BinaryOperator::getOpcodeStr(Op) << ' ';
2917  break;
2918  }
2919 
2920  Out << (shouldInvert ? LhsString : RhsString);
2921  const LocationContext *LCtx = N->getLocationContext();
2922  const SourceManager &SM = BRC.getSourceManager();
2923 
2924  if (isVarAnInterestingCondition(BExpr->getLHS(), N, &R) ||
2925  isVarAnInterestingCondition(BExpr->getRHS(), N, &R))
2926  Out << WillBeUsedForACondition;
2927 
2928  // Convert 'field ...' to 'Field ...' if it is a MemberExpr.
2929  std::string Message = std::string(Out.str());
2930  Message[0] = toupper(Message[0]);
2931 
2932  // If we know the value create a pop-up note to the value part of 'BExpr'.
2933  if (!IsAssuming) {
2935  if (!shouldInvert) {
2936  if (LhsME && LhsME->getMemberLoc().isValid())
2937  Loc = PathDiagnosticLocation(LhsME->getMemberLoc(), SM);
2938  else
2939  Loc = PathDiagnosticLocation(BExpr->getLHS(), SM, LCtx);
2940  } else {
2941  if (RhsME && RhsME->getMemberLoc().isValid())
2942  Loc = PathDiagnosticLocation(RhsME->getMemberLoc(), SM);
2943  else
2944  Loc = PathDiagnosticLocation(BExpr->getRHS(), SM, LCtx);
2945  }
2946 
2947  return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Message);
2948  }
2949 
2950  PathDiagnosticLocation Loc(Cond, SM, LCtx);
2951  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Message);
2952  if (shouldPrune)
2953  event->setPrunable(shouldPrune.getValue());
2954  return event;
2955 }
2956 
2958  StringRef LhsString, const Expr *CondVarExpr, BugReporterContext &BRC,
2959  PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue) {
2960  // FIXME: If there's already a constraint tracker for this variable,
2961  // we shouldn't emit anything here (c.f. the double note in
2962  // test/Analysis/inlining/path-notes.c)
2963  SmallString<256> buf;
2964  llvm::raw_svector_ostream Out(buf);
2965  Out << "Assuming " << LhsString << " is ";
2966 
2967  if (!printValue(CondVarExpr, Out, N, TookTrue, /*IsAssuming=*/true))
2968  return nullptr;
2969 
2970  const LocationContext *LCtx = N->getLocationContext();
2971  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
2972 
2973  if (isVarAnInterestingCondition(CondVarExpr, N, &report))
2974  Out << WillBeUsedForACondition;
2975 
2976  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
2977 
2978  if (isInterestingExpr(CondVarExpr, N, &report))
2979  event->setPrunable(false);
2980 
2981  return event;
2982 }
2983 
2985  const Expr *Cond, const DeclRefExpr *DRE, BugReporterContext &BRC,
2986  PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue,
2987  bool IsAssuming) {
2988  const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
2989  if (!VD)
2990  return nullptr;
2991 
2992  SmallString<256> Buf;
2993  llvm::raw_svector_ostream Out(Buf);
2994 
2995  Out << (IsAssuming ? "Assuming '" : "'") << VD->getDeclName() << "' is ";
2996 
2997  if (!printValue(DRE, Out, N, TookTrue, IsAssuming))
2998  return nullptr;
2999 
3000  const LocationContext *LCtx = N->getLocationContext();
3001 
3002  if (isVarAnInterestingCondition(DRE, N, &report))
3003  Out << WillBeUsedForACondition;
3004 
3005  // If we know the value create a pop-up note to the 'DRE'.
3006  if (!IsAssuming) {
3007  PathDiagnosticLocation Loc(DRE, BRC.getSourceManager(), LCtx);
3008  return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str());
3009  }
3010 
3011  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
3012  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
3013 
3014  if (isInterestingExpr(DRE, N, &report))
3015  event->setPrunable(false);
3016 
3017  return std::move(event);
3018 }
3019 
3021  const Expr *Cond, const MemberExpr *ME, BugReporterContext &BRC,
3022  PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue,
3023  bool IsAssuming) {
3024  SmallString<256> Buf;
3025  llvm::raw_svector_ostream Out(Buf);
3026 
3027  Out << (IsAssuming ? "Assuming field '" : "Field '")
3028  << ME->getMemberDecl()->getName() << "' is ";
3029 
3030  if (!printValue(ME, Out, N, TookTrue, IsAssuming))
3031  return nullptr;
3032 
3033  const LocationContext *LCtx = N->getLocationContext();
3034  PathDiagnosticLocation Loc;
3035 
3036  // If we know the value create a pop-up note to the member of the MemberExpr.
3037  if (!IsAssuming && ME->getMemberLoc().isValid())
3038  Loc = PathDiagnosticLocation(ME->getMemberLoc(), BRC.getSourceManager());
3039  else
3040  Loc = PathDiagnosticLocation(Cond, BRC.getSourceManager(), LCtx);
3041 
3042  if (!Loc.isValid() || !Loc.asLocation().isValid())
3043  return nullptr;
3044 
3045  if (isVarAnInterestingCondition(ME, N, &report))
3046  Out << WillBeUsedForACondition;
3047 
3048  // If we know the value create a pop-up note.
3049  if (!IsAssuming)
3050  return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str());
3051 
3052  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
3053  if (isInterestingExpr(ME, N, &report))
3054  event->setPrunable(false);
3055  return event;
3056 }
3057 
3058 bool ConditionBRVisitor::printValue(const Expr *CondVarExpr, raw_ostream &Out,
3059  const ExplodedNode *N, bool TookTrue,
3060  bool IsAssuming) {
3061  QualType Ty = CondVarExpr->getType();
3062 
3063  if (Ty->isPointerType()) {
3064  Out << (TookTrue ? "non-null" : "null");
3065  return true;
3066  }
3067 
3068  if (Ty->isObjCObjectPointerType()) {
3069  Out << (TookTrue ? "non-nil" : "nil");
3070  return true;
3071  }
3072 
3073  if (!Ty->isIntegralOrEnumerationType())
3074  return false;
3075 
3077  if (!IsAssuming)
3078  IntValue = getConcreteIntegerValue(CondVarExpr, N);
3079 
3080  if (IsAssuming || !IntValue) {
3081  if (Ty->isBooleanType())
3082  Out << (TookTrue ? "true" : "false");
3083  else
3084  Out << (TookTrue ? "not equal to 0" : "0");
3085  } else {
3086  if (Ty->isBooleanType())
3087  Out << (IntValue.getValue()->getBoolValue() ? "true" : "false");
3088  else
3089  Out << *IntValue.getValue();
3090  }
3091 
3092  return true;
3093 }
3094 
3095 constexpr llvm::StringLiteral ConditionBRVisitor::GenericTrueMessage;
3096 constexpr llvm::StringLiteral ConditionBRVisitor::GenericFalseMessage;
3097 
3099  const PathDiagnosticPiece *Piece) {
3100  return Piece->getString() == GenericTrueMessage ||
3101  Piece->getString() == GenericFalseMessage;
3102 }
3103 
3104 //===----------------------------------------------------------------------===//
3105 // Implementation of LikelyFalsePositiveSuppressionBRVisitor.
3106 //===----------------------------------------------------------------------===//
3107 
3109  BugReporterContext &BRC, const ExplodedNode *N,
3110  PathSensitiveBugReport &BR) {
3111  // Here we suppress false positives coming from system headers. This list is
3112  // based on known issues.
3113  const AnalyzerOptions &Options = BRC.getAnalyzerOptions();
3114  const Decl *D = N->getLocationContext()->getDecl();
3115 
3117  // Skip reports within the 'std' namespace. Although these can sometimes be
3118  // the user's fault, we currently don't report them very well, and
3119  // Note that this will not help for any other data structure libraries, like
3120  // TR1, Boost, or llvm/ADT.
3121  if (Options.ShouldSuppressFromCXXStandardLibrary) {
3122  BR.markInvalid(getTag(), nullptr);
3123  return;
3124  } else {
3125  // If the complete 'std' suppression is not enabled, suppress reports
3126  // from the 'std' namespace that are known to produce false positives.
3127 
3128  // The analyzer issues a false use-after-free when std::list::pop_front
3129  // or std::list::pop_back are called multiple times because we cannot
3130  // reason about the internal invariants of the data structure.
3131  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3132  const CXXRecordDecl *CD = MD->getParent();
3133  if (CD->getName() == "list") {
3134  BR.markInvalid(getTag(), nullptr);
3135  return;
3136  }
3137  }
3138 
3139  // The analyzer issues a false positive when the constructor of
3140  // std::__independent_bits_engine from algorithms is used.
3141  if (const auto *MD = dyn_cast<CXXConstructorDecl>(D)) {
3142  const CXXRecordDecl *CD = MD->getParent();
3143  if (CD->getName() == "__independent_bits_engine") {
3144  BR.markInvalid(getTag(), nullptr);
3145  return;
3146  }
3147  }
3148 
3149  for (const LocationContext *LCtx = N->getLocationContext(); LCtx;
3150  LCtx = LCtx->getParent()) {
3151  const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl());
3152  if (!MD)
3153  continue;
3154 
3155  const CXXRecordDecl *CD = MD->getParent();
3156  // The analyzer issues a false positive on
3157  // std::basic_string<uint8_t> v; v.push_back(1);
3158  // and
3159  // std::u16string s; s += u'a';
3160  // because we cannot reason about the internal invariants of the
3161  // data structure.
3162  if (CD->getName() == "basic_string") {
3163  BR.markInvalid(getTag(), nullptr);
3164  return;
3165  }
3166 
3167  // The analyzer issues a false positive on
3168  // std::shared_ptr<int> p(new int(1)); p = nullptr;
3169  // because it does not reason properly about temporary destructors.
3170  if (CD->getName() == "shared_ptr") {
3171  BR.markInvalid(getTag(), nullptr);
3172  return;
3173  }
3174  }
3175  }
3176  }
3177 
3178  // Skip reports within the sys/queue.h macros as we do not have the ability to
3179  // reason about data structure shapes.
3180  const SourceManager &SM = BRC.getSourceManager();
3182  while (Loc.isMacroID()) {
3183  Loc = Loc.getSpellingLoc();
3184  if (SM.getFilename(Loc).endswith("sys/queue.h")) {
3185  BR.markInvalid(getTag(), nullptr);
3186  return;
3187  }
3188  }
3189 }
3190 
3191 //===----------------------------------------------------------------------===//
3192 // Implementation of UndefOrNullArgVisitor.
3193 //===----------------------------------------------------------------------===//
3194 
3197  PathSensitiveBugReport &BR) {
3199  ProgramPoint ProgLoc = N->getLocation();
3200 
3201  // We are only interested in visiting CallEnter nodes.
3202  Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
3203  if (!CEnter)
3204  return nullptr;
3205 
3206  // Check if one of the arguments is the region the visitor is tracking.
3208  CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
3209  unsigned Idx = 0;
3210  ArrayRef<ParmVarDecl *> parms = Call->parameters();
3211 
3212  for (const auto ParamDecl : parms) {
3213  const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
3214  ++Idx;
3215 
3216  // Are we tracking the argument or its subregion?
3217  if ( !ArgReg || !R->isSubRegionOf(ArgReg->StripCasts()))
3218  continue;
3219 
3220  // Check the function parameter type.
3221  assert(ParamDecl && "Formal parameter has no decl?");
3222  QualType T = ParamDecl->getType();
3223 
3224  if (!(T->isAnyPointerType() || T->isReferenceType())) {
3225  // Function can only change the value passed in by address.
3226  continue;
3227  }
3228 
3229  // If it is a const pointer value, the function does not intend to
3230  // change the value.
3231  if (T->getPointeeType().isConstQualified())
3232  continue;
3233 
3234  // Mark the call site (LocationContext) as interesting if the value of the
3235  // argument is undefined or '0'/'NULL'.
3236  SVal BoundVal = State->getSVal(R);
3237  if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
3238  BR.markInteresting(CEnter->getCalleeContext());
3239  return nullptr;
3240  }
3241  }
3242  return nullptr;
3243 }
3244 
3245 //===----------------------------------------------------------------------===//
3246 // Implementation of FalsePositiveRefutationBRVisitor.
3247 //===----------------------------------------------------------------------===//
3248 
3250  : Constraints(ConstraintMap::Factory().getEmptyMap()) {}
3251 
3253  BugReporterContext &BRC, const ExplodedNode *EndPathNode,
3254  PathSensitiveBugReport &BR) {
3255  // Collect new constraints
3256  addConstraints(EndPathNode, /*OverwriteConstraintsOnExistingSyms=*/true);
3257 
3258  // Create a refutation manager
3259  llvm::SMTSolverRef RefutationSolver = llvm::CreateZ3Solver();
3260  ASTContext &Ctx = BRC.getASTContext();
3261 
3262  // Add constraints to the solver
3263  for (const auto &I : Constraints) {
3264  const SymbolRef Sym = I.first;
3265  auto RangeIt = I.second.begin();
3266 
3267  llvm::SMTExprRef SMTConstraints = SMTConv::getRangeExpr(
3268  RefutationSolver, Ctx, Sym, RangeIt->From(), RangeIt->To(),
3269  /*InRange=*/true);
3270  while ((++RangeIt) != I.second.end()) {
3271  SMTConstraints = RefutationSolver->mkOr(
3272  SMTConstraints, SMTConv::getRangeExpr(RefutationSolver, Ctx, Sym,
3273  RangeIt->From(), RangeIt->To(),
3274  /*InRange=*/true));
3275  }
3276 
3277  RefutationSolver->addConstraint(SMTConstraints);
3278  }
3279 
3280  // And check for satisfiability
3281  Optional<bool> IsSAT = RefutationSolver->check();
3282  if (!IsSAT)
3283  return;
3284 
3285  if (!IsSAT.getValue())
3286  BR.markInvalid("Infeasible constraints", EndPathNode->getLocationContext());
3287 }
3288 
3290  const ExplodedNode *N, bool OverwriteConstraintsOnExistingSyms) {
3291  // Collect new constraints
3292  ConstraintMap NewCs = getConstraintMap(N->getState());
3293  ConstraintMap::Factory &CF = N->getState()->get_context<ConstraintMap>();
3294 
3295  // Add constraints if we don't have them yet
3296  for (auto const &C : NewCs) {
3297  const SymbolRef &Sym = C.first;
3298  if (!Constraints.contains(Sym)) {
3299  // This symbol is new, just add the constraint.
3300  Constraints = CF.add(Constraints, Sym, C.second);
3301  } else if (OverwriteConstraintsOnExistingSyms) {
3302  // Overwrite the associated constraint of the Symbol.
3303  Constraints = CF.remove(Constraints, Sym);
3304  Constraints = CF.add(Constraints, Sym, C.second);
3305  }
3306  }
3307 }
3308 
3311  addConstraints(N, /*OverwriteConstraintsOnExistingSyms=*/false);
3312  return nullptr;
3313 }
3314 
3316  llvm::FoldingSetNodeID &ID) const {
3317  static int Tag = 0;
3318  ID.AddPointer(&Tag);
3319 }
3320 
3321 //===----------------------------------------------------------------------===//
3322 // Implementation of TagVisitor.
3323 //===----------------------------------------------------------------------===//
3324 
3325 int NoteTag::Kind = 0;
3326 
3327 void TagVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
3328  static int Tag = 0;
3329  ID.AddPointer(&Tag);
3330 }
3331 
3333  BugReporterContext &BRC,
3335  ProgramPoint PP = N->getLocation();
3336  const NoteTag *T = dyn_cast_or_null<NoteTag>(PP.getTag());
3337  if (!T)
3338  return nullptr;
3339 
3340  if (Optional<std::string> Msg = T->generateMessage(BRC, R)) {
3343  auto Piece = std::make_shared<PathDiagnosticEventPiece>(Loc, *Msg);
3344  Piece->setPrunable(T->isPrunable());
3345  return Piece;
3346  }
3347 
3348  return nullptr;
3349 }
clang::AnalysisDeclContext::getCFGStmtMap
CFGStmtMap * getCFGStmtMap()
Definition: AnalysisDeclContext.cpp:251
clang::CallExitBegin
Represents a point when we start the call exit sequence (for inlined call).
Definition: ProgramPoint.h:667
clang::Lexer::isAtEndOfMacroExpansion
static bool isAtEndOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroEnd=nullptr)
Returns true if the given MacroID location points at the last token of the macro expansion.
Definition: Lexer.cpp:831
clang::ento::ProgramStateManager::haveEqualConstraints
bool haveEqualConstraints(ProgramStateRef S1, ProgramStateRef S2) const
Definition: ProgramState.h:608
AnalyzerOptions.h
clang::ento::PathSensitiveBugReport::addVisitor
void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)
Add custom or predefined bug report visitors to this report.
Definition: BugReporter.cpp:2157
InterestingLValueHandler
Definition: BugReporterVisitors.cpp:2158
clang::ast_matchers::StatementMatcher
internal::Matcher< Stmt > StatementMatcher
Definition: ASTMatchers.h:142
clang::ento::PathDiagnosticLocation
Definition: PathDiagnostic.h:195
clang::CXXBoolLiteralExpr
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:721
clang::ento::ObjKind::CF
@ CF
Indicates that the tracked object is a CF object.
getSValForVar
static Optional< SVal > getSValForVar(const Expr *CondVarExpr, const ExplodedNode *N)
Definition: BugReporterVisitors.cpp:209
clang::ento::ExplodedNode::getLocationContext
const LocationContext * getLocationContext() const
Definition: ExplodedGraph.h:146
hasVisibleUpdate
static bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal, const ExplodedNode *RightNode, SVal RightVal)
Comparing internal representations of symbolic values (via SVal::operator==()) is a valid way to chec...
Definition: BugReporterVisitors.cpp:191
getConcreteIntegerValue
static Optional< const llvm::APSInt * > getConcreteIntegerValue(const Expr *CondVarExpr, const ExplodedNode *N)
Definition: BugReporterVisitors.cpp:234
clang::ento::CallEventRef
Definition: CallEvent.h:81
clang::LocationContext
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Definition: AnalysisDeclContext.h:215
clang::ento::bugreporter::StoreInfo
Describes an event when the value got stored into a memory region.
Definition: BugReporterVisitors.h:120
clang::LocationContext::getStackFrame
const StackFrameContext * getStackFrame() const
Definition: AnalysisDeclContext.cpp:463
SVals.h
clang::FullSourceLoc
A SourceLocation and its associated SourceManager.
Definition: SourceLocation.h:368
clang::ento::TrackConstraintBRVisitor::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
Definition: BugReporterVisitors.cpp:1649
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
Ret
static bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
Definition: Interp.cpp:34
clang::ento::NoteTag::isPrunable
bool isPrunable() const
Definition: BugReporter.h:798
clang::ast_matchers::stmt
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
Definition: ASTMatchersInternal.cpp:810
clang::ento::TagVisitor::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &R) override
Return a diagnostic piece which should be associated with the given node.
Definition: BugReporterVisitors.cpp:3332
clang::ento::PathDiagnosticPieceRef
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef
Definition: PathDiagnostic.h:492
isInterestingExpr
static bool isInterestingExpr(const Expr *E, const ExplodedNode *N, const PathSensitiveBugReport *B)
Definition: BugReporterVisitors.cpp:258
clang::ento::SVal::isUndef
bool isUndef() const
Definition: SVals.h:130
clang::QualType::isConstQualified
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6618
clang::CFGBlock::succ_size
unsigned succ_size() const
Definition: CFG.h:973
clang::ProgramPointTag
ProgramPoints can be "tagged" as representing points specific to a given analysis entity.
Definition: ProgramPoint.h:38
clang::CFGBlock::succ_begin
succ_iterator succ_begin()
Definition: CFG.h:955
clang::ento::NilReceiverBRVisitor::getNilReceiver
static const Expr * getNilReceiver(const Stmt *S, const ExplodedNode *N)
If the statement is a message send expression with nil receiver, returns the receiver expression.
Definition: BugReporterVisitors.cpp:2513
AnalysisDeclContext.h
llvm::SmallVector
Definition: LLVM.h:38
clang::ento::MemRegion::StripCasts
const LLVM_ATTRIBUTE_RETURNS_NONNULL MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
Definition: MemRegion.cpp:1323
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
peelOffOuterExpr
static const Expr * peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N)
Definition: BugReporterVisitors.cpp:1965
clang::Stmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:324
clang::ento::ProgramStateRef
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Definition: ProgramState_Fwd.h:37
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:731
clang::SrcMgr::ExpansionInfo::isFunctionMacroExpansion
bool isFunctionMacroExpansion() const
Definition: SourceManager.h:396
clang::ento::SVal::isZeroConstant
bool isZeroConstant() const
Definition: SVals.cpp:251
clang::ento::ExplodedNode::getStackFrame
const StackFrameContext * getStackFrame() const
Definition: ExplodedGraph.h:150
clang::QualType::getCanonicalType
QualType getCanonicalType() const
Definition: Type.h:6598
clang::FieldDecl
Represents a member of a struct/union/class.
Definition: Decl.h:2862
clang::ento::ExplodedNode
Definition: ExplodedGraph.h:65
DefaultStoreHandler
Definition: BugReporterVisitors.cpp:2064
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1680
ControlDependencyHandler
Definition: BugReporterVisitors.cpp:2094
DeclCXX.h
ProgramState_Fwd.h
clang::BinaryOperator::isAssignmentOp
bool isAssignmentOp() const
Definition: Expr.h:3945
clang::BinaryOperator::getOpcodeStr
StringRef getOpcodeStr() const
Definition: Expr.h:3872
StoreSiteFinder
Finds last store into the given region, which is different from a given symbolic value.
Definition: BugReporterVisitors.cpp:1201
clang::ento::ConditionBRVisitor::getTag
static const char * getTag()
Return the tag associated with this visitor.
Definition: BugReporterVisitors.cpp:2570
clang::ento::bugreporter::Tracker::Result
Describes a tracking result with the most basic information of what was actually done (or not done).
Definition: BugReporterVisitors.h:190
clang::ento::BugReporterVisitor::getEndPath
virtual PathDiagnosticPieceRef getEndPath(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR)
Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...
Definition: BugReporterVisitors.cpp:323
clang::ento::ConditionBRVisitor::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
Definition: BugReporterVisitors.cpp:2573
llvm::Optional
Definition: LLVM.h:40
clang::CFG::isLinear
bool isLinear() const
Returns true if the CFG has no branches.
Definition: CFG.cpp:5122
clang::ento::bugreporter::TrackingKind
TrackingKind
Specifies the type of tracking for an expression.
Definition: BugReporterVisitors.h:95
clang::Lexer::getSourceText
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Definition: Lexer.cpp:961
clang::Expr::isPRValue
bool isPRValue() const
Definition: Expr.h:271
clang::StackFrameContext
It represents a stack frame of the call stack (based on CallEvent).
Definition: AnalysisDeclContext.h:299
clang::prec::Assignment
@ Assignment
Definition: OperatorPrecedence.h:29
SourceManager.h
clang::Type::isVoidType
bool isVoidType() const
Definition: Type.h:7096
clang::ento::ConditionBRVisitor::printValue
bool printValue(const Expr *CondVarExpr, raw_ostream &Out, const ExplodedNode *N, bool TookTrue, bool IsAssuming)
Tries to print the value of the given expression.
Definition: BugReporterVisitors.cpp:3058
clang::tooling::X
static ToolExecutorPluginRegistry::Add< AllTUsToolExecutorPlugin > X("all-TUs", "Runs FrontendActions on all TUs in the compilation database. " "Tool results are stored in memory.")
ASTMatchFinder.h
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
clang::ento::FalsePositiveRefutationBRVisitor::FalsePositiveRefutationBRVisitor
FalsePositiveRefutationBRVisitor()
Definition: BugReporterVisitors.cpp:3249
clang::index::SymbolRole::Call
@ Call
clang::BinaryOperator::getOpcode
Opcode getOpcode() const
Definition: Expr.h:3851
clang::ento::SMTConv::getRangeExpr
static llvm::SMTExprRef getRangeExpr(llvm::SMTSolverRef &Solver, ASTContext &Ctx, SymbolRef Sym, const llvm::APSInt &From, const llvm::APSInt &To, bool InRange)
Definition: SMTConv.h:530
PRValueHandler
Attempts to add visitors to track an RValue expression back to its point of origin.
Definition: BugReporterVisitors.cpp:2387
clang::ento::CallEvent::isCallStmt
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
Definition: CallEvent.cpp:345
clang::ento::ProgramState
Definition: ProgramState.h:72
clang::Expr::IgnoreImpCasts
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:2932
clang::Expr::isGLValue
bool isGLValue() const
Definition: Expr.h:273
clang::SourceManager
This class handles loading and caching of source files into memory.
Definition: SourceManager.h:627
clang::ento::PathSensitiveBugReport::markInvalid
void markInvalid(const void *Tag, const void *Data)
Marks the current report as invalid, meaning that it is probably a false positive and should not be r...
Definition: BugReporter.h:481
clang::ObjCBoolLiteralExpr
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition: ExprObjC.h:88
showBRParamDiagnostics
static void showBRParamDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI)
Display diagnostics for passing bad region as a parameter.
Definition: BugReporterVisitors.cpp:1343
clang::ento::bugreporter::Tracker::track
virtual Result track(const Expr *E, const ExplodedNode *N, TrackingOptions Opts={})
Track expression value back to its point of origin.
Decl.h
CallEvent.h
clang::ento::NoStateChangeFuncVisitor
Put a diagnostic on return statement (or on } in its absence) of all inlined functions for which some...
Definition: BugReporterVisitors.h:639
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:95
wasRegionOfInterestModifiedAt
static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest, const ExplodedNode *N, SVal ValueAfter)
Definition: BugReporterVisitors.cpp:291
clang::CFGBlock
Represents a single basic block in a source-level CFG.
Definition: CFG.h:576
clang::ento::NoteTag::generateMessage
Optional< std::string > generateMessage(BugReporterContext &BRC, PathSensitiveBugReport &R) const
Definition: BugReporter.h:782
clang::ento::bugreporter::Tracker::handle
virtual PathDiagnosticPieceRef handle(StoreInfo SI, BugReporterContext &BRC, TrackingOptions Opts)
Handle the store operation and produce the note.
Definition: BugReporterVisitors.cpp:2480
U
clang::StackFrameContext::inTopFrame
bool inTopFrame() const override
Definition: AnalysisDeclContext.h:329
clang::ento::MemRegionManager::getFieldRegion
const FieldRegion * getFieldRegion(const FieldDecl *fd, const SubRegion *superRegion)
getFieldRegion - Retrieve or create the memory region associated with a specified FieldDecl.
Definition: MemRegion.cpp:1161
clang::ento::TrackConstraintBRVisitor::getTag
static const char * getTag()
Return the tag associated with this visitor.
Definition: BugReporterVisitors.cpp:1639
clang::Type::isReferenceType
bool isReferenceType() const
Definition: Type.h:6819
clang::syntax::NodeRole::Parameters
@ Parameters
V
#define V(N, I)
Definition: ASTContext.h:3176
clang::IntegerLiteral
Definition: Expr.h:1494
clang::ento::ExplodedNode::getState
const ProgramStateRef & getState() const
Definition: ExplodedGraph.h:168
clang::ento::DefinedSVal
Definition: SVals.h:239
ProgramPoint.h
clang::ento::TrackConstraintBRVisitor::Profile
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: BugReporterVisitors.cpp:1630
clang::FloatingLiteral
Definition: Expr.h:1639
TrackingBugReporterVisitor
clang::ast_matchers::objcIvarRefExpr
const internal::VariadicDynCastAllOfMatcher< Stmt, ObjCIvarRefExpr > objcIvarRefExpr
Matches a reference to an ObjCIvar.
Definition: ASTMatchersInternal.cpp:892
InlinedFunctionCallHandler
Adds a ReturnVisitor if the given statement represents a call that was inlined.
Definition: BugReporterVisitors.cpp:2241
clang::ento::Range
A Range represents the closed range [from, to].
Definition: RangedConstraintManager.h:29
clang::ento::ConstraintMap
llvm::ImmutableMap< SymbolRef, RangeSet > ConstraintMap
Definition: RangedConstraintManager.h:404
isVarAnInterestingCondition
static bool isVarAnInterestingCondition(const Expr *CondVarExpr, const ExplodedNode *N, const PathSensitiveBugReport *B)
Definition: BugReporterVisitors.cpp:242
clang::StmtPoint
Definition: ProgramPoint.h:270
clang::BinaryOperator
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3807
clang::SrcMgr::ExpansionInfo
Each ExpansionInfo encodes the expansion location - where the token was ultimately expanded,...
Definition: SourceManager.h:348
DeclBase.h
clang::ento::PathDiagnosticLocation::create
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
Definition: PathDiagnostic.h:248
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
clang::ento::bugreporter::TrackingOptions
Defines a set of options altering tracking behavior.
Definition: BugReporterVisitors.h:107
clang::ento::SuppressInlineDefensiveChecksVisitor::SuppressInlineDefensiveChecksVisitor
SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N)
Definition: BugReporterVisitors.cpp:1714
clang::ento::BugReporterContext::getSourceManager
const SourceManager & getSourceManager() const
Definition: BugReporter.h:721
BugReporter.h
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:208
clang::ProgramPoint::getAs
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Definition: ProgramPoint.h:150
clang::ento::SymExpr
Symbolic value.
Definition: SymExpr.h:29
clang::ProgramPoint::getTag
const ProgramPointTag * getTag() const
Definition: ProgramPoint.h:176
clang::ento::PathDiagnosticLocation::isValid
bool isValid() const
Definition: PathDiagnostic.h:335
clang::CallExitEnd
Represents a point when we finish the call exit sequence (for inlined call).
Definition: ProgramPoint.h:687
clang::ento::PathSensitiveBugReport::getErrorNode
const ExplodedNode * getErrorNode() const
Definition: BugReporter.h:402
clang::ento::FalsePositiveRefutationBRVisitor::finalizeVisitor
void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR) override
Last function called on the visitor, no further calls to VisitNode would follow.
Definition: BugReporterVisitors.cpp:3252
clang::ento::ConditionBRVisitor::VisitTerminator
PathDiagnosticPieceRef VisitTerminator(const Stmt *Term, const ExplodedNode *N, const CFGBlock *SrcBlk, const CFGBlock *DstBlk, PathSensitiveBugReport &R, BugReporterContext &BRC)
Definition: BugReporterVisitors.cpp:2623
clang::ento::bugreporter::TrackingKind::Condition
@ Condition
Specifies that a more moderate tracking should be used for the expression value.
clang::LocationContext::isParentOf
bool isParentOf(const LocationContext *LC) const
Definition: AnalysisDeclContext.cpp:477
SMTConv.h
clang::ento::BugReporterContext::getAnalyzerOptions
const AnalyzerOptions & getAnalyzerOptions() const
Definition: BugReporter.h:725
getMatchingCallExitEnd
static const ExplodedNode * getMatchingCallExitEnd(const ExplodedNode *N)
Definition: BugReporterVisitors.cpp:373
clang::CFGBlock::getLastCondition
const Expr * getLastCondition() const
Definition: CFG.cpp:6091
clang::PostStore
Represents a program point after a store evaluation.
Definition: ProgramPoint.h:430
clang::ento::MemRegion::isSubRegionOf
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
Definition: MemRegion.cpp:1315
clang::CFGStmtMap::getBlock
CFGBlock * getBlock(Stmt *S)
Returns the CFGBlock the specified Stmt* appears in.
Definition: CFGStmtMap.cpp:26
StoreHandler
clang::ento::BugReporterVisitor::finalizeVisitor
virtual void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR)
Last function called on the visitor, no further calls to VisitNode would follow.
Definition: BugReporterVisitors.cpp:329
clang::Stmt::getEndLoc
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:348
clang::isa
bool isa(CodeGen::Address addr)
Definition: Address.h:177
IdentifierTable.h
clang::ento::TagVisitor::Profile
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: BugReporterVisitors.cpp:3327
clang::DeclRefExpr::getDecl
ValueDecl * getDecl()
Definition: Expr.h:1295
clang::ento::SuppressInlineDefensiveChecksVisitor::Profile
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: BugReporterVisitors.cpp:1722
Type.h
clang::PD_NONE
@ PD_NONE
Definition: AnalyzerOptions.h:48
Expr.h
llvm::SmallString
Definition: LLVM.h:37
ASTContext.h
clang::ento::bugreporter::StoreInfo::Initialization
@ Initialization
The value got stored into the region during initialization: int x = 42;.
Definition: BugReporterVisitors.h:124
clang::StmtPoint::getStmt
const Stmt * getStmt() const
Definition: ProgramPoint.h:278
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::ento::bugreporter::TrackingKind::Thorough
@ Thorough
Default tracking kind – specifies that as much information should be gathered about the tracked expre...
clang::PostInitializer
Definition: ProgramPoint.h:526
clang::MemberExpr::getMemberLoc
SourceLocation getMemberLoc() const
getMemberLoc - Return the location of the "member", in X->F, it is the location of 'F'.
Definition: Expr.h:3353
clang::ento::BugReporterContext
Definition: BugReporter.h:701
clang::ast_matchers::binaryOperator
const internal::VariadicDynCastAllOfMatcher< Stmt, BinaryOperator > binaryOperator
Matches binary operator expressions.
Definition: ASTMatchersInternal.cpp:947
WillBeUsedForACondition
static llvm::StringLiteral WillBeUsedForACondition
Definition: BugReporterVisitors.cpp:757
isInitializationOfVar
static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR)
Returns true if N represents the DeclStmt declaring and initializing VR.
Definition: BugReporterVisitors.cpp:1246
PathDiagnostic.h
clang::AnalysisDeclContext::isInStdNamespace
static bool isInStdNamespace(const Decl *D)
Definition: AnalysisDeclContext.cpp:325
clang::ento::FalsePositiveRefutationBRVisitor::Profile
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: BugReporterVisitors.cpp:3315
ExprObjC.h
clang::Lexer::getImmediateMacroName
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
Definition: Lexer.cpp:997
ExprCXX.h
Base
clang::ento::SuppressInlineDefensiveChecksVisitor::getTag
static const char * getTag()
Return the tag associated with this visitor.
Definition: BugReporterVisitors.cpp:1729
clang::CFGBlock::getTerminatorCondition
Stmt * getTerminatorCondition(bool StripParens=true)
Definition: CFG.cpp:6119
clang::ento::PathDiagnosticPiece::getString
StringRef getString() const
Definition: PathDiagnostic.h:436
clang::CFGStmtMap
Definition: CFGStmtMap.h:24
clang::ento::CallEventManager::getCaller
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
Gets an outside caller given a callee context.
Definition: CallEvent.cpp:1360
clang::ento::KnownSVal
Represents an SVal that is guaranteed to not be UnknownVal.
Definition: SVals.h:255
x
IRgen optimization opportunities The common pattern of short x
Definition: README.txt:7
ExpressionHandler
ExplodedGraph.h
DefaultExpressionHandler
Definition: BugReporterVisitors.cpp:2324
clang::MemberExpr::getMemberDecl
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:3247
state
and static some checkers Checker The latter are built on top of the former via the Checker and CheckerVisitor and attempts to isolate them from much of the gore of the internal analysis the analyzer is basically a source code simulator that traces out possible paths of execution The state of the and the combination of state and program point is a node in an exploded which has the entry program point and initial state
Definition: README.txt:30
CFGStmtMap.h
clang::ento::Loc
Definition: SVals.h:278
getMacroName
static StringRef getMacroName(SourceLocation Loc, BugReporterContext &BRC)
Definition: BugReporterVisitors.cpp:266
clang::ento::ExprEngine::geteagerlyAssumeBinOpBifurcationTags
static std::pair< const ProgramPointTag *, const ProgramPointTag * > geteagerlyAssumeBinOpBifurcationTags()
Definition: ExprEngine.cpp:3157
NilReceiverHandler
Definition: BugReporterVisitors.cpp:2122
clang::Type::isObjCObjectPointerType
bool isObjCObjectPointerType() const
Definition: Type.h:6935
clang::ento::NilReceiverBRVisitor::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
Definition: BugReporterVisitors.cpp:2528
constructDebugPieceForTrackedCondition
static std::shared_ptr< PathDiagnosticEventPiece > constructDebugPieceForTrackedCondition(const Expr *Cond, const ExplodedNode *N, BugReporterContext &BRC)
Definition: BugReporterVisitors.cpp:1844
clang::LocationContext::getAnalysisDeclContext
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
Definition: AnalysisDeclContext.h:244
clang::LocationContext::getParent
const LocationContext * getParent() const
It might return null.
Definition: AnalysisDeclContext.h:247
clang::ento::bugreporter::trackExpressionValue
bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts={})
Attempts to add visitors to track expression value back to its point of origin.
clang::ento::ExplodedGraph::isInterestingLValueExpr
static bool isInterestingLValueExpr(const Expr *Ex)
Returns true if nodes for the given expression kind are always kept around.
Definition: ExplodedGraph.cpp:50
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:2957
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::PostStmt
Definition: ProgramPoint.h:310
clang::SrcMgr::SLocEntry::getExpansion
const ExpansionInfo & getExpansion() const
Definition: SourceManager.h:490
clang::ento::bugreporter::getDerefExpr
const Expr * getDerefExpr(const Stmt *S)
SourceLocation.h
clang::DeclStmt::getSingleDecl
const Decl * getSingleDecl() const
Definition: Stmt.h:1309
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::PreStmt
Definition: ProgramPoint.h:294
clang::ento::CallEventManager
Manages the lifetime of CallEvent objects.
Definition: CallEvent.h:1233
clang::Stmt::getStmtClass
StmtClass getStmtClass() const
Definition: Stmt.h:1160
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6807
clang::ento::PathSensitiveBugReport::getRanges
ArrayRef< SourceRange > getRanges() const override
Get the SourceRanges associated with the report.
Definition: BugReporter.cpp:2402
clang::ento::FalsePositiveRefutationBRVisitor::addConstraints
void addConstraints(const ExplodedNode *N, bool OverwriteConstraintsOnExistingSyms)
Definition: BugReporterVisitors.cpp:3289
clang::ento::DefinedSVal::isValid
bool isValid() const =delete
SValBuilder.h
clang::ento::NoStateChangeFuncVisitor::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BR, PathSensitiveBugReport &R) override final
Return a diagnostic piece which should be associated with the given node.
Definition: BugReporterVisitors.cpp:440
clang::ValueDecl
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:674
clang::ento::ProgramStateManager::getCallEventManager
CallEventManager & getCallEventManager()
Definition: ProgramState.h:577
isPointerToConst
static bool isPointerToConst(QualType Ty)
Definition: BugReporterVisitors.cpp:708
clang::BinaryOperator::getLHS
Expr * getLHS() const
Definition: Expr.h:3856
clang::ento::ConditionBRVisitor::isPieceMessageGeneric
static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece)
Definition: BugReporterVisitors.cpp:3098
clang::CharSourceRange::getTokenRange
static CharSourceRange getTokenRange(SourceRange R)
Definition: SourceLocation.h:261
clang::DeclContext::getParent
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1882
clang::RecordDecl::fields
field_range fields() const
Definition: Decl.h:4134
showBRDiagnostics
static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI)
Show diagnostics for initializing or declaring a region R with a bad value.
Definition: BugReporterVisitors.cpp:1286
potentiallyWritesIntoIvar
static bool potentiallyWritesIntoIvar(const Decl *Parent, const ObjCIvarDecl *Ivar)
Definition: BugReporterVisitors.cpp:589
clang::ento::ExplodedNode::getFirstPred
ExplodedNode * getFirstPred()
Definition: ExplodedGraph.h:208
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:796
llvm::ArrayRef
Definition: LLVM.h:34
Lexer.h
Value
Value
Definition: UninitializedValues.cpp:102
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::BinaryOperator::isComparisonOp
bool isComparisonOp() const
Definition: Expr.h:3907
BugReporterVisitors.h
clang::CFGBlock::isInevitablySinking
bool isInevitablySinking() const
Returns true if the block would eventually end with a sink (a noreturn node).
Definition: CFG.cpp:6053
clang::StackFrameContext::getCallSite
const Stmt * getCallSite() const
Definition: AnalysisDeclContext.h:325
clang::CharSourceRange
Represents a character-granular source range.
Definition: SourceLocation.h:253
clang::ento::bugreporter::trackStoredValue
void trackStoredValue(KnownSVal V, const MemRegion *R, PathSensitiveBugReport &Report, TrackingOptions Opts={}, const StackFrameContext *Origin=nullptr)
Track how the value got stored into the given region and where it came from.
clang::ento::PathDiagnosticLocation::asLocation
FullSourceLoc asLocation() const
Definition: PathDiagnostic.h:339
isObjCPointer
static bool isObjCPointer(const MemRegion *R)
Definition: BugReporterVisitors.cpp:1273
clang::ento::bugreporter::Tracker::create
static TrackerRef create(PathSensitiveBugReport &Report)
Definition: BugReporterVisitors.h:182
LLVM.h
getLocationRegionIfReference
static const MemRegion * getLocationRegionIfReference(const Expr *E, const ExplodedNode *N, bool LookingForReference=true)
Definition: BugReporterVisitors.cpp:162
clang::AnalyzerOptions
Stores options for the analyzer from the command line.
Definition: AnalyzerOptions.h:151
clang::Type::getAsRecordDecl
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition: Type.cpp:1763
State
LineState State
Definition: UnwrappedLineFormatter.cpp:1126
clang::ento::ConditionBRVisitor::patternMatch
bool patternMatch(const Expr *Ex, const Expr *ParentEx, raw_ostream &Out, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, Optional< bool > &prunable, bool IsSameFieldName)
Definition: BugReporterVisitors.cpp:2750
clang::ast_matchers::hasDescendant
const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher.
Definition: ASTMatchersInternal.cpp:1010
clang::ImplicitParamDecl::ObjCSelf
@ ObjCSelf
Parameter for Objective-C 'self' argument.
Definition: Decl.h:1622
clang::BinaryOperatorKind
BinaryOperatorKind
Definition: OperationKinds.h:25
clang::ento::ConditionBRVisitor::VisitTrueTest
PathDiagnosticPieceRef VisitTrueTest(const Expr *Cond, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue)
Definition: BugReporterVisitors.cpp:2682
clang::SourceLocation::isMacroID
bool isMacroID() const
Definition: SourceLocation.h:103
clang::NamedDecl::getNameAsString
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Definition: Decl.h:290
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::Type::isBooleanType
bool isBooleanType() const
Definition: Type.h:7212
isAssertlikeBlock
static bool isAssertlikeBlock(const CFGBlock *B, ASTContext &Context)
Definition: BugReporterVisitors.cpp:1862
clang::DeclStmt
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1294
ProgramState.h
clang::ento::BugReport::getDescription
StringRef getDescription() const
A verbose warning message that is appropriate for displaying next to the source code that introduces ...
Definition: BugReporter.h:157
clang::ento::MemRegionManager
Definition: MemRegion.h:1341
ArrayIndexHandler
Definition: BugReporterVisitors.cpp:2140
clang::ento::PathSensitiveBugReport
Definition: BugReporter.h:289
clang::ento::UndefOrNullArgVisitor::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
Definition: BugReporterVisitors.cpp:3196
ExprEngine.h
findNodeForExpression
static const ExplodedNode * findNodeForExpression(const ExplodedNode *N, const Expr *Inner)
Find the ExplodedNode where the lvalue (the value of 'Ex') was computed.
Definition: BugReporterVisitors.cpp:2031
clang::ento::bugreporter::TrackerRef
llvm::IntrusiveRefCntPtr< Tracker > TrackerRef
Definition: BugReporterVisitors.h:156
StoreSiteFinder::StoreSiteFinder
StoreSiteFinder(bugreporter::TrackerRef ParentTracker, KnownSVal V, const MemRegion *R, TrackingOptions Options, const StackFrameContext *OriginSFC=nullptr)
Definition: BugReporterVisitors.cpp:1220
clang::Builtin::ID
ID
Definition: Builtins.h:52
DefaultStoreHandler::handle
PathDiagnosticPieceRef handle(StoreInfo SI, BugReporterContext &BRC, TrackingOptions Opts) override
Definition: BugReporterVisitors.cpp:2068
clang::Expr::IgnoreParens
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:2948
clang::ento::bugreporter::StoreInfo::Assignment
@ Assignment
The value got stored into the region during assignment: int x; x = 42;.
Definition: BugReporterVisitors.h:128
clang::ento::BugReporterVisitor::getDefaultEndPath
static PathDiagnosticPieceRef getDefaultEndPath(const BugReporterContext &BRC, const ExplodedNode *N, const PathSensitiveBugReport &BR)
Generates the default final diagnostic piece.
Definition: BugReporterVisitors.cpp:334
clang
Definition: CalledOnceCheck.h:17
clang::Type::isAnyPointerType
bool isAnyPointerType() const
Definition: Type.h:6811
clang::Lexer::isAtStartOfMacroExpansion
static bool isAtStartOfMacroExpansion(SourceLocation loc, const SourceManager &SM, const LangOptions &LangOpts, SourceLocation *MacroBegin=nullptr)
Returns true if the given MacroID location points at the first token of the macro expansion.
Definition: Lexer.cpp:809
StoreSiteFinder::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Definition: BugReporterVisitors.cpp:1416
clang::ento::ExplodedNode::getLocation
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
Definition: ExplodedGraph.h:144
CFG.h
clang::ento::ExplodedNode::getLocationAs
Optional< T > getLocationAs() const &
Definition: ExplodedGraph.h:170
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:69
clang::ObjCIvarDecl
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1923
clang::ento::bugreporter::StoreInfo::SourceOfTheValue
const Expr * SourceOfTheValue
The expression where the value comes from.
Definition: BugReporterVisitors.h:145
clang::BinaryOperator::getRHS
Expr * getRHS() const
Definition: Expr.h:3858
clang::ento::bugreporter::StoreInfo::BlockCapture
@ BlockCapture
The value got stored into the region as block capture.
Definition: BugReporterVisitors.h:136
clang::ast_matchers::match
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
Definition: ASTMatchFinder.h:312
clang::ento::PathDiagnosticPiece
Definition: PathDiagnostic.h:403
clang::CFGBlock::getTerminatorStmt
Stmt * getTerminatorStmt()
Definition: CFG.h:1050
clang::ento::ConditionBRVisitor::VisitConditionVariable
PathDiagnosticPieceRef VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr, BugReporterContext &BRC, PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue)
Definition: BugReporterVisitors.cpp:2957
MemRegion.h
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::ento::bugreporter::StoreInfo::StoreSite
const ExplodedNode * StoreSite
The node where the store happened.
Definition: BugReporterVisitors.h:142
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:110
clang::ento::PathDiagnosticLocation::createBegin
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
Definition: PathDiagnostic.cpp:580
clang::ento::ExplodedNode::getSVal
SVal getSVal(const Stmt *S) const
Get the value of an arbitrary expression at this node.
Definition: ExplodedGraph.h:175
clang::ControlDependencyCalculator
Definition: Dominators.h:215
clang::ento::PathSensitiveBugReport::markInteresting
void markInteresting(SymbolRef sym, bugreporter::TrackingKind TKind=bugreporter::TrackingKind::Thorough)
Marks a symbol as interesting.
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
peelOffPointerArithmetic
static const Expr * peelOffPointerArithmetic(const BinaryOperator *B)
Definition: BugReporterVisitors.cpp:74
isFunctionMacroExpansion
static bool isFunctionMacroExpansion(SourceLocation Loc, const SourceManager &SM)
Definition: BugReporterVisitors.cpp:276
clang::CallEnter
Represents a point when we begin processing an inlined call.
Definition: ProgramPoint.h:629
Dominators.h
clang::MemberExpr
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:3164
clang::BlockEdge
Definition: ProgramPoint.h:502
clang::ast_matchers::BoundNodes
Maps string IDs to AST nodes matched by parts of a matcher.
Definition: ASTMatchers.h:107
clang::ento::PathSensitiveBugReport::isInteresting
bool isInteresting(SymbolRef sym) const
Definition: BugReporter.cpp:2369
clang::ento::SVal
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
Definition: SVals.h:74
clang::ento::ConditionBRVisitor::VisitNodeImpl
PathDiagnosticPieceRef VisitNodeImpl(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR)
Definition: BugReporterVisitors.cpp:2585
Parent
NodeId Parent
Definition: ASTDiff.cpp:192
StoreSiteFinder::Profile
void Profile(llvm::FoldingSetNodeID &ID) const override
Definition: BugReporterVisitors.cpp:1235
clang::LocationContext::getCFG
CFG * getCFG() const
Definition: AnalysisDeclContext.h:253
Stmt.h
clang::GNUNullExpr
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition: Expr.h:4599
clang::ento::SubRegion
SubRegion - A region that subsets another larger region.
Definition: MemRegion.h:442
clang::BinaryOperator::isAdditiveOp
static bool isAdditiveOp(Opcode Opc)
Definition: Expr.h:3892
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:685
clang::Expr
This represents one expression.
Definition: Expr.h:109
SM
#define SM(sm)
Definition: Cuda.cpp:81
clang::ento::SuppressInlineDefensiveChecksVisitor::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *Succ, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
Definition: BugReporterVisitors.cpp:1734
clang::ento::bugreporter::StoreInfo::CallArgument
@ CallArgument
The value got stored into the parameter region as the result of a call.
Definition: BugReporterVisitors.h:131
clang::ento::BugReporterContext::getASTContext
ASTContext & getASTContext() const
Definition: BugReporter.h:717
clang::ast_matchers::hasDeclaration
internal::PolymorphicMatcher< internal::HasDeclarationMatcher, void(internal::HasDeclarationSupportedTypes), internal::Matcher< Decl > > hasDeclaration(const internal::Matcher< Decl > &InnerMatcher)
Matches a node if the declaration associated with that node matches the given matcher.
Definition: ASTMatchers.h:3565
AnalysisManager.h
clang::ento::NoteTag
The tag upon which the TagVisitor reacts.
Definition: BugReporter.h:763
clang::ento::PathSensitiveBugReport::getLocation
PathDiagnosticLocation getLocation() const override
The primary location of the bug report that points at the undesirable behavior in the code.
Definition: BugReporter.cpp:2412
clang::ento::BugReporterContext::getStateManager
ProgramStateManager & getStateManager() const
Definition: BugReporter.h:713
clang::DeclRefExpr
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1223
clang::LocationContext::getDecl
const Decl * getDecl() const
Definition: AnalysisDeclContext.h:251
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3908
clang::ProgramPoint
Definition: ProgramPoint.h:58
clang::ObjCIvarRefExpr
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:548
clang::ento::getConstraintMap
ConstraintMap getConstraintMap(ProgramStateRef State)
Definition: RangeConstraintManager.cpp:2178
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:786
showBRDefaultDiagnostics
static void showBRDefaultDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI)
Show default diagnostics for storing bad region.
Definition: BugReporterVisitors.cpp:1377
llvm::IntrusiveRefCntPtr< const ProgramState >
clang::Type::isIntegralOrEnumerationType
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:7199
clang::ento::ObjKind::OS
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
clang::ento::LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor
void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *N, PathSensitiveBugReport &BR) override
Last function called on the visitor, no further calls to VisitNode would follow.
Definition: BugReporterVisitors.cpp:3108
clang::ento::FalsePositiveRefutationBRVisitor::VisitNode
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
Definition: BugReporterVisitors.cpp:3309
clang::SrcMgr::SLocEntry
This is a discriminated union of FileInfo and ExpansionInfo.
Definition: SourceManager.h:468
clang::Lexer::getAsCharRange
static CharSourceRange getAsCharRange(SourceRange Range, const SourceManager &SM, const LangOptions &LangOpts)
Given a token range, produce a corresponding CharSourceRange that is not a token range.
Definition: Lexer.h:430
clang::NamedDecl::getName
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274