clang  6.0.0
BugReporter.cpp
Go to the documentation of this file.
1 // BugReporter.cpp - Generate PathDiagnostics for Bugs ------------*- C++ -*--//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines BugReporter, a utility class for generating
11 // PathDiagnostics.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/ParentMap.h"
21 #include "clang/AST/StmtCXX.h"
22 #include "clang/AST/StmtObjC.h"
23 #include "clang/Analysis/CFG.h"
30 #include "llvm/ADT/DenseMap.h"
31 #include "llvm/ADT/IntrusiveRefCntPtr.h"
32 #include "llvm/ADT/STLExtras.h"
33 #include "llvm/ADT/SmallString.h"
34 #include "llvm/ADT/Statistic.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include <memory>
37 #include <queue>
38 
39 using namespace clang;
40 using namespace ento;
41 
42 #define DEBUG_TYPE "BugReporter"
43 
44 STATISTIC(MaxBugClassSize,
45  "The maximum number of bug reports in the same equivalence class");
46 STATISTIC(MaxValidBugClassSize,
47  "The maximum number of bug reports in the same equivalence class "
48  "where at least one report is valid (not suppressed)");
49 
51 
52 void BugReporterContext::anchor() {}
53 
54 //===----------------------------------------------------------------------===//
55 // Helper routines for walking the ExplodedGraph and fetching statements.
56 //===----------------------------------------------------------------------===//
57 
58 static const Stmt *GetPreviousStmt(const ExplodedNode *N) {
59  for (N = N->getFirstPred(); N; N = N->getFirstPred())
60  if (const Stmt *S = PathDiagnosticLocation::getStmt(N))
61  return S;
62 
63  return nullptr;
64 }
65 
66 static inline const Stmt*
68  if (const Stmt *S = PathDiagnosticLocation::getStmt(N))
69  return S;
70 
71  return GetPreviousStmt(N);
72 }
73 
74 //===----------------------------------------------------------------------===//
75 // Diagnostic cleanup.
76 //===----------------------------------------------------------------------===//
77 
81  // Prefer diagnostics that come from ConditionBRVisitor over
82  // those that came from TrackConstraintBRVisitor,
83  // unless the one from ConditionBRVisitor is
84  // its generic fallback diagnostic.
85  const void *tagPreferred = ConditionBRVisitor::getTag();
86  const void *tagLesser = TrackConstraintBRVisitor::getTag();
87 
88  if (X->getLocation() != Y->getLocation())
89  return nullptr;
90 
91  if (X->getTag() == tagPreferred && Y->getTag() == tagLesser)
93 
94  if (Y->getTag() == tagPreferred && X->getTag() == tagLesser)
96 
97  return nullptr;
98 }
99 
100 /// An optimization pass over PathPieces that removes redundant diagnostics
101 /// generated by both ConditionBRVisitor and TrackConstraintBRVisitor. Both
102 /// BugReporterVisitors use different methods to generate diagnostics, with
103 /// one capable of emitting diagnostics in some cases but not in others. This
104 /// can lead to redundant diagnostic pieces at the same point in a path.
105 static void removeRedundantMsgs(PathPieces &path) {
106  unsigned N = path.size();
107  if (N < 2)
108  return;
109  // NOTE: this loop intentionally is not using an iterator. Instead, we
110  // are streaming the path and modifying it in place. This is done by
111  // grabbing the front, processing it, and if we decide to keep it append
112  // it to the end of the path. The entire path is processed in this way.
113  for (unsigned i = 0; i < N; ++i) {
114  auto piece = std::move(path.front());
115  path.pop_front();
116 
117  switch (piece->getKind()) {
119  removeRedundantMsgs(cast<PathDiagnosticCallPiece>(*piece).path);
120  break;
122  removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(*piece).subPieces);
123  break;
125  break;
127  if (i == N-1)
128  break;
129 
130  if (PathDiagnosticEventPiece *nextEvent =
131  dyn_cast<PathDiagnosticEventPiece>(path.front().get())) {
132  PathDiagnosticEventPiece *event =
133  cast<PathDiagnosticEventPiece>(piece.get());
134  // Check to see if we should keep one of the two pieces. If we
135  // come up with a preference, record which piece to keep, and consume
136  // another piece from the path.
137  if (auto *pieceToKeep =
138  eventsDescribeSameCondition(event, nextEvent)) {
139  piece = std::move(pieceToKeep == event ? piece : path.front());
140  path.pop_front();
141  ++i;
142  }
143  }
144  break;
145  }
147  break;
148  }
149  path.push_back(std::move(piece));
150  }
151 }
152 
153 /// A map from PathDiagnosticPiece to the LocationContext of the inlined
154 /// function call it represents.
155 typedef llvm::DenseMap<const PathPieces *, const LocationContext *>
157 
158 /// Recursively scan through a path and prune out calls and macros pieces
159 /// that aren't needed. Return true if afterwards the path contains
160 /// "interesting stuff" which means it shouldn't be pruned from the parent path.
161 static bool removeUnneededCalls(PathPieces &pieces, BugReport *R,
162  LocationContextMap &LCM) {
163  bool containsSomethingInteresting = false;
164  const unsigned N = pieces.size();
165 
166  for (unsigned i = 0 ; i < N ; ++i) {
167  // Remove the front piece from the path. If it is still something we
168  // want to keep once we are done, we will push it back on the end.
169  auto piece = std::move(pieces.front());
170  pieces.pop_front();
171 
172  switch (piece->getKind()) {
174  auto &call = cast<PathDiagnosticCallPiece>(*piece);
175  // Check if the location context is interesting.
176  assert(LCM.count(&call.path));
177  if (R->isInteresting(LCM[&call.path])) {
178  containsSomethingInteresting = true;
179  break;
180  }
181 
182  if (!removeUnneededCalls(call.path, R, LCM))
183  continue;
184 
185  containsSomethingInteresting = true;
186  break;
187  }
189  auto &macro = cast<PathDiagnosticMacroPiece>(*piece);
190  if (!removeUnneededCalls(macro.subPieces, R, LCM))
191  continue;
192  containsSomethingInteresting = true;
193  break;
194  }
196  auto &event = cast<PathDiagnosticEventPiece>(*piece);
197 
198  // We never throw away an event, but we do throw it away wholesale
199  // as part of a path if we throw the entire path away.
200  containsSomethingInteresting |= !event.isPrunable();
201  break;
202  }
204  break;
205 
207  break;
208  }
209 
210  pieces.push_back(std::move(piece));
211  }
212 
213  return containsSomethingInteresting;
214 }
215 
216 /// Returns true if the given decl has been implicitly given a body, either by
217 /// the analyzer or by the compiler proper.
218 static bool hasImplicitBody(const Decl *D) {
219  assert(D);
220  return D->isImplicit() || !D->hasBody();
221 }
222 
223 /// Recursively scan through a path and make sure that all call pieces have
224 /// valid locations.
225 static void
227  PathDiagnosticLocation *LastCallLocation = nullptr) {
228  for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E; ++I) {
229  PathDiagnosticCallPiece *Call = dyn_cast<PathDiagnosticCallPiece>(I->get());
230 
231  if (!Call) {
232  continue;
233  }
234 
235  if (LastCallLocation) {
236  bool CallerIsImplicit = hasImplicitBody(Call->getCaller());
237  if (CallerIsImplicit || !Call->callEnter.asLocation().isValid())
238  Call->callEnter = *LastCallLocation;
239  if (CallerIsImplicit || !Call->callReturn.asLocation().isValid())
240  Call->callReturn = *LastCallLocation;
241  }
242 
243  // Recursively clean out the subclass. Keep this call around if
244  // it contains any informative diagnostics.
245  PathDiagnosticLocation *ThisCallLocation;
246  if (Call->callEnterWithin.asLocation().isValid() &&
247  !hasImplicitBody(Call->getCallee()))
248  ThisCallLocation = &Call->callEnterWithin;
249  else
250  ThisCallLocation = &Call->callEnter;
251 
252  assert(ThisCallLocation && "Outermost call has an invalid location");
253  adjustCallLocations(Call->path, ThisCallLocation);
254  }
255 }
256 
257 /// Remove edges in and out of C++ default initializer expressions. These are
258 /// for fields that have in-class initializers, as opposed to being initialized
259 /// explicitly in a constructor or braced list.
261  for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) {
262  if (auto *C = dyn_cast<PathDiagnosticCallPiece>(I->get()))
264 
265  if (auto *M = dyn_cast<PathDiagnosticMacroPiece>(I->get()))
266  removeEdgesToDefaultInitializers(M->subPieces);
267 
268  if (auto *CF = dyn_cast<PathDiagnosticControlFlowPiece>(I->get())) {
269  const Stmt *Start = CF->getStartLocation().asStmt();
270  const Stmt *End = CF->getEndLocation().asStmt();
271  if (Start && isa<CXXDefaultInitExpr>(Start)) {
272  I = Pieces.erase(I);
273  continue;
274  } else if (End && isa<CXXDefaultInitExpr>(End)) {
275  PathPieces::iterator Next = std::next(I);
276  if (Next != E) {
277  if (auto *NextCF =
278  dyn_cast<PathDiagnosticControlFlowPiece>(Next->get())) {
279  NextCF->setStartLocation(CF->getStartLocation());
280  }
281  }
282  I = Pieces.erase(I);
283  continue;
284  }
285  }
286 
287  I++;
288  }
289 }
290 
291 /// Remove all pieces with invalid locations as these cannot be serialized.
292 /// We might have pieces with invalid locations as a result of inlining Body
293 /// Farm generated functions.
295  for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) {
296  if (auto *C = dyn_cast<PathDiagnosticCallPiece>(I->get()))
298 
299  if (auto *M = dyn_cast<PathDiagnosticMacroPiece>(I->get()))
300  removePiecesWithInvalidLocations(M->subPieces);
301 
302  if (!(*I)->getLocation().isValid() ||
303  !(*I)->getLocation().asLocation().isValid()) {
304  I = Pieces.erase(I);
305  continue;
306  }
307  I++;
308  }
309 }
310 
311 //===----------------------------------------------------------------------===//
312 // PathDiagnosticBuilder and its associated routines and helper objects.
313 //===----------------------------------------------------------------------===//
314 
315 namespace {
316 class NodeMapClosure : public BugReport::NodeResolver {
318 public:
319  NodeMapClosure(InterExplodedGraphMap &m) : M(m) {}
320 
321  const ExplodedNode *getOriginalNode(const ExplodedNode *N) override {
322  return M.lookup(N);
323  }
324 };
325 
326 class PathDiagnosticBuilder : public BugReporterContext {
327  BugReport *R;
329  NodeMapClosure NMC;
330 public:
331  const LocationContext *LC;
332 
333  PathDiagnosticBuilder(GRBugReporter &br,
334  BugReport *r, InterExplodedGraphMap &Backmap,
336  : BugReporterContext(br),
337  R(r), PDC(pdc), NMC(Backmap), LC(r->getErrorNode()->getLocationContext())
338  {}
339 
340  PathDiagnosticLocation ExecutionContinues(const ExplodedNode *N);
341 
342  PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream &os,
343  const ExplodedNode *N);
344 
345  BugReport *getBugReport() { return R; }
346 
347  Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); }
348 
349  ParentMap& getParentMap() { return LC->getParentMap(); }
350 
351  const Stmt *getParent(const Stmt *S) {
352  return getParentMap().getParent(S);
353  }
354 
355  NodeMapClosure& getNodeResolver() override { return NMC; }
356 
358 
359  PathDiagnosticConsumer::PathGenerationScheme getGenerationScheme() const {
361  }
362 
363  bool supportsLogicalOpControlFlow() const {
364  return PDC ? PDC->supportsLogicalOpControlFlow() : true;
365  }
366 };
367 } // end anonymous namespace
368 
370 PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode *N) {
371  if (const Stmt *S = PathDiagnosticLocation::getNextStmt(N))
372  return PathDiagnosticLocation(S, getSourceManager(), LC);
373 
375  getSourceManager());
376 }
377 
379 PathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream &os,
380  const ExplodedNode *N) {
381 
382  // Slow, but probably doesn't matter.
383  if (os.str().empty())
384  os << ' ';
385 
386  const PathDiagnosticLocation &Loc = ExecutionContinues(N);
387 
388  if (Loc.asStmt())
389  os << "Execution continues on line "
390  << getSourceManager().getExpansionLineNumber(Loc.asLocation())
391  << '.';
392  else {
393  os << "Execution jumps to the end of the ";
394  const Decl *D = N->getLocationContext()->getDecl();
395  if (isa<ObjCMethodDecl>(D))
396  os << "method";
397  else if (isa<FunctionDecl>(D))
398  os << "function";
399  else {
400  assert(isa<BlockDecl>(D));
401  os << "anonymous block";
402  }
403  os << '.';
404  }
405 
406  return Loc;
407 }
408 
409 static const Stmt *getEnclosingParent(const Stmt *S, const ParentMap &PM) {
410  if (isa<Expr>(S) && PM.isConsumedExpr(cast<Expr>(S)))
411  return PM.getParentIgnoreParens(S);
412 
413  const Stmt *Parent = PM.getParentIgnoreParens(S);
414  if (!Parent)
415  return nullptr;
416 
417  switch (Parent->getStmtClass()) {
418  case Stmt::ForStmtClass:
419  case Stmt::DoStmtClass:
420  case Stmt::WhileStmtClass:
421  case Stmt::ObjCForCollectionStmtClass:
422  case Stmt::CXXForRangeStmtClass:
423  return Parent;
424  default:
425  break;
426  }
427 
428  return nullptr;
429 }
430 
433  const LocationContext *LC, bool allowNestedContexts) {
434  if (!S)
435  return PathDiagnosticLocation();
436 
437  while (const Stmt *Parent = getEnclosingParent(S, P)) {
438  switch (Parent->getStmtClass()) {
439  case Stmt::BinaryOperatorClass: {
440  const BinaryOperator *B = cast<BinaryOperator>(Parent);
441  if (B->isLogicalOp())
442  return PathDiagnosticLocation(allowNestedContexts ? B : S, SMgr, LC);
443  break;
444  }
445  case Stmt::CompoundStmtClass:
446  case Stmt::StmtExprClass:
447  return PathDiagnosticLocation(S, SMgr, LC);
448  case Stmt::ChooseExprClass:
449  // Similar to '?' if we are referring to condition, just have the edge
450  // point to the entire choose expression.
451  if (allowNestedContexts || cast<ChooseExpr>(Parent)->getCond() == S)
452  return PathDiagnosticLocation(Parent, SMgr, LC);
453  else
454  return PathDiagnosticLocation(S, SMgr, LC);
455  case Stmt::BinaryConditionalOperatorClass:
456  case Stmt::ConditionalOperatorClass:
457  // For '?', if we are referring to condition, just have the edge point
458  // to the entire '?' expression.
459  if (allowNestedContexts ||
460  cast<AbstractConditionalOperator>(Parent)->getCond() == S)
461  return PathDiagnosticLocation(Parent, SMgr, LC);
462  else
463  return PathDiagnosticLocation(S, SMgr, LC);
464  case Stmt::CXXForRangeStmtClass:
465  if (cast<CXXForRangeStmt>(Parent)->getBody() == S)
466  return PathDiagnosticLocation(S, SMgr, LC);
467  break;
468  case Stmt::DoStmtClass:
469  return PathDiagnosticLocation(S, SMgr, LC);
470  case Stmt::ForStmtClass:
471  if (cast<ForStmt>(Parent)->getBody() == S)
472  return PathDiagnosticLocation(S, SMgr, LC);
473  break;
474  case Stmt::IfStmtClass:
475  if (cast<IfStmt>(Parent)->getCond() != S)
476  return PathDiagnosticLocation(S, SMgr, LC);
477  break;
478  case Stmt::ObjCForCollectionStmtClass:
479  if (cast<ObjCForCollectionStmt>(Parent)->getBody() == S)
480  return PathDiagnosticLocation(S, SMgr, LC);
481  break;
482  case Stmt::WhileStmtClass:
483  if (cast<WhileStmt>(Parent)->getCond() != S)
484  return PathDiagnosticLocation(S, SMgr, LC);
485  break;
486  default:
487  break;
488  }
489 
490  S = Parent;
491  }
492 
493  assert(S && "Cannot have null Stmt for PathDiagnosticLocation");
494 
495  return PathDiagnosticLocation(S, SMgr, LC);
496 }
497 
500  assert(S && "Null Stmt passed to getEnclosingStmtLocation");
501  return ::getEnclosingStmtLocation(S, getSourceManager(), getParentMap(), LC,
502  /*allowNestedContexts=*/false);
503 }
504 
505 //===----------------------------------------------------------------------===//
506 // "Visitors only" path diagnostic generation algorithm.
507 //===----------------------------------------------------------------------===//
509  PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N,
510  ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) {
511  // All path generation skips the very first node (the error node).
512  // This is because there is special handling for the end-of-path note.
513  N = N->getFirstPred();
514  if (!N)
515  return true;
516 
517  BugReport *R = PDB.getBugReport();
518  while (const ExplodedNode *Pred = N->getFirstPred()) {
519  for (auto &V : visitors)
520  // Visit all the node pairs, but throw the path pieces away.
521  V->VisitNode(N, Pred, PDB, *R);
522 
523  N = Pred;
524  }
525 
526  return R->isValid();
527 }
528 
529 //===----------------------------------------------------------------------===//
530 // "Minimal" path diagnostic generation algorithm.
531 //===----------------------------------------------------------------------===//
532 typedef std::pair<PathDiagnosticCallPiece*, const ExplodedNode*> StackDiagPair;
534 
536  StackDiagVector &CallStack) {
537  // If the piece contains a special message, add it to all the call
538  // pieces on the active stack.
539  if (PathDiagnosticEventPiece *ep = dyn_cast<PathDiagnosticEventPiece>(&P)) {
540 
541  if (ep->hasCallStackHint())
542  for (StackDiagVector::iterator I = CallStack.begin(),
543  E = CallStack.end(); I != E; ++I) {
544  PathDiagnosticCallPiece *CP = I->first;
545  const ExplodedNode *N = I->second;
546  std::string stackMsg = ep->getCallStackMessage(N);
547 
548  // The last message on the path to final bug is the most important
549  // one. Since we traverse the path backwards, do not add the message
550  // if one has been previously added.
551  if (!CP->hasCallStackMessage())
552  CP->setCallStackMessage(stackMsg);
553  }
554  }
555 }
556 
557 static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
558 
560  PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N,
561  LocationContextMap &LCM,
562  ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) {
563 
564  SourceManager& SMgr = PDB.getSourceManager();
565  const LocationContext *LC = PDB.LC;
566  const ExplodedNode *NextNode = N->pred_empty()
567  ? nullptr : *(N->pred_begin());
568 
569  StackDiagVector CallStack;
570 
571  while (NextNode) {
572  N = NextNode;
573  PDB.LC = N->getLocationContext();
574  NextNode = N->getFirstPred();
575 
576  ProgramPoint P = N->getLocation();
577 
578  do {
579  if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
580  auto C = PathDiagnosticCallPiece::construct(N, *CE, SMgr);
581  // Record the mapping from call piece to LocationContext.
582  LCM[&C->path] = CE->getCalleeContext();
583  auto *P = C.get();
584  PD.getActivePath().push_front(std::move(C));
585  PD.pushActivePath(&P->path);
586  CallStack.push_back(StackDiagPair(P, N));
587  break;
588  }
589 
590  if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
591  // Flush all locations, and pop the active path.
592  bool VisitedEntireCall = PD.isWithinCall();
593  PD.popActivePath();
594 
595  // Either we just added a bunch of stuff to the top-level path, or
596  // we have a previous CallExitEnd. If the former, it means that the
597  // path terminated within a function call. We must then take the
598  // current contents of the active path and place it within
599  // a new PathDiagnosticCallPiece.
601  if (VisitedEntireCall) {
602  C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front().get());
603  } else {
604  const Decl *Caller = CE->getLocationContext()->getDecl();
606  // Record the mapping from call piece to LocationContext.
607  LCM[&C->path] = CE->getCalleeContext();
608  }
609 
610  C->setCallee(*CE, SMgr);
611  if (!CallStack.empty()) {
612  assert(CallStack.back().first == C);
613  CallStack.pop_back();
614  }
615  break;
616  }
617 
618  if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
619  const CFGBlock *Src = BE->getSrc();
620  const CFGBlock *Dst = BE->getDst();
621  const Stmt *T = Src->getTerminator();
622 
623  if (!T)
624  break;
625 
626  PathDiagnosticLocation Start =
628  N->getLocationContext());
629 
630  switch (T->getStmtClass()) {
631  default:
632  break;
633 
634  case Stmt::GotoStmtClass:
635  case Stmt::IndirectGotoStmtClass: {
637 
638  if (!S)
639  break;
640 
641  std::string sbuf;
642  llvm::raw_string_ostream os(sbuf);
643  const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S);
644 
645  os << "Control jumps to line "
647  PD.getActivePath().push_front(
648  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
649  os.str()));
650  break;
651  }
652 
653  case Stmt::SwitchStmtClass: {
654  // Figure out what case arm we took.
655  std::string sbuf;
656  llvm::raw_string_ostream os(sbuf);
657 
658  if (const Stmt *S = Dst->getLabel()) {
659  PathDiagnosticLocation End(S, SMgr, LC);
660 
661  switch (S->getStmtClass()) {
662  default:
663  os << "No cases match in the switch statement. "
664  "Control jumps to line "
666  break;
667  case Stmt::DefaultStmtClass:
668  os << "Control jumps to the 'default' case at line "
670  break;
671 
672  case Stmt::CaseStmtClass: {
673  os << "Control jumps to 'case ";
674  const CaseStmt *Case = cast<CaseStmt>(S);
675  const Expr *LHS = Case->getLHS()->IgnoreParenCasts();
676 
677  // Determine if it is an enum.
678  bool GetRawInt = true;
679 
680  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS)) {
681  // FIXME: Maybe this should be an assertion. Are there cases
682  // were it is not an EnumConstantDecl?
683  const EnumConstantDecl *D =
684  dyn_cast<EnumConstantDecl>(DR->getDecl());
685 
686  if (D) {
687  GetRawInt = false;
688  os << *D;
689  }
690  }
691 
692  if (GetRawInt)
693  os << LHS->EvaluateKnownConstInt(PDB.getASTContext());
694 
695  os << ":' at line "
697  break;
698  }
699  }
700  PD.getActivePath().push_front(
701  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
702  os.str()));
703  }
704  else {
705  os << "'Default' branch taken. ";
706  const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
707  PD.getActivePath().push_front(
708  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
709  os.str()));
710  }
711 
712  break;
713  }
714 
715  case Stmt::BreakStmtClass:
716  case Stmt::ContinueStmtClass: {
717  std::string sbuf;
718  llvm::raw_string_ostream os(sbuf);
719  PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
720  PD.getActivePath().push_front(
721  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
722  os.str()));
723  break;
724  }
725 
726  // Determine control-flow for ternary '?'.
727  case Stmt::BinaryConditionalOperatorClass:
728  case Stmt::ConditionalOperatorClass: {
729  std::string sbuf;
730  llvm::raw_string_ostream os(sbuf);
731  os << "'?' condition is ";
732 
733  if (*(Src->succ_begin()+1) == Dst)
734  os << "false";
735  else
736  os << "true";
737 
738  PathDiagnosticLocation End = PDB.ExecutionContinues(N);
739 
740  if (const Stmt *S = End.asStmt())
741  End = PDB.getEnclosingStmtLocation(S);
742 
743  PD.getActivePath().push_front(
744  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
745  os.str()));
746  break;
747  }
748 
749  // Determine control-flow for short-circuited '&&' and '||'.
750  case Stmt::BinaryOperatorClass: {
751  if (!PDB.supportsLogicalOpControlFlow())
752  break;
753 
754  const BinaryOperator *B = cast<BinaryOperator>(T);
755  std::string sbuf;
756  llvm::raw_string_ostream os(sbuf);
757  os << "Left side of '";
758 
759  if (B->getOpcode() == BO_LAnd) {
760  os << "&&" << "' is ";
761 
762  if (*(Src->succ_begin()+1) == Dst) {
763  os << "false";
764  PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
765  PathDiagnosticLocation Start =
767  PD.getActivePath().push_front(
768  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
769  os.str()));
770  }
771  else {
772  os << "true";
773  PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
774  PathDiagnosticLocation End = PDB.ExecutionContinues(N);
775  PD.getActivePath().push_front(
776  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
777  os.str()));
778  }
779  }
780  else {
781  assert(B->getOpcode() == BO_LOr);
782  os << "||" << "' is ";
783 
784  if (*(Src->succ_begin()+1) == Dst) {
785  os << "false";
786  PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
787  PathDiagnosticLocation End = PDB.ExecutionContinues(N);
788  PD.getActivePath().push_front(
789  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
790  os.str()));
791  }
792  else {
793  os << "true";
794  PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
795  PathDiagnosticLocation Start =
797  PD.getActivePath().push_front(
798  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
799  os.str()));
800  }
801  }
802 
803  break;
804  }
805 
806  case Stmt::DoStmtClass: {
807  if (*(Src->succ_begin()) == Dst) {
808  std::string sbuf;
809  llvm::raw_string_ostream os(sbuf);
810 
811  os << "Loop condition is true. ";
812  PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
813 
814  if (const Stmt *S = End.asStmt())
815  End = PDB.getEnclosingStmtLocation(S);
816 
817  PD.getActivePath().push_front(
818  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
819  os.str()));
820  }
821  else {
822  PathDiagnosticLocation End = PDB.ExecutionContinues(N);
823 
824  if (const Stmt *S = End.asStmt())
825  End = PDB.getEnclosingStmtLocation(S);
826 
827  PD.getActivePath().push_front(
828  std::make_shared<PathDiagnosticControlFlowPiece>(
829  Start, End, "Loop condition is false. Exiting loop"));
830  }
831 
832  break;
833  }
834 
835  case Stmt::WhileStmtClass:
836  case Stmt::ForStmtClass: {
837  if (*(Src->succ_begin()+1) == Dst) {
838  std::string sbuf;
839  llvm::raw_string_ostream os(sbuf);
840 
841  os << "Loop condition is false. ";
842  PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
843  if (const Stmt *S = End.asStmt())
844  End = PDB.getEnclosingStmtLocation(S);
845 
846  PD.getActivePath().push_front(
847  std::make_shared<PathDiagnosticControlFlowPiece>(Start, End,
848  os.str()));
849  }
850  else {
851  PathDiagnosticLocation End = PDB.ExecutionContinues(N);
852  if (const Stmt *S = End.asStmt())
853  End = PDB.getEnclosingStmtLocation(S);
854 
855  PD.getActivePath().push_front(
856  std::make_shared<PathDiagnosticControlFlowPiece>(
857  Start, End, "Loop condition is true. Entering loop body"));
858  }
859 
860  break;
861  }
862 
863  case Stmt::IfStmtClass: {
864  PathDiagnosticLocation End = PDB.ExecutionContinues(N);
865 
866  if (const Stmt *S = End.asStmt())
867  End = PDB.getEnclosingStmtLocation(S);
868 
869  if (*(Src->succ_begin()+1) == Dst)
870  PD.getActivePath().push_front(
871  std::make_shared<PathDiagnosticControlFlowPiece>(
872  Start, End, "Taking false branch"));
873  else
874  PD.getActivePath().push_front(
875  std::make_shared<PathDiagnosticControlFlowPiece>(
876  Start, End, "Taking true branch"));
877 
878  break;
879  }
880  }
881  }
882  } while(0);
883 
884  if (NextNode) {
885  // Add diagnostic pieces from custom visitors.
886  BugReport *R = PDB.getBugReport();
887  llvm::FoldingSet<PathDiagnosticPiece> DeduplicationSet;
888  for (auto &V : visitors) {
889  if (auto p = V->VisitNode(N, NextNode, PDB, *R)) {
890  if (DeduplicationSet.GetOrInsertNode(p.get()) != p.get())
891  continue;
892 
893  updateStackPiecesWithMessage(*p, CallStack);
894  PD.getActivePath().push_front(std::move(p));
895  }
896  }
897  }
898  }
899 
900  if (!PDB.getBugReport()->isValid())
901  return false;
902 
903  // After constructing the full PathDiagnostic, do a pass over it to compact
904  // PathDiagnosticPieces that occur within a macro.
905  CompactPathDiagnostic(PD.getMutablePieces(), PDB.getSourceManager());
906  return true;
907 }
908 
909 //===----------------------------------------------------------------------===//
910 // "Extensive" PathDiagnostic generation.
911 //===----------------------------------------------------------------------===//
912 
913 static bool IsControlFlowExpr(const Stmt *S) {
914  const Expr *E = dyn_cast<Expr>(S);
915 
916  if (!E)
917  return false;
918 
919  E = E->IgnoreParenCasts();
920 
921  if (isa<AbstractConditionalOperator>(E))
922  return true;
923 
924  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E))
925  if (B->isLogicalOp())
926  return true;
927 
928  return false;
929 }
930 
931 namespace {
932 class ContextLocation : public PathDiagnosticLocation {
933  bool IsDead;
934 public:
935  ContextLocation(const PathDiagnosticLocation &L, bool isdead = false)
936  : PathDiagnosticLocation(L), IsDead(isdead) {}
937 
938  void markDead() { IsDead = true; }
939  bool isDead() const { return IsDead; }
940 };
941 
942 static PathDiagnosticLocation cleanUpLocation(PathDiagnosticLocation L,
943  const LocationContext *LC,
944  bool firstCharOnly = false) {
945  if (const Stmt *S = L.asStmt()) {
946  const Stmt *Original = S;
947  while (1) {
948  // Adjust the location for some expressions that are best referenced
949  // by one of their subexpressions.
950  switch (S->getStmtClass()) {
951  default:
952  break;
953  case Stmt::ParenExprClass:
954  case Stmt::GenericSelectionExprClass:
955  S = cast<Expr>(S)->IgnoreParens();
956  firstCharOnly = true;
957  continue;
958  case Stmt::BinaryConditionalOperatorClass:
959  case Stmt::ConditionalOperatorClass:
960  S = cast<AbstractConditionalOperator>(S)->getCond();
961  firstCharOnly = true;
962  continue;
963  case Stmt::ChooseExprClass:
964  S = cast<ChooseExpr>(S)->getCond();
965  firstCharOnly = true;
966  continue;
967  case Stmt::BinaryOperatorClass:
968  S = cast<BinaryOperator>(S)->getLHS();
969  firstCharOnly = true;
970  continue;
971  }
972 
973  break;
974  }
975 
976  if (S != Original)
977  L = PathDiagnosticLocation(S, L.getManager(), LC);
978  }
979 
980  if (firstCharOnly)
982 
983  return L;
984 }
985 
986 class EdgeBuilder {
987  std::vector<ContextLocation> CLocs;
988  typedef std::vector<ContextLocation>::iterator iterator;
989  PathDiagnostic &PD;
990  PathDiagnosticBuilder &PDB;
991  PathDiagnosticLocation PrevLoc;
992 
993  bool IsConsumedExpr(const PathDiagnosticLocation &L);
994 
995  bool containsLocation(const PathDiagnosticLocation &Container,
996  const PathDiagnosticLocation &Containee);
997 
998  PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L);
999 
1000 
1001 
1002  void popLocation() {
1003  if (!CLocs.back().isDead() && CLocs.back().asLocation().isFileID()) {
1004  // For contexts, we only one the first character as the range.
1005  rawAddEdge(cleanUpLocation(CLocs.back(), PDB.LC, true));
1006  }
1007  CLocs.pop_back();
1008  }
1009 
1010 public:
1011  EdgeBuilder(PathDiagnostic &pd, PathDiagnosticBuilder &pdb)
1012  : PD(pd), PDB(pdb) {
1013 
1014  // If the PathDiagnostic already has pieces, add the enclosing statement
1015  // of the first piece as a context as well.
1016  if (!PD.path.empty()) {
1017  PrevLoc = (*PD.path.begin())->getLocation();
1018 
1019  if (const Stmt *S = PrevLoc.asStmt())
1020  addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
1021  }
1022  }
1023 
1024  ~EdgeBuilder() {
1025  while (!CLocs.empty()) popLocation();
1026 
1027  // Finally, add an initial edge from the start location of the first
1028  // statement (if it doesn't already exist).
1030  PDB.LC,
1031  PDB.getSourceManager());
1032  if (L.isValid())
1033  rawAddEdge(L);
1034  }
1035 
1036  void flushLocations() {
1037  while (!CLocs.empty())
1038  popLocation();
1039  PrevLoc = PathDiagnosticLocation();
1040  }
1041 
1042  void addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd = false,
1043  bool IsPostJump = false);
1044 
1045  void rawAddEdge(PathDiagnosticLocation NewLoc);
1046 
1047  void addContext(const Stmt *S);
1048  void addContext(const PathDiagnosticLocation &L);
1049  void addExtendedContext(const Stmt *S);
1050 };
1051 } // end anonymous namespace
1052 
1053 
1055 EdgeBuilder::getContextLocation(const PathDiagnosticLocation &L) {
1056  if (const Stmt *S = L.asStmt()) {
1057  if (IsControlFlowExpr(S))
1058  return L;
1059 
1060  return PDB.getEnclosingStmtLocation(S);
1061  }
1062 
1063  return L;
1064 }
1065 
1066 bool EdgeBuilder::containsLocation(const PathDiagnosticLocation &Container,
1067  const PathDiagnosticLocation &Containee) {
1068 
1069  if (Container == Containee)
1070  return true;
1071 
1072  if (Container.asDecl())
1073  return true;
1074 
1075  if (const Stmt *S = Containee.asStmt())
1076  if (const Stmt *ContainerS = Container.asStmt()) {
1077  while (S) {
1078  if (S == ContainerS)
1079  return true;
1080  S = PDB.getParent(S);
1081  }
1082  return false;
1083  }
1084 
1085  // Less accurate: compare using source ranges.
1086  SourceRange ContainerR = Container.asRange();
1087  SourceRange ContaineeR = Containee.asRange();
1088 
1089  SourceManager &SM = PDB.getSourceManager();
1090  SourceLocation ContainerRBeg = SM.getExpansionLoc(ContainerR.getBegin());
1091  SourceLocation ContainerREnd = SM.getExpansionLoc(ContainerR.getEnd());
1092  SourceLocation ContaineeRBeg = SM.getExpansionLoc(ContaineeR.getBegin());
1093  SourceLocation ContaineeREnd = SM.getExpansionLoc(ContaineeR.getEnd());
1094 
1095  unsigned ContainerBegLine = SM.getExpansionLineNumber(ContainerRBeg);
1096  unsigned ContainerEndLine = SM.getExpansionLineNumber(ContainerREnd);
1097  unsigned ContaineeBegLine = SM.getExpansionLineNumber(ContaineeRBeg);
1098  unsigned ContaineeEndLine = SM.getExpansionLineNumber(ContaineeREnd);
1099 
1100  assert(ContainerBegLine <= ContainerEndLine);
1101  assert(ContaineeBegLine <= ContaineeEndLine);
1102 
1103  return (ContainerBegLine <= ContaineeBegLine &&
1104  ContainerEndLine >= ContaineeEndLine &&
1105  (ContainerBegLine != ContaineeBegLine ||
1106  SM.getExpansionColumnNumber(ContainerRBeg) <=
1107  SM.getExpansionColumnNumber(ContaineeRBeg)) &&
1108  (ContainerEndLine != ContaineeEndLine ||
1109  SM.getExpansionColumnNumber(ContainerREnd) >=
1110  SM.getExpansionColumnNumber(ContaineeREnd)));
1111 }
1112 
1113 void EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) {
1114  if (!PrevLoc.isValid()) {
1115  PrevLoc = NewLoc;
1116  return;
1117  }
1118 
1119  const PathDiagnosticLocation &NewLocClean = cleanUpLocation(NewLoc, PDB.LC);
1120  const PathDiagnosticLocation &PrevLocClean = cleanUpLocation(PrevLoc, PDB.LC);
1121 
1122  if (PrevLocClean.asLocation().isInvalid()) {
1123  PrevLoc = NewLoc;
1124  return;
1125  }
1126 
1127  if (NewLocClean.asLocation() == PrevLocClean.asLocation())
1128  return;
1129 
1130  // FIXME: Ignore intra-macro edges for now.
1131  if (NewLocClean.asLocation().getExpansionLoc() ==
1132  PrevLocClean.asLocation().getExpansionLoc())
1133  return;
1134 
1135  PD.getActivePath().push_front(
1136  std::make_shared<PathDiagnosticControlFlowPiece>(NewLocClean,
1137  PrevLocClean));
1138  PrevLoc = NewLoc;
1139 }
1140 
1141 void EdgeBuilder::addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd,
1142  bool IsPostJump) {
1143 
1144  if (!alwaysAdd && NewLoc.asLocation().isMacroID())
1145  return;
1146 
1147  const PathDiagnosticLocation &CLoc = getContextLocation(NewLoc);
1148 
1149  while (!CLocs.empty()) {
1150  ContextLocation &TopContextLoc = CLocs.back();
1151 
1152  // Is the top location context the same as the one for the new location?
1153  if (TopContextLoc == CLoc) {
1154  if (alwaysAdd) {
1155  if (IsConsumedExpr(TopContextLoc))
1156  TopContextLoc.markDead();
1157 
1158  rawAddEdge(NewLoc);
1159  }
1160 
1161  if (IsPostJump)
1162  TopContextLoc.markDead();
1163  return;
1164  }
1165 
1166  if (containsLocation(TopContextLoc, CLoc)) {
1167  if (alwaysAdd) {
1168  rawAddEdge(NewLoc);
1169 
1170  if (IsConsumedExpr(CLoc)) {
1171  CLocs.push_back(ContextLocation(CLoc, /*IsDead=*/true));
1172  return;
1173  }
1174  }
1175 
1176  CLocs.push_back(ContextLocation(CLoc, /*IsDead=*/IsPostJump));
1177  return;
1178  }
1179 
1180  // Context does not contain the location. Flush it.
1181  popLocation();
1182  }
1183 
1184  // If we reach here, there is no enclosing context. Just add the edge.
1185  rawAddEdge(NewLoc);
1186 }
1187 
1188 bool EdgeBuilder::IsConsumedExpr(const PathDiagnosticLocation &L) {
1189  if (const Expr *X = dyn_cast_or_null<Expr>(L.asStmt()))
1190  return PDB.getParentMap().isConsumedExpr(X) && !IsControlFlowExpr(X);
1191 
1192  return false;
1193 }
1194 
1195 void EdgeBuilder::addExtendedContext(const Stmt *S) {
1196  if (!S)
1197  return;
1198 
1199  const Stmt *Parent = PDB.getParent(S);
1200  while (Parent) {
1201  if (isa<CompoundStmt>(Parent))
1202  Parent = PDB.getParent(Parent);
1203  else
1204  break;
1205  }
1206 
1207  if (Parent) {
1208  switch (Parent->getStmtClass()) {
1209  case Stmt::DoStmtClass:
1210  case Stmt::ObjCAtSynchronizedStmtClass:
1211  addContext(Parent);
1212  default:
1213  break;
1214  }
1215  }
1216 
1217  addContext(S);
1218 }
1219 
1220 void EdgeBuilder::addContext(const Stmt *S) {
1221  if (!S)
1222  return;
1223 
1224  PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.LC);
1225  addContext(L);
1226 }
1227 
1228 void EdgeBuilder::addContext(const PathDiagnosticLocation &L) {
1229  while (!CLocs.empty()) {
1230  const PathDiagnosticLocation &TopContextLoc = CLocs.back();
1231 
1232  // Is the top location context the same as the one for the new location?
1233  if (TopContextLoc == L)
1234  return;
1235 
1236  if (containsLocation(TopContextLoc, L)) {
1237  CLocs.push_back(L);
1238  return;
1239  }
1240 
1241  // Context does not contain the location. Flush it.
1242  popLocation();
1243  }
1244 
1245  CLocs.push_back(L);
1246 }
1247 
1248 // Cone-of-influence: support the reverse propagation of "interesting" symbols
1249 // and values by tracing interesting calculations backwards through evaluated
1250 // expressions along a path. This is probably overly complicated, but the idea
1251 // is that if an expression computed an "interesting" value, the child
1252 // expressions are are also likely to be "interesting" as well (which then
1253 // propagates to the values they in turn compute). This reverse propagation
1254 // is needed to track interesting correlations across function call boundaries,
1255 // where formal arguments bind to actual arguments, etc. This is also needed
1256 // because the constraint solver sometimes simplifies certain symbolic values
1257 // into constants when appropriate, and this complicates reasoning about
1258 // interesting values.
1260 
1262  InterestingExprs &IE,
1263  const ProgramState *State,
1264  const Expr *Ex,
1265  const LocationContext *LCtx) {
1266  SVal V = State->getSVal(Ex, LCtx);
1267  if (!(R.isInteresting(V) || IE.count(Ex)))
1268  return;
1269 
1270  switch (Ex->getStmtClass()) {
1271  default:
1272  if (!isa<CastExpr>(Ex))
1273  break;
1274  // Fall through.
1275  case Stmt::BinaryOperatorClass:
1276  case Stmt::UnaryOperatorClass: {
1277  for (const Stmt *SubStmt : Ex->children()) {
1278  if (const Expr *child = dyn_cast_or_null<Expr>(SubStmt)) {
1279  IE.insert(child);
1280  SVal ChildV = State->getSVal(child, LCtx);
1281  R.markInteresting(ChildV);
1282  }
1283  }
1284  break;
1285  }
1286  }
1287 
1288  R.markInteresting(V);
1289 }
1290 
1292  InterestingExprs &IE,
1293  const ProgramState *State,
1294  const LocationContext *CalleeCtx,
1295  const LocationContext *CallerCtx)
1296 {
1297  // FIXME: Handle non-CallExpr-based CallEvents.
1298  const StackFrameContext *Callee = CalleeCtx->getCurrentStackFrame();
1299  const Stmt *CallSite = Callee->getCallSite();
1300  if (const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite)) {
1301  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeCtx->getDecl())) {
1302  FunctionDecl::param_const_iterator PI = FD->param_begin(),
1303  PE = FD->param_end();
1304  CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
1305  for (; AI != AE && PI != PE; ++AI, ++PI) {
1306  if (const Expr *ArgE = *AI) {
1307  if (const ParmVarDecl *PD = *PI) {
1308  Loc LV = State->getLValue(PD, CalleeCtx);
1309  if (R.isInteresting(LV) || R.isInteresting(State->getRawSVal(LV)))
1310  IE.insert(ArgE);
1311  }
1312  }
1313  }
1314  }
1315  }
1316 }
1317 
1318 //===----------------------------------------------------------------------===//
1319 // Functions for determining if a loop was executed 0 times.
1320 //===----------------------------------------------------------------------===//
1321 
1322 static bool isLoop(const Stmt *Term) {
1323  switch (Term->getStmtClass()) {
1324  case Stmt::ForStmtClass:
1325  case Stmt::WhileStmtClass:
1326  case Stmt::ObjCForCollectionStmtClass:
1327  case Stmt::CXXForRangeStmtClass:
1328  return true;
1329  default:
1330  // Note that we intentionally do not include do..while here.
1331  return false;
1332  }
1333 }
1334 
1335 static bool isJumpToFalseBranch(const BlockEdge *BE) {
1336  const CFGBlock *Src = BE->getSrc();
1337  assert(Src->succ_size() == 2);
1338  return (*(Src->succ_begin()+1) == BE->getDst());
1339 }
1340 
1341 /// Return true if the terminator is a loop and the destination is the
1342 /// false branch.
1343 static bool isLoopJumpPastBody(const Stmt *Term, const BlockEdge *BE) {
1344  if (!isLoop(Term))
1345  return false;
1346 
1347  // Did we take the false branch?
1348  return isJumpToFalseBranch(BE);
1349 }
1350 
1351 static bool isContainedByStmt(ParentMap &PM, const Stmt *S, const Stmt *SubS) {
1352  while (SubS) {
1353  if (SubS == S)
1354  return true;
1355  SubS = PM.getParent(SubS);
1356  }
1357  return false;
1358 }
1359 
1360 static const Stmt *getStmtBeforeCond(ParentMap &PM, const Stmt *Term,
1361  const ExplodedNode *N) {
1362  while (N) {
1364  if (SP) {
1365  const Stmt *S = SP->getStmt();
1366  if (!isContainedByStmt(PM, Term, S))
1367  return S;
1368  }
1369  N = N->getFirstPred();
1370  }
1371  return nullptr;
1372 }
1373 
1374 static bool isInLoopBody(ParentMap &PM, const Stmt *S, const Stmt *Term) {
1375  const Stmt *LoopBody = nullptr;
1376  switch (Term->getStmtClass()) {
1377  case Stmt::CXXForRangeStmtClass: {
1378  const CXXForRangeStmt *FR = cast<CXXForRangeStmt>(Term);
1379  if (isContainedByStmt(PM, FR->getInc(), S))
1380  return true;
1381  if (isContainedByStmt(PM, FR->getLoopVarStmt(), S))
1382  return true;
1383  LoopBody = FR->getBody();
1384  break;
1385  }
1386  case Stmt::ForStmtClass: {
1387  const ForStmt *FS = cast<ForStmt>(Term);
1388  if (isContainedByStmt(PM, FS->getInc(), S))
1389  return true;
1390  LoopBody = FS->getBody();
1391  break;
1392  }
1393  case Stmt::ObjCForCollectionStmtClass: {
1394  const ObjCForCollectionStmt *FC = cast<ObjCForCollectionStmt>(Term);
1395  LoopBody = FC->getBody();
1396  break;
1397  }
1398  case Stmt::WhileStmtClass:
1399  LoopBody = cast<WhileStmt>(Term)->getBody();
1400  break;
1401  default:
1402  return false;
1403  }
1404  return isContainedByStmt(PM, LoopBody, S);
1405 }
1406 
1407 //===----------------------------------------------------------------------===//
1408 // Top-level logic for generating extensive path diagnostics.
1409 //===----------------------------------------------------------------------===//
1410 
1412  PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N,
1413  LocationContextMap &LCM,
1414  ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) {
1415  EdgeBuilder EB(PD, PDB);
1416  const SourceManager& SM = PDB.getSourceManager();
1417  StackDiagVector CallStack;
1418  InterestingExprs IE;
1419 
1420  const ExplodedNode *NextNode = N->pred_empty() ? nullptr : *(N->pred_begin());
1421  while (NextNode) {
1422  N = NextNode;
1423  NextNode = N->getFirstPred();
1424  ProgramPoint P = N->getLocation();
1425 
1426  do {
1427  if (Optional<PostStmt> PS = P.getAs<PostStmt>()) {
1428  if (const Expr *Ex = PS->getStmtAs<Expr>())
1429  reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
1430  N->getState().get(), Ex,
1431  N->getLocationContext());
1432  }
1433 
1434  if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
1435  const Stmt *S = CE->getCalleeContext()->getCallSite();
1436  if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
1437  reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
1438  N->getState().get(), Ex,
1439  N->getLocationContext());
1440  }
1441 
1442  auto C = PathDiagnosticCallPiece::construct(N, *CE, SM);
1443  LCM[&C->path] = CE->getCalleeContext();
1444 
1445  EB.addEdge(C->callReturn, /*AlwaysAdd=*/true, /*IsPostJump=*/true);
1446  EB.flushLocations();
1447 
1448  auto *P = C.get();
1449  PD.getActivePath().push_front(std::move(C));
1450  PD.pushActivePath(&P->path);
1451  CallStack.push_back(StackDiagPair(P, N));
1452  break;
1453  }
1454 
1455  // Pop the call hierarchy if we are done walking the contents
1456  // of a function call.
1457  if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
1458  // Add an edge to the start of the function.
1459  const Decl *D = CE->getCalleeContext()->getDecl();
1462  EB.addEdge(pos);
1463 
1464  // Flush all locations, and pop the active path.
1465  bool VisitedEntireCall = PD.isWithinCall();
1466  EB.flushLocations();
1467  PD.popActivePath();
1468  PDB.LC = N->getLocationContext();
1469 
1470  // Either we just added a bunch of stuff to the top-level path, or
1471  // we have a previous CallExitEnd. If the former, it means that the
1472  // path terminated within a function call. We must then take the
1473  // current contents of the active path and place it within
1474  // a new PathDiagnosticCallPiece.
1476  if (VisitedEntireCall) {
1477  C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front().get());
1478  } else {
1479  const Decl *Caller = CE->getLocationContext()->getDecl();
1481  LCM[&C->path] = CE->getCalleeContext();
1482  }
1483 
1484  C->setCallee(*CE, SM);
1485  EB.addContext(C->getLocation());
1486 
1487  if (!CallStack.empty()) {
1488  assert(CallStack.back().first == C);
1489  CallStack.pop_back();
1490  }
1491  break;
1492  }
1493 
1494  // Note that is important that we update the LocationContext
1495  // after looking at CallExits. CallExit basically adds an
1496  // edge in the *caller*, so we don't want to update the LocationContext
1497  // too soon.
1498  PDB.LC = N->getLocationContext();
1499 
1500  // Block edges.
1501  if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
1502  // Does this represent entering a call? If so, look at propagating
1503  // interesting symbols across call boundaries.
1504  if (NextNode) {
1505  const LocationContext *CallerCtx = NextNode->getLocationContext();
1506  const LocationContext *CalleeCtx = PDB.LC;
1507  if (CallerCtx != CalleeCtx) {
1508  reversePropagateInterestingSymbols(*PDB.getBugReport(), IE,
1509  N->getState().get(),
1510  CalleeCtx, CallerCtx);
1511  }
1512  }
1513 
1514  // Are we jumping to the head of a loop? Add a special diagnostic.
1515  if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) {
1516  PathDiagnosticLocation L(Loop, SM, PDB.LC);
1517  const CompoundStmt *CS = nullptr;
1518 
1519  if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
1520  CS = dyn_cast<CompoundStmt>(FS->getBody());
1521  else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
1522  CS = dyn_cast<CompoundStmt>(WS->getBody());
1523 
1524  auto p = std::make_shared<PathDiagnosticEventPiece>(
1525  L, "Looping back to the head of the loop");
1526  p->setPrunable(true);
1527 
1528  EB.addEdge(p->getLocation(), true);
1529  PD.getActivePath().push_front(std::move(p));
1530 
1531  if (CS) {
1534  EB.addEdge(BL);
1535  }
1536  }
1537 
1538  const CFGBlock *BSrc = BE->getSrc();
1539  ParentMap &PM = PDB.getParentMap();
1540 
1541  if (const Stmt *Term = BSrc->getTerminator()) {
1542  // Are we jumping past the loop body without ever executing the
1543  // loop (because the condition was false)?
1544  if (isLoopJumpPastBody(Term, &*BE) &&
1545  !isInLoopBody(PM,
1546  getStmtBeforeCond(PM,
1547  BSrc->getTerminatorCondition(),
1548  N),
1549  Term)) {
1550  PathDiagnosticLocation L(Term, SM, PDB.LC);
1551  auto PE = std::make_shared<PathDiagnosticEventPiece>(
1552  L, "Loop body executed 0 times");
1553  PE->setPrunable(true);
1554 
1555  EB.addEdge(PE->getLocation(), true);
1556  PD.getActivePath().push_front(std::move(PE));
1557  }
1558 
1559  // In any case, add the terminator as the current statement
1560  // context for control edges.
1561  EB.addContext(Term);
1562  }
1563 
1564  break;
1565  }
1566 
1568  Optional<CFGElement> First = BE->getFirstElement();
1569  if (Optional<CFGStmt> S = First ? First->getAs<CFGStmt>() : None) {
1570  const Stmt *stmt = S->getStmt();
1571  if (IsControlFlowExpr(stmt)) {
1572  // Add the proper context for '&&', '||', and '?'.
1573  EB.addContext(stmt);
1574  }
1575  else
1576  EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt());
1577  }
1578 
1579  break;
1580  }
1581 
1582 
1583  } while (0);
1584 
1585  if (!NextNode)
1586  continue;
1587 
1588  // Add pieces from custom visitors.
1589  BugReport *R = PDB.getBugReport();
1590  llvm::FoldingSet<PathDiagnosticPiece> DeduplicationSet;
1591  for (auto &V : visitors) {
1592  if (auto p = V->VisitNode(N, NextNode, PDB, *R)) {
1593  if (DeduplicationSet.GetOrInsertNode(p.get()) != p.get())
1594  continue;
1595 
1596  const PathDiagnosticLocation &Loc = p->getLocation();
1597  EB.addEdge(Loc, true);
1598  updateStackPiecesWithMessage(*p, CallStack);
1599  PD.getActivePath().push_front(std::move(p));
1600 
1601  if (const Stmt *S = Loc.asStmt())
1602  EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
1603  }
1604  }
1605  }
1606 
1607  return PDB.getBugReport()->isValid();
1608 }
1609 
1610 /// \brief Adds a sanitized control-flow diagnostic edge to a path.
1611 static void addEdgeToPath(PathPieces &path,
1612  PathDiagnosticLocation &PrevLoc,
1613  PathDiagnosticLocation NewLoc,
1614  const LocationContext *LC) {
1615  if (!NewLoc.isValid())
1616  return;
1617 
1618  SourceLocation NewLocL = NewLoc.asLocation();
1619  if (NewLocL.isInvalid())
1620  return;
1621 
1622  if (!PrevLoc.isValid() || !PrevLoc.asLocation().isValid()) {
1623  PrevLoc = NewLoc;
1624  return;
1625  }
1626 
1627  // Ignore self-edges, which occur when there are multiple nodes at the same
1628  // statement.
1629  if (NewLoc.asStmt() && NewLoc.asStmt() == PrevLoc.asStmt())
1630  return;
1631 
1632  path.push_front(
1633  std::make_shared<PathDiagnosticControlFlowPiece>(NewLoc, PrevLoc));
1634  PrevLoc = NewLoc;
1635 }
1636 
1637 /// A customized wrapper for CFGBlock::getTerminatorCondition()
1638 /// which returns the element for ObjCForCollectionStmts.
1639 static const Stmt *getTerminatorCondition(const CFGBlock *B) {
1640  const Stmt *S = B->getTerminatorCondition();
1641  if (const ObjCForCollectionStmt *FS =
1642  dyn_cast_or_null<ObjCForCollectionStmt>(S))
1643  return FS->getElement();
1644  return S;
1645 }
1646 
1647 static const char StrEnteringLoop[] = "Entering loop body";
1648 static const char StrLoopBodyZero[] = "Loop body executed 0 times";
1649 static const char StrLoopRangeEmpty[] =
1650  "Loop body skipped when range is empty";
1651 static const char StrLoopCollectionEmpty[] =
1652  "Loop body skipped when collection is empty";
1653 
1655  PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N,
1656  LocationContextMap &LCM,
1657  ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) {
1658 
1659  BugReport *report = PDB.getBugReport();
1660  const SourceManager& SM = PDB.getSourceManager();
1661  StackDiagVector CallStack;
1662  InterestingExprs IE;
1663 
1664  PathDiagnosticLocation PrevLoc = PD.getLocation();
1665 
1666  const ExplodedNode *NextNode = N->getFirstPred();
1667  while (NextNode) {
1668  N = NextNode;
1669  NextNode = N->getFirstPred();
1670  ProgramPoint P = N->getLocation();
1671 
1672  do {
1673  // Have we encountered an entrance to a call? It may be
1674  // the case that we have not encountered a matching
1675  // call exit before this point. This means that the path
1676  // terminated within the call itself.
1677  if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
1678  // Add an edge to the start of the function.
1679  const StackFrameContext *CalleeLC = CE->getCalleeContext();
1680  const Decl *D = CalleeLC->getDecl();
1681  // Add the edge only when the callee has body. We jump to the beginning
1682  // of the *declaration*, however we expect it to be followed by the
1683  // body. This isn't the case for autosynthesized property accessors in
1684  // Objective-C. No need for a similar extra check for CallExit points
1685  // because the exit edge comes from a statement (i.e. return),
1686  // not from declaration.
1687  if (D->hasBody())
1688  addEdgeToPath(PD.getActivePath(), PrevLoc,
1689  PathDiagnosticLocation::createBegin(D, SM), CalleeLC);
1690 
1691  // Did we visit an entire call?
1692  bool VisitedEntireCall = PD.isWithinCall();
1693  PD.popActivePath();
1694 
1696  if (VisitedEntireCall) {
1697  PathDiagnosticPiece *P = PD.getActivePath().front().get();
1698  C = cast<PathDiagnosticCallPiece>(P);
1699  } else {
1700  const Decl *Caller = CE->getLocationContext()->getDecl();
1702 
1703  // Since we just transferred the path over to the call piece,
1704  // reset the mapping from active to location context.
1705  assert(PD.getActivePath().size() == 1 &&
1706  PD.getActivePath().front().get() == C);
1707  LCM[&PD.getActivePath()] = nullptr;
1708 
1709  // Record the location context mapping for the path within
1710  // the call.
1711  assert(LCM[&C->path] == nullptr ||
1712  LCM[&C->path] == CE->getCalleeContext());
1713  LCM[&C->path] = CE->getCalleeContext();
1714 
1715  // If this is the first item in the active path, record
1716  // the new mapping from active path to location context.
1717  const LocationContext *&NewLC = LCM[&PD.getActivePath()];
1718  if (!NewLC)
1719  NewLC = N->getLocationContext();
1720 
1721  PDB.LC = NewLC;
1722  }
1723  C->setCallee(*CE, SM);
1724 
1725  // Update the previous location in the active path.
1726  PrevLoc = C->getLocation();
1727 
1728  if (!CallStack.empty()) {
1729  assert(CallStack.back().first == C);
1730  CallStack.pop_back();
1731  }
1732  break;
1733  }
1734 
1735  // Query the location context here and the previous location
1736  // as processing CallEnter may change the active path.
1737  PDB.LC = N->getLocationContext();
1738 
1739  // Record the mapping from the active path to the location
1740  // context.
1741  assert(!LCM[&PD.getActivePath()] ||
1742  LCM[&PD.getActivePath()] == PDB.LC);
1743  LCM[&PD.getActivePath()] = PDB.LC;
1744 
1745  // Have we encountered an exit from a function call?
1746  if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) {
1747  const Stmt *S = CE->getCalleeContext()->getCallSite();
1748  // Propagate the interesting symbols accordingly.
1749  if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
1750  reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
1751  N->getState().get(), Ex,
1752  N->getLocationContext());
1753  }
1754 
1755  // We are descending into a call (backwards). Construct
1756  // a new call piece to contain the path pieces for that call.
1757  auto C = PathDiagnosticCallPiece::construct(N, *CE, SM);
1758 
1759  // Record the location context for this call piece.
1760  LCM[&C->path] = CE->getCalleeContext();
1761 
1762  // Add the edge to the return site.
1763  addEdgeToPath(PD.getActivePath(), PrevLoc, C->callReturn, PDB.LC);
1764  auto *P = C.get();
1765  PD.getActivePath().push_front(std::move(C));
1766  PrevLoc.invalidate();
1767 
1768  // Make the contents of the call the active path for now.
1769  PD.pushActivePath(&P->path);
1770  CallStack.push_back(StackDiagPair(P, N));
1771  break;
1772  }
1773 
1774  if (Optional<PostStmt> PS = P.getAs<PostStmt>()) {
1775  // For expressions, make sure we propagate the
1776  // interesting symbols correctly.
1777  if (const Expr *Ex = PS->getStmtAs<Expr>())
1778  reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
1779  N->getState().get(), Ex,
1780  N->getLocationContext());
1781 
1782  // Add an edge. If this is an ObjCForCollectionStmt do
1783  // not add an edge here as it appears in the CFG both
1784  // as a terminator and as a terminator condition.
1785  if (!isa<ObjCForCollectionStmt>(PS->getStmt())) {
1787  PathDiagnosticLocation(PS->getStmt(), SM, PDB.LC);
1788  addEdgeToPath(PD.getActivePath(), PrevLoc, L, PDB.LC);
1789  }
1790  break;
1791  }
1792 
1793  // Block edges.
1794  if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
1795  // Does this represent entering a call? If so, look at propagating
1796  // interesting symbols across call boundaries.
1797  if (NextNode) {
1798  const LocationContext *CallerCtx = NextNode->getLocationContext();
1799  const LocationContext *CalleeCtx = PDB.LC;
1800  if (CallerCtx != CalleeCtx) {
1801  reversePropagateInterestingSymbols(*PDB.getBugReport(), IE,
1802  N->getState().get(),
1803  CalleeCtx, CallerCtx);
1804  }
1805  }
1806 
1807  // Are we jumping to the head of a loop? Add a special diagnostic.
1808  if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) {
1809  PathDiagnosticLocation L(Loop, SM, PDB.LC);
1810  const Stmt *Body = nullptr;
1811 
1812  if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
1813  Body = FS->getBody();
1814  else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
1815  Body = WS->getBody();
1816  else if (const ObjCForCollectionStmt *OFS =
1817  dyn_cast<ObjCForCollectionStmt>(Loop)) {
1818  Body = OFS->getBody();
1819  } else if (const CXXForRangeStmt *FRS =
1820  dyn_cast<CXXForRangeStmt>(Loop)) {
1821  Body = FRS->getBody();
1822  }
1823  // do-while statements are explicitly excluded here
1824 
1825  auto p = std::make_shared<PathDiagnosticEventPiece>(
1826  L, "Looping back to the head "
1827  "of the loop");
1828  p->setPrunable(true);
1829 
1830  addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC);
1831  PD.getActivePath().push_front(std::move(p));
1832 
1833  if (const CompoundStmt *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
1834  addEdgeToPath(PD.getActivePath(), PrevLoc,
1836  PDB.LC);
1837  }
1838  }
1839 
1840  const CFGBlock *BSrc = BE->getSrc();
1841  ParentMap &PM = PDB.getParentMap();
1842 
1843  if (const Stmt *Term = BSrc->getTerminator()) {
1844  // Are we jumping past the loop body without ever executing the
1845  // loop (because the condition was false)?
1846  if (isLoop(Term)) {
1847  const Stmt *TermCond = getTerminatorCondition(BSrc);
1848  bool IsInLoopBody =
1849  isInLoopBody(PM, getStmtBeforeCond(PM, TermCond, N), Term);
1850 
1851  const char *str = nullptr;
1852 
1853  if (isJumpToFalseBranch(&*BE)) {
1854  if (!IsInLoopBody) {
1855  if (isa<ObjCForCollectionStmt>(Term)) {
1856  str = StrLoopCollectionEmpty;
1857  } else if (isa<CXXForRangeStmt>(Term)) {
1858  str = StrLoopRangeEmpty;
1859  } else {
1860  str = StrLoopBodyZero;
1861  }
1862  }
1863  } else {
1864  str = StrEnteringLoop;
1865  }
1866 
1867  if (str) {
1868  PathDiagnosticLocation L(TermCond ? TermCond : Term, SM, PDB.LC);
1869  auto PE = std::make_shared<PathDiagnosticEventPiece>(L, str);
1870  PE->setPrunable(true);
1871  addEdgeToPath(PD.getActivePath(), PrevLoc,
1872  PE->getLocation(), PDB.LC);
1873  PD.getActivePath().push_front(std::move(PE));
1874  }
1875  } else if (isa<BreakStmt>(Term) || isa<ContinueStmt>(Term) ||
1876  isa<GotoStmt>(Term)) {
1877  PathDiagnosticLocation L(Term, SM, PDB.LC);
1878  addEdgeToPath(PD.getActivePath(), PrevLoc, L, PDB.LC);
1879  }
1880  }
1881  break;
1882  }
1883  } while (0);
1884 
1885  if (!NextNode)
1886  continue;
1887 
1888  // Add pieces from custom visitors.
1889  llvm::FoldingSet<PathDiagnosticPiece> DeduplicationSet;
1890  for (auto &V : visitors) {
1891  if (auto p = V->VisitNode(N, NextNode, PDB, *report)) {
1892  if (DeduplicationSet.GetOrInsertNode(p.get()) != p.get())
1893  continue;
1894 
1895  addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC);
1896  updateStackPiecesWithMessage(*p, CallStack);
1897  PD.getActivePath().push_front(std::move(p));
1898  }
1899  }
1900  }
1901 
1902  // Add an edge to the start of the function.
1903  // We'll prune it out later, but it helps make diagnostics more uniform.
1904  const StackFrameContext *CalleeLC = PDB.LC->getCurrentStackFrame();
1905  const Decl *D = CalleeLC->getDecl();
1906  addEdgeToPath(PD.getActivePath(), PrevLoc,
1908  CalleeLC);
1909 
1910  return report->isValid();
1911 }
1912 
1914  if (!L.isValid())
1915  return nullptr;
1916  return L.asStmt();
1917 }
1918 
1919 static const Stmt *getStmtParent(const Stmt *S, const ParentMap &PM) {
1920  if (!S)
1921  return nullptr;
1922 
1923  while (true) {
1924  S = PM.getParentIgnoreParens(S);
1925 
1926  if (!S)
1927  break;
1928 
1929  if (isa<ExprWithCleanups>(S) ||
1930  isa<CXXBindTemporaryExpr>(S) ||
1931  isa<SubstNonTypeTemplateParmExpr>(S))
1932  continue;
1933 
1934  break;
1935  }
1936 
1937  return S;
1938 }
1939 
1940 static bool isConditionForTerminator(const Stmt *S, const Stmt *Cond) {
1941  switch (S->getStmtClass()) {
1942  case Stmt::BinaryOperatorClass: {
1943  const BinaryOperator *BO = cast<BinaryOperator>(S);
1944  if (!BO->isLogicalOp())
1945  return false;
1946  return BO->getLHS() == Cond || BO->getRHS() == Cond;
1947  }
1948  case Stmt::IfStmtClass:
1949  return cast<IfStmt>(S)->getCond() == Cond;
1950  case Stmt::ForStmtClass:
1951  return cast<ForStmt>(S)->getCond() == Cond;
1952  case Stmt::WhileStmtClass:
1953  return cast<WhileStmt>(S)->getCond() == Cond;
1954  case Stmt::DoStmtClass:
1955  return cast<DoStmt>(S)->getCond() == Cond;
1956  case Stmt::ChooseExprClass:
1957  return cast<ChooseExpr>(S)->getCond() == Cond;
1958  case Stmt::IndirectGotoStmtClass:
1959  return cast<IndirectGotoStmt>(S)->getTarget() == Cond;
1960  case Stmt::SwitchStmtClass:
1961  return cast<SwitchStmt>(S)->getCond() == Cond;
1962  case Stmt::BinaryConditionalOperatorClass:
1963  return cast<BinaryConditionalOperator>(S)->getCond() == Cond;
1964  case Stmt::ConditionalOperatorClass: {
1965  const ConditionalOperator *CO = cast<ConditionalOperator>(S);
1966  return CO->getCond() == Cond ||
1967  CO->getLHS() == Cond ||
1968  CO->getRHS() == Cond;
1969  }
1970  case Stmt::ObjCForCollectionStmtClass:
1971  return cast<ObjCForCollectionStmt>(S)->getElement() == Cond;
1972  case Stmt::CXXForRangeStmtClass: {
1973  const CXXForRangeStmt *FRS = cast<CXXForRangeStmt>(S);
1974  return FRS->getCond() == Cond || FRS->getRangeInit() == Cond;
1975  }
1976  default:
1977  return false;
1978  }
1979 }
1980 
1981 static bool isIncrementOrInitInForLoop(const Stmt *S, const Stmt *FL) {
1982  if (const ForStmt *FS = dyn_cast<ForStmt>(FL))
1983  return FS->getInc() == S || FS->getInit() == S;
1984  if (const CXXForRangeStmt *FRS = dyn_cast<CXXForRangeStmt>(FL))
1985  return FRS->getInc() == S || FRS->getRangeStmt() == S ||
1986  FRS->getLoopVarStmt() || FRS->getRangeInit() == S;
1987  return false;
1988 }
1989 
1992 
1993 /// Adds synthetic edges from top-level statements to their subexpressions.
1994 ///
1995 /// This avoids a "swoosh" effect, where an edge from a top-level statement A
1996 /// points to a sub-expression B.1 that's not at the start of B. In these cases,
1997 /// we'd like to see an edge from A to B, then another one from B to B.1.
1998 static void addContextEdges(PathPieces &pieces, SourceManager &SM,
1999  const ParentMap &PM, const LocationContext *LCtx) {
2000  PathPieces::iterator Prev = pieces.end();
2001  for (PathPieces::iterator I = pieces.begin(), E = Prev; I != E;
2002  Prev = I, ++I) {
2004  dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
2005 
2006  if (!Piece)
2007  continue;
2008 
2009  PathDiagnosticLocation SrcLoc = Piece->getStartLocation();
2011 
2012  PathDiagnosticLocation NextSrcContext = SrcLoc;
2013  const Stmt *InnerStmt = nullptr;
2014  while (NextSrcContext.isValid() && NextSrcContext.asStmt() != InnerStmt) {
2015  SrcContexts.push_back(NextSrcContext);
2016  InnerStmt = NextSrcContext.asStmt();
2017  NextSrcContext = getEnclosingStmtLocation(InnerStmt, SM, PM, LCtx,
2018  /*allowNested=*/true);
2019  }
2020 
2021  // Repeatedly split the edge as necessary.
2022  // This is important for nested logical expressions (||, &&, ?:) where we
2023  // want to show all the levels of context.
2024  while (true) {
2025  const Stmt *Dst = getLocStmt(Piece->getEndLocation());
2026 
2027  // We are looking at an edge. Is the destination within a larger
2028  // expression?
2029  PathDiagnosticLocation DstContext =
2030  getEnclosingStmtLocation(Dst, SM, PM, LCtx, /*allowNested=*/true);
2031  if (!DstContext.isValid() || DstContext.asStmt() == Dst)
2032  break;
2033 
2034  // If the source is in the same context, we're already good.
2035  if (std::find(SrcContexts.begin(), SrcContexts.end(), DstContext) !=
2036  SrcContexts.end())
2037  break;
2038 
2039  // Update the subexpression node to point to the context edge.
2040  Piece->setStartLocation(DstContext);
2041 
2042  // Try to extend the previous edge if it's at the same level as the source
2043  // context.
2044  if (Prev != E) {
2045  auto *PrevPiece = dyn_cast<PathDiagnosticControlFlowPiece>(Prev->get());
2046 
2047  if (PrevPiece) {
2048  if (const Stmt *PrevSrc = getLocStmt(PrevPiece->getStartLocation())) {
2049  const Stmt *PrevSrcParent = getStmtParent(PrevSrc, PM);
2050  if (PrevSrcParent == getStmtParent(getLocStmt(DstContext), PM)) {
2051  PrevPiece->setEndLocation(DstContext);
2052  break;
2053  }
2054  }
2055  }
2056  }
2057 
2058  // Otherwise, split the current edge into a context edge and a
2059  // subexpression edge. Note that the context statement may itself have
2060  // context.
2061  auto P =
2062  std::make_shared<PathDiagnosticControlFlowPiece>(SrcLoc, DstContext);
2063  Piece = P.get();
2064  I = pieces.insert(I, std::move(P));
2065  }
2066  }
2067 }
2068 
2069 /// \brief Move edges from a branch condition to a branch target
2070 /// when the condition is simple.
2071 ///
2072 /// This restructures some of the work of addContextEdges. That function
2073 /// creates edges this may destroy, but they work together to create a more
2074 /// aesthetically set of edges around branches. After the call to
2075 /// addContextEdges, we may have (1) an edge to the branch, (2) an edge from
2076 /// the branch to the branch condition, and (3) an edge from the branch
2077 /// condition to the branch target. We keep (1), but may wish to remove (2)
2078 /// and move the source of (3) to the branch if the branch condition is simple.
2079 ///
2080 static void simplifySimpleBranches(PathPieces &pieces) {
2081  for (PathPieces::iterator I = pieces.begin(), E = pieces.end(); I != E; ++I) {
2082 
2083  auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
2084 
2085  if (!PieceI)
2086  continue;
2087 
2088  const Stmt *s1Start = getLocStmt(PieceI->getStartLocation());
2089  const Stmt *s1End = getLocStmt(PieceI->getEndLocation());
2090 
2091  if (!s1Start || !s1End)
2092  continue;
2093 
2094  PathPieces::iterator NextI = I; ++NextI;
2095  if (NextI == E)
2096  break;
2097 
2098  PathDiagnosticControlFlowPiece *PieceNextI = nullptr;
2099 
2100  while (true) {
2101  if (NextI == E)
2102  break;
2103 
2104  auto *EV = dyn_cast<PathDiagnosticEventPiece>(NextI->get());
2105  if (EV) {
2106  StringRef S = EV->getString();
2107  if (S == StrEnteringLoop || S == StrLoopBodyZero ||
2109  ++NextI;
2110  continue;
2111  }
2112  break;
2113  }
2114 
2115  PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
2116  break;
2117  }
2118 
2119  if (!PieceNextI)
2120  continue;
2121 
2122  const Stmt *s2Start = getLocStmt(PieceNextI->getStartLocation());
2123  const Stmt *s2End = getLocStmt(PieceNextI->getEndLocation());
2124 
2125  if (!s2Start || !s2End || s1End != s2Start)
2126  continue;
2127 
2128  // We only perform this transformation for specific branch kinds.
2129  // We don't want to do this for do..while, for example.
2130  if (!(isa<ForStmt>(s1Start) || isa<WhileStmt>(s1Start) ||
2131  isa<IfStmt>(s1Start) || isa<ObjCForCollectionStmt>(s1Start) ||
2132  isa<CXXForRangeStmt>(s1Start)))
2133  continue;
2134 
2135  // Is s1End the branch condition?
2136  if (!isConditionForTerminator(s1Start, s1End))
2137  continue;
2138 
2139  // Perform the hoisting by eliminating (2) and changing the start
2140  // location of (3).
2141  PieceNextI->setStartLocation(PieceI->getStartLocation());
2142  I = pieces.erase(I);
2143  }
2144 }
2145 
2146 /// Returns the number of bytes in the given (character-based) SourceRange.
2147 ///
2148 /// If the locations in the range are not on the same line, returns None.
2149 ///
2150 /// Note that this does not do a precise user-visible character or column count.
2152  SourceRange Range) {
2153  SourceRange ExpansionRange(SM.getExpansionLoc(Range.getBegin()),
2154  SM.getExpansionRange(Range.getEnd()).second);
2155 
2156  FileID FID = SM.getFileID(ExpansionRange.getBegin());
2157  if (FID != SM.getFileID(ExpansionRange.getEnd()))
2158  return None;
2159 
2160  bool Invalid;
2161  const llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, &Invalid);
2162  if (Invalid)
2163  return None;
2164 
2165  unsigned BeginOffset = SM.getFileOffset(ExpansionRange.getBegin());
2166  unsigned EndOffset = SM.getFileOffset(ExpansionRange.getEnd());
2167  StringRef Snippet = Buffer->getBuffer().slice(BeginOffset, EndOffset);
2168 
2169  // We're searching the raw bytes of the buffer here, which might include
2170  // escaped newlines and such. That's okay; we're trying to decide whether the
2171  // SourceRange is covering a large or small amount of space in the user's
2172  // editor.
2173  if (Snippet.find_first_of("\r\n") != StringRef::npos)
2174  return None;
2175 
2176  // This isn't Unicode-aware, but it doesn't need to be.
2177  return Snippet.size();
2178 }
2179 
2180 /// \sa getLengthOnSingleLine(SourceManager, SourceRange)
2182  const Stmt *S) {
2183  return getLengthOnSingleLine(SM, S->getSourceRange());
2184 }
2185 
2186 /// Eliminate two-edge cycles created by addContextEdges().
2187 ///
2188 /// Once all the context edges are in place, there are plenty of cases where
2189 /// there's a single edge from a top-level statement to a subexpression,
2190 /// followed by a single path note, and then a reverse edge to get back out to
2191 /// the top level. If the statement is simple enough, the subexpression edges
2192 /// just add noise and make it harder to understand what's going on.
2193 ///
2194 /// This function only removes edges in pairs, because removing only one edge
2195 /// might leave other edges dangling.
2196 ///
2197 /// This will not remove edges in more complicated situations:
2198 /// - if there is more than one "hop" leading to or from a subexpression.
2199 /// - if there is an inlined call between the edges instead of a single event.
2200 /// - if the whole statement is large enough that having subexpression arrows
2201 /// might be helpful.
2203  ParentMap &PM) {
2204  for (PathPieces::iterator I = Path.begin(), E = Path.end(); I != E; ) {
2205  // Pattern match the current piece and its successor.
2207  dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
2208 
2209  if (!PieceI) {
2210  ++I;
2211  continue;
2212  }
2213 
2214  const Stmt *s1Start = getLocStmt(PieceI->getStartLocation());
2215  const Stmt *s1End = getLocStmt(PieceI->getEndLocation());
2216 
2217  PathPieces::iterator NextI = I; ++NextI;
2218  if (NextI == E)
2219  break;
2220 
2221  PathDiagnosticControlFlowPiece *PieceNextI =
2222  dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
2223 
2224  if (!PieceNextI) {
2225  if (isa<PathDiagnosticEventPiece>(NextI->get())) {
2226  ++NextI;
2227  if (NextI == E)
2228  break;
2229  PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
2230  }
2231 
2232  if (!PieceNextI) {
2233  ++I;
2234  continue;
2235  }
2236  }
2237 
2238  const Stmt *s2Start = getLocStmt(PieceNextI->getStartLocation());
2239  const Stmt *s2End = getLocStmt(PieceNextI->getEndLocation());
2240 
2241  if (s1Start && s2Start && s1Start == s2End && s2Start == s1End) {
2242  const size_t MAX_SHORT_LINE_LENGTH = 80;
2243  Optional<size_t> s1Length = getLengthOnSingleLine(SM, s1Start);
2244  if (s1Length && *s1Length <= MAX_SHORT_LINE_LENGTH) {
2245  Optional<size_t> s2Length = getLengthOnSingleLine(SM, s2Start);
2246  if (s2Length && *s2Length <= MAX_SHORT_LINE_LENGTH) {
2247  Path.erase(I);
2248  I = Path.erase(NextI);
2249  continue;
2250  }
2251  }
2252  }
2253 
2254  ++I;
2255  }
2256 }
2257 
2258 /// \brief Return true if X is contained by Y.
2259 static bool lexicalContains(ParentMap &PM,
2260  const Stmt *X,
2261  const Stmt *Y) {
2262  while (X) {
2263  if (X == Y)
2264  return true;
2265  X = PM.getParent(X);
2266  }
2267  return false;
2268 }
2269 
2270 // Remove short edges on the same line less than 3 columns in difference.
2271 static void removePunyEdges(PathPieces &path,
2272  SourceManager &SM,
2273  ParentMap &PM) {
2274 
2275  bool erased = false;
2276 
2277  for (PathPieces::iterator I = path.begin(), E = path.end(); I != E;
2278  erased ? I : ++I) {
2279 
2280  erased = false;
2281 
2282  auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
2283 
2284  if (!PieceI)
2285  continue;
2286 
2287  const Stmt *start = getLocStmt(PieceI->getStartLocation());
2288  const Stmt *end = getLocStmt(PieceI->getEndLocation());
2289 
2290  if (!start || !end)
2291  continue;
2292 
2293  const Stmt *endParent = PM.getParent(end);
2294  if (!endParent)
2295  continue;
2296 
2297  if (isConditionForTerminator(end, endParent))
2298  continue;
2299 
2300  SourceLocation FirstLoc = start->getLocStart();
2301  SourceLocation SecondLoc = end->getLocStart();
2302 
2303  if (!SM.isWrittenInSameFile(FirstLoc, SecondLoc))
2304  continue;
2305  if (SM.isBeforeInTranslationUnit(SecondLoc, FirstLoc))
2306  std::swap(SecondLoc, FirstLoc);
2307 
2308  SourceRange EdgeRange(FirstLoc, SecondLoc);
2309  Optional<size_t> ByteWidth = getLengthOnSingleLine(SM, EdgeRange);
2310 
2311  // If the statements are on different lines, continue.
2312  if (!ByteWidth)
2313  continue;
2314 
2315  const size_t MAX_PUNY_EDGE_LENGTH = 2;
2316  if (*ByteWidth <= MAX_PUNY_EDGE_LENGTH) {
2317  // FIXME: There are enough /bytes/ between the endpoints of the edge, but
2318  // there might not be enough /columns/. A proper user-visible column count
2319  // is probably too expensive, though.
2320  I = path.erase(I);
2321  erased = true;
2322  continue;
2323  }
2324  }
2325 }
2326 
2327 static void removeIdenticalEvents(PathPieces &path) {
2328  for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ++I) {
2329  auto *PieceI = dyn_cast<PathDiagnosticEventPiece>(I->get());
2330 
2331  if (!PieceI)
2332  continue;
2333 
2334  PathPieces::iterator NextI = I; ++NextI;
2335  if (NextI == E)
2336  return;
2337 
2338  auto *PieceNextI = dyn_cast<PathDiagnosticEventPiece>(NextI->get());
2339 
2340  if (!PieceNextI)
2341  continue;
2342 
2343  // Erase the second piece if it has the same exact message text.
2344  if (PieceI->getString() == PieceNextI->getString()) {
2345  path.erase(NextI);
2346  }
2347  }
2348 }
2349 
2350 static bool optimizeEdges(PathPieces &path, SourceManager &SM,
2351  OptimizedCallsSet &OCS,
2352  LocationContextMap &LCM) {
2353  bool hasChanges = false;
2354  const LocationContext *LC = LCM[&path];
2355  assert(LC);
2356  ParentMap &PM = LC->getParentMap();
2357 
2358  for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ) {
2359  // Optimize subpaths.
2360  if (auto *CallI = dyn_cast<PathDiagnosticCallPiece>(I->get())) {
2361  // Record the fact that a call has been optimized so we only do the
2362  // effort once.
2363  if (!OCS.count(CallI)) {
2364  while (optimizeEdges(CallI->path, SM, OCS, LCM)) {}
2365  OCS.insert(CallI);
2366  }
2367  ++I;
2368  continue;
2369  }
2370 
2371  // Pattern match the current piece and its successor.
2372  auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get());
2373 
2374  if (!PieceI) {
2375  ++I;
2376  continue;
2377  }
2378 
2379  const Stmt *s1Start = getLocStmt(PieceI->getStartLocation());
2380  const Stmt *s1End = getLocStmt(PieceI->getEndLocation());
2381  const Stmt *level1 = getStmtParent(s1Start, PM);
2382  const Stmt *level2 = getStmtParent(s1End, PM);
2383 
2384  PathPieces::iterator NextI = I; ++NextI;
2385  if (NextI == E)
2386  break;
2387 
2388  auto *PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get());
2389 
2390  if (!PieceNextI) {
2391  ++I;
2392  continue;
2393  }
2394 
2395  const Stmt *s2Start = getLocStmt(PieceNextI->getStartLocation());
2396  const Stmt *s2End = getLocStmt(PieceNextI->getEndLocation());
2397  const Stmt *level3 = getStmtParent(s2Start, PM);
2398  const Stmt *level4 = getStmtParent(s2End, PM);
2399 
2400  // Rule I.
2401  //
2402  // If we have two consecutive control edges whose end/begin locations
2403  // are at the same level (e.g. statements or top-level expressions within
2404  // a compound statement, or siblings share a single ancestor expression),
2405  // then merge them if they have no interesting intermediate event.
2406  //
2407  // For example:
2408  //
2409  // (1.1 -> 1.2) -> (1.2 -> 1.3) becomes (1.1 -> 1.3) because the common
2410  // parent is '1'. Here 'x.y.z' represents the hierarchy of statements.
2411  //
2412  // NOTE: this will be limited later in cases where we add barriers
2413  // to prevent this optimization.
2414  //
2415  if (level1 && level1 == level2 && level1 == level3 && level1 == level4) {
2416  PieceI->setEndLocation(PieceNextI->getEndLocation());
2417  path.erase(NextI);
2418  hasChanges = true;
2419  continue;
2420  }
2421 
2422  // Rule II.
2423  //
2424  // Eliminate edges between subexpressions and parent expressions
2425  // when the subexpression is consumed.
2426  //
2427  // NOTE: this will be limited later in cases where we add barriers
2428  // to prevent this optimization.
2429  //
2430  if (s1End && s1End == s2Start && level2) {
2431  bool removeEdge = false;
2432  // Remove edges into the increment or initialization of a
2433  // loop that have no interleaving event. This means that
2434  // they aren't interesting.
2435  if (isIncrementOrInitInForLoop(s1End, level2))
2436  removeEdge = true;
2437  // Next only consider edges that are not anchored on
2438  // the condition of a terminator. This are intermediate edges
2439  // that we might want to trim.
2440  else if (!isConditionForTerminator(level2, s1End)) {
2441  // Trim edges on expressions that are consumed by
2442  // the parent expression.
2443  if (isa<Expr>(s1End) && PM.isConsumedExpr(cast<Expr>(s1End))) {
2444  removeEdge = true;
2445  }
2446  // Trim edges where a lexical containment doesn't exist.
2447  // For example:
2448  //
2449  // X -> Y -> Z
2450  //
2451  // If 'Z' lexically contains Y (it is an ancestor) and
2452  // 'X' does not lexically contain Y (it is a descendant OR
2453  // it has no lexical relationship at all) then trim.
2454  //
2455  // This can eliminate edges where we dive into a subexpression
2456  // and then pop back out, etc.
2457  else if (s1Start && s2End &&
2458  lexicalContains(PM, s2Start, s2End) &&
2459  !lexicalContains(PM, s1End, s1Start)) {
2460  removeEdge = true;
2461  }
2462  // Trim edges from a subexpression back to the top level if the
2463  // subexpression is on a different line.
2464  //
2465  // A.1 -> A -> B
2466  // becomes
2467  // A.1 -> B
2468  //
2469  // These edges just look ugly and don't usually add anything.
2470  else if (s1Start && s2End &&
2471  lexicalContains(PM, s1Start, s1End)) {
2472  SourceRange EdgeRange(PieceI->getEndLocation().asLocation(),
2473  PieceI->getStartLocation().asLocation());
2474  if (!getLengthOnSingleLine(SM, EdgeRange).hasValue())
2475  removeEdge = true;
2476  }
2477  }
2478 
2479  if (removeEdge) {
2480  PieceI->setEndLocation(PieceNextI->getEndLocation());
2481  path.erase(NextI);
2482  hasChanges = true;
2483  continue;
2484  }
2485  }
2486 
2487  // Optimize edges for ObjC fast-enumeration loops.
2488  //
2489  // (X -> collection) -> (collection -> element)
2490  //
2491  // becomes:
2492  //
2493  // (X -> element)
2494  if (s1End == s2Start) {
2495  const ObjCForCollectionStmt *FS =
2496  dyn_cast_or_null<ObjCForCollectionStmt>(level3);
2497  if (FS && FS->getCollection()->IgnoreParens() == s2Start &&
2498  s2End == FS->getElement()) {
2499  PieceI->setEndLocation(PieceNextI->getEndLocation());
2500  path.erase(NextI);
2501  hasChanges = true;
2502  continue;
2503  }
2504  }
2505 
2506  // No changes at this index? Move to the next one.
2507  ++I;
2508  }
2509 
2510  if (!hasChanges) {
2511  // Adjust edges into subexpressions to make them more uniform
2512  // and aesthetically pleasing.
2513  addContextEdges(path, SM, PM, LC);
2514  // Remove "cyclical" edges that include one or more context edges.
2515  removeContextCycles(path, SM, PM);
2516  // Hoist edges originating from branch conditions to branches
2517  // for simple branches.
2518  simplifySimpleBranches(path);
2519  // Remove any puny edges left over after primary optimization pass.
2520  removePunyEdges(path, SM, PM);
2521  // Remove identical events.
2522  removeIdenticalEvents(path);
2523  }
2524 
2525  return hasChanges;
2526 }
2527 
2528 /// Drop the very first edge in a path, which should be a function entry edge.
2529 ///
2530 /// If the first edge is not a function entry edge (say, because the first
2531 /// statement had an invalid source location), this function does nothing.
2532 // FIXME: We should just generate invalid edges anyway and have the optimizer
2533 // deal with them.
2535  LocationContextMap &LCM,
2536  SourceManager &SM) {
2537  const auto *FirstEdge =
2538  dyn_cast<PathDiagnosticControlFlowPiece>(Path.front().get());
2539  if (!FirstEdge)
2540  return;
2541 
2542  const Decl *D = LCM[&Path]->getDecl();
2544  if (FirstEdge->getStartLocation() != EntryLoc)
2545  return;
2546 
2547  Path.pop_front();
2548 }
2549 
2550 
2551 //===----------------------------------------------------------------------===//
2552 // Methods for BugType and subclasses.
2553 //===----------------------------------------------------------------------===//
2554 void BugType::anchor() { }
2555 
2557 
2558 void BuiltinBug::anchor() {}
2559 
2560 //===----------------------------------------------------------------------===//
2561 // Methods for BugReport and subclasses.
2562 //===----------------------------------------------------------------------===//
2563 
2564 void BugReport::NodeResolver::anchor() {}
2565 
2566 void BugReport::addVisitor(std::unique_ptr<BugReporterVisitor> visitor) {
2567  if (!visitor)
2568  return;
2569 
2570  llvm::FoldingSetNodeID ID;
2571  visitor->Profile(ID);
2572  void *InsertPos;
2573 
2574  if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos))
2575  return;
2576 
2577  CallbacksSet.InsertNode(visitor.get(), InsertPos);
2578  Callbacks.push_back(std::move(visitor));
2579  ++ConfigurationChangeToken;
2580 }
2581 
2583  while (!interestingSymbols.empty()) {
2584  popInterestingSymbolsAndRegions();
2585  }
2586 }
2587 
2589  if (DeclWithIssue)
2590  return DeclWithIssue;
2591 
2592  const ExplodedNode *N = getErrorNode();
2593  if (!N)
2594  return nullptr;
2595 
2596  const LocationContext *LC = N->getLocationContext();
2597  return LC->getCurrentStackFrame()->getDecl();
2598 }
2599 
2600 void BugReport::Profile(llvm::FoldingSetNodeID& hash) const {
2601  hash.AddPointer(&BT);
2602  hash.AddString(Description);
2603  PathDiagnosticLocation UL = getUniqueingLocation();
2604  if (UL.isValid()) {
2605  UL.Profile(hash);
2606  } else if (Location.isValid()) {
2607  Location.Profile(hash);
2608  } else {
2609  assert(ErrorNode);
2610  hash.AddPointer(GetCurrentOrPreviousStmt(ErrorNode));
2611  }
2612 
2613  for (SourceRange range : Ranges) {
2614  if (!range.isValid())
2615  continue;
2616  hash.AddInteger(range.getBegin().getRawEncoding());
2617  hash.AddInteger(range.getEnd().getRawEncoding());
2618  }
2619 }
2620 
2622  if (!sym)
2623  return;
2624 
2625  // If the symbol wasn't already in our set, note a configuration change.
2626  if (getInterestingSymbols().insert(sym).second)
2627  ++ConfigurationChangeToken;
2628 
2629  if (const SymbolMetadata *meta = dyn_cast<SymbolMetadata>(sym))
2630  getInterestingRegions().insert(meta->getRegion());
2631 }
2632 
2634  if (!R)
2635  return;
2636 
2637  // If the base region wasn't already in our set, note a configuration change.
2638  R = R->getBaseRegion();
2639  if (getInterestingRegions().insert(R).second)
2640  ++ConfigurationChangeToken;
2641 
2642  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
2643  getInterestingSymbols().insert(SR->getSymbol());
2644 }
2645 
2647  markInteresting(V.getAsRegion());
2648  markInteresting(V.getAsSymbol());
2649 }
2650 
2652  if (!LC)
2653  return;
2654  InterestingLocationContexts.insert(LC);
2655 }
2656 
2658  return isInteresting(V.getAsRegion()) || isInteresting(V.getAsSymbol());
2659 }
2660 
2662  if (!sym)
2663  return false;
2664  // We don't currently consider metadata symbols to be interesting
2665  // even if we know their region is interesting. Is that correct behavior?
2666  return getInterestingSymbols().count(sym);
2667 }
2668 
2670  if (!R)
2671  return false;
2672  R = R->getBaseRegion();
2673  bool b = getInterestingRegions().count(R);
2674  if (b)
2675  return true;
2676  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
2677  return getInterestingSymbols().count(SR->getSymbol());
2678  return false;
2679 }
2680 
2682  if (!LC)
2683  return false;
2684  return InterestingLocationContexts.count(LC);
2685 }
2686 
2687 void BugReport::lazyInitializeInterestingSets() {
2688  if (interestingSymbols.empty()) {
2689  interestingSymbols.push_back(new Symbols());
2690  interestingRegions.push_back(new Regions());
2691  }
2692 }
2693 
2694 BugReport::Symbols &BugReport::getInterestingSymbols() {
2695  lazyInitializeInterestingSets();
2696  return *interestingSymbols.back();
2697 }
2698 
2699 BugReport::Regions &BugReport::getInterestingRegions() {
2700  lazyInitializeInterestingSets();
2701  return *interestingRegions.back();
2702 }
2703 
2704 void BugReport::pushInterestingSymbolsAndRegions() {
2705  interestingSymbols.push_back(new Symbols(getInterestingSymbols()));
2706  interestingRegions.push_back(new Regions(getInterestingRegions()));
2707 }
2708 
2709 void BugReport::popInterestingSymbolsAndRegions() {
2710  delete interestingSymbols.pop_back_val();
2711  delete interestingRegions.pop_back_val();
2712 }
2713 
2714 const Stmt *BugReport::getStmt() const {
2715  if (!ErrorNode)
2716  return nullptr;
2717 
2718  ProgramPoint ProgP = ErrorNode->getLocation();
2719  const Stmt *S = nullptr;
2720 
2721  if (Optional<BlockEntrance> BE = ProgP.getAs<BlockEntrance>()) {
2722  CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit();
2723  if (BE->getBlock() == &Exit)
2724  S = GetPreviousStmt(ErrorNode);
2725  }
2726  if (!S)
2727  S = PathDiagnosticLocation::getStmt(ErrorNode);
2728 
2729  return S;
2730 }
2731 
2732 llvm::iterator_range<BugReport::ranges_iterator> BugReport::getRanges() {
2733  // If no custom ranges, add the range of the statement corresponding to
2734  // the error node.
2735  if (Ranges.empty()) {
2736  if (const Expr *E = dyn_cast_or_null<Expr>(getStmt()))
2737  addRange(E->getSourceRange());
2738  else
2739  return llvm::make_range(ranges_iterator(), ranges_iterator());
2740  }
2741 
2742  // User-specified absence of range info.
2743  if (Ranges.size() == 1 && !Ranges.begin()->isValid())
2744  return llvm::make_range(ranges_iterator(), ranges_iterator());
2745 
2746  return llvm::make_range(Ranges.begin(), Ranges.end());
2747 }
2748 
2750  if (ErrorNode) {
2751  assert(!Location.isValid() &&
2752  "Either Location or ErrorNode should be specified but not both.");
2753  return PathDiagnosticLocation::createEndOfPath(ErrorNode, SM);
2754  }
2755 
2756  assert(Location.isValid());
2757  return Location;
2758 }
2759 
2760 //===----------------------------------------------------------------------===//
2761 // Methods for BugReporter and subclasses.
2762 //===----------------------------------------------------------------------===//
2763 
2767 
2768 ExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); }
2769 
2771 GRBugReporter::getStateManager() { return Eng.getStateManager(); }
2772 
2774  FlushReports();
2775 
2776  // Free the bug reports we are tracking.
2777  typedef std::vector<BugReportEquivClass *> ContTy;
2778  for (ContTy::iterator I = EQClassesVector.begin(), E = EQClassesVector.end();
2779  I != E; ++I) {
2780  delete *I;
2781  }
2782 }
2783 
2785  if (BugTypes.isEmpty())
2786  return;
2787 
2788  // First flush the warnings for each BugType. This may end up creating new
2789  // warnings and new BugTypes.
2790  // FIXME: Only NSErrorChecker needs BugType's FlushReports.
2791  // Turn NSErrorChecker into a proper checker and remove this.
2792  SmallVector<const BugType *, 16> bugTypes(BugTypes.begin(), BugTypes.end());
2794  I = bugTypes.begin(), E = bugTypes.end(); I != E; ++I)
2795  const_cast<BugType*>(*I)->FlushReports(*this);
2796 
2797  // We need to flush reports in deterministic order to ensure the order
2798  // of the reports is consistent between runs.
2799  typedef std::vector<BugReportEquivClass *> ContVecTy;
2800  for (ContVecTy::iterator EI=EQClassesVector.begin(), EE=EQClassesVector.end();
2801  EI != EE; ++EI){
2802  BugReportEquivClass& EQ = **EI;
2803  FlushReport(EQ);
2804  }
2805 
2806  // BugReporter owns and deletes only BugTypes created implicitly through
2807  // EmitBasicReport.
2808  // FIXME: There are leaks from checkers that assume that the BugTypes they
2809  // create will be destroyed by the BugReporter.
2810  llvm::DeleteContainerSeconds(StrBugTypes);
2811 
2812  // Remove all references to the BugType objects.
2813  BugTypes = F.getEmptySet();
2814 }
2815 
2816 //===----------------------------------------------------------------------===//
2817 // PathDiagnostics generation.
2818 //===----------------------------------------------------------------------===//
2819 
2820 namespace {
2821 /// A wrapper around a report graph, which contains only a single path, and its
2822 /// node maps.
2823 class ReportGraph {
2824 public:
2825  InterExplodedGraphMap BackMap;
2826  std::unique_ptr<ExplodedGraph> Graph;
2827  const ExplodedNode *ErrorNode;
2828  size_t Index;
2829 };
2830 
2831 /// A wrapper around a trimmed graph and its node maps.
2832 class TrimmedGraph {
2833  InterExplodedGraphMap InverseMap;
2834 
2835  typedef llvm::DenseMap<const ExplodedNode *, unsigned> PriorityMapTy;
2836  PriorityMapTy PriorityMap;
2837 
2838  typedef std::pair<const ExplodedNode *, size_t> NodeIndexPair;
2839  SmallVector<NodeIndexPair, 32> ReportNodes;
2840 
2841  std::unique_ptr<ExplodedGraph> G;
2842 
2843  /// A helper class for sorting ExplodedNodes by priority.
2844  template <bool Descending>
2845  class PriorityCompare {
2846  const PriorityMapTy &PriorityMap;
2847 
2848  public:
2849  PriorityCompare(const PriorityMapTy &M) : PriorityMap(M) {}
2850 
2851  bool operator()(const ExplodedNode *LHS, const ExplodedNode *RHS) const {
2852  PriorityMapTy::const_iterator LI = PriorityMap.find(LHS);
2853  PriorityMapTy::const_iterator RI = PriorityMap.find(RHS);
2854  PriorityMapTy::const_iterator E = PriorityMap.end();
2855 
2856  if (LI == E)
2857  return Descending;
2858  if (RI == E)
2859  return !Descending;
2860 
2861  return Descending ? LI->second > RI->second
2862  : LI->second < RI->second;
2863  }
2864 
2865  bool operator()(const NodeIndexPair &LHS, const NodeIndexPair &RHS) const {
2866  return (*this)(LHS.first, RHS.first);
2867  }
2868  };
2869 
2870 public:
2871  TrimmedGraph(const ExplodedGraph *OriginalGraph,
2873 
2874  bool popNextReportGraph(ReportGraph &GraphWrapper);
2875 };
2876 }
2877 
2878 TrimmedGraph::TrimmedGraph(const ExplodedGraph *OriginalGraph,
2880  // The trimmed graph is created in the body of the constructor to ensure
2881  // that the DenseMaps have been initialized already.
2882  InterExplodedGraphMap ForwardMap;
2883  G = OriginalGraph->trim(Nodes, &ForwardMap, &InverseMap);
2884 
2885  // Find the (first) error node in the trimmed graph. We just need to consult
2886  // the node map which maps from nodes in the original graph to nodes
2887  // in the new graph.
2888  llvm::SmallPtrSet<const ExplodedNode *, 32> RemainingNodes;
2889 
2890  for (unsigned i = 0, count = Nodes.size(); i < count; ++i) {
2891  if (const ExplodedNode *NewNode = ForwardMap.lookup(Nodes[i])) {
2892  ReportNodes.push_back(std::make_pair(NewNode, i));
2893  RemainingNodes.insert(NewNode);
2894  }
2895  }
2896 
2897  assert(!RemainingNodes.empty() && "No error node found in the trimmed graph");
2898 
2899  // Perform a forward BFS to find all the shortest paths.
2900  std::queue<const ExplodedNode *> WS;
2901 
2902  assert(G->num_roots() == 1);
2903  WS.push(*G->roots_begin());
2904  unsigned Priority = 0;
2905 
2906  while (!WS.empty()) {
2907  const ExplodedNode *Node = WS.front();
2908  WS.pop();
2909 
2910  PriorityMapTy::iterator PriorityEntry;
2911  bool IsNew;
2912  std::tie(PriorityEntry, IsNew) =
2913  PriorityMap.insert(std::make_pair(Node, Priority));
2914  ++Priority;
2915 
2916  if (!IsNew) {
2917  assert(PriorityEntry->second <= Priority);
2918  continue;
2919  }
2920 
2921  if (RemainingNodes.erase(Node))
2922  if (RemainingNodes.empty())
2923  break;
2924 
2926  E = Node->succ_end();
2927  I != E; ++I)
2928  WS.push(*I);
2929  }
2930 
2931  // Sort the error paths from longest to shortest.
2932  std::sort(ReportNodes.begin(), ReportNodes.end(),
2933  PriorityCompare<true>(PriorityMap));
2934 }
2935 
2936 bool TrimmedGraph::popNextReportGraph(ReportGraph &GraphWrapper) {
2937  if (ReportNodes.empty())
2938  return false;
2939 
2940  const ExplodedNode *OrigN;
2941  std::tie(OrigN, GraphWrapper.Index) = ReportNodes.pop_back_val();
2942  assert(PriorityMap.find(OrigN) != PriorityMap.end() &&
2943  "error node not accessible from root");
2944 
2945  // Create a new graph with a single path. This is the graph
2946  // that will be returned to the caller.
2947  auto GNew = llvm::make_unique<ExplodedGraph>();
2948  GraphWrapper.BackMap.clear();
2949 
2950  // Now walk from the error node up the BFS path, always taking the
2951  // predeccessor with the lowest number.
2952  ExplodedNode *Succ = nullptr;
2953  while (true) {
2954  // Create the equivalent node in the new graph with the same state
2955  // and location.
2956  ExplodedNode *NewN = GNew->createUncachedNode(OrigN->getLocation(), OrigN->getState(),
2957  OrigN->isSink());
2958 
2959  // Store the mapping to the original node.
2960  InterExplodedGraphMap::const_iterator IMitr = InverseMap.find(OrigN);
2961  assert(IMitr != InverseMap.end() && "No mapping to original node.");
2962  GraphWrapper.BackMap[NewN] = IMitr->second;
2963 
2964  // Link up the new node with the previous node.
2965  if (Succ)
2966  Succ->addPredecessor(NewN, *GNew);
2967  else
2968  GraphWrapper.ErrorNode = NewN;
2969 
2970  Succ = NewN;
2971 
2972  // Are we at the final node?
2973  if (OrigN->pred_empty()) {
2974  GNew->addRoot(NewN);
2975  break;
2976  }
2977 
2978  // Find the next predeccessor node. We choose the node that is marked
2979  // with the lowest BFS number.
2980  OrigN = *std::min_element(OrigN->pred_begin(), OrigN->pred_end(),
2981  PriorityCompare<false>(PriorityMap));
2982  }
2983 
2984  GraphWrapper.Graph = std::move(GNew);
2985 
2986  return true;
2987 }
2988 
2989 
2990 /// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
2991 /// and collapses PathDiagosticPieces that are expanded by macros.
2992 static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
2993  typedef std::vector<
2994  std::pair<std::shared_ptr<PathDiagnosticMacroPiece>, SourceLocation>>
2995  MacroStackTy;
2996 
2997  typedef std::vector<std::shared_ptr<PathDiagnosticPiece>> PiecesTy;
2998 
2999  MacroStackTy MacroStack;
3000  PiecesTy Pieces;
3001 
3002  for (PathPieces::const_iterator I = path.begin(), E = path.end();
3003  I!=E; ++I) {
3004 
3005  auto &piece = *I;
3006 
3007  // Recursively compact calls.
3008  if (auto *call = dyn_cast<PathDiagnosticCallPiece>(&*piece)) {
3009  CompactPathDiagnostic(call->path, SM);
3010  }
3011 
3012  // Get the location of the PathDiagnosticPiece.
3013  const FullSourceLoc Loc = piece->getLocation().asLocation();
3014 
3015  // Determine the instantiation location, which is the location we group
3016  // related PathDiagnosticPieces.
3017  SourceLocation InstantiationLoc = Loc.isMacroID() ?
3018  SM.getExpansionLoc(Loc) :
3019  SourceLocation();
3020 
3021  if (Loc.isFileID()) {
3022  MacroStack.clear();
3023  Pieces.push_back(piece);
3024  continue;
3025  }
3026 
3027  assert(Loc.isMacroID());
3028 
3029  // Is the PathDiagnosticPiece within the same macro group?
3030  if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
3031  MacroStack.back().first->subPieces.push_back(piece);
3032  continue;
3033  }
3034 
3035  // We aren't in the same group. Are we descending into a new macro
3036  // or are part of an old one?
3037  std::shared_ptr<PathDiagnosticMacroPiece> MacroGroup;
3038 
3039  SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
3040  SM.getExpansionLoc(Loc) :
3041  SourceLocation();
3042 
3043  // Walk the entire macro stack.
3044  while (!MacroStack.empty()) {
3045  if (InstantiationLoc == MacroStack.back().second) {
3046  MacroGroup = MacroStack.back().first;
3047  break;
3048  }
3049 
3050  if (ParentInstantiationLoc == MacroStack.back().second) {
3051  MacroGroup = MacroStack.back().first;
3052  break;
3053  }
3054 
3055  MacroStack.pop_back();
3056  }
3057 
3058  if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) {
3059  // Create a new macro group and add it to the stack.
3060  auto NewGroup = std::make_shared<PathDiagnosticMacroPiece>(
3061  PathDiagnosticLocation::createSingleLocation(piece->getLocation()));
3062 
3063  if (MacroGroup)
3064  MacroGroup->subPieces.push_back(NewGroup);
3065  else {
3066  assert(InstantiationLoc.isFileID());
3067  Pieces.push_back(NewGroup);
3068  }
3069 
3070  MacroGroup = NewGroup;
3071  MacroStack.push_back(std::make_pair(MacroGroup, InstantiationLoc));
3072  }
3073 
3074  // Finally, add the PathDiagnosticPiece to the group.
3075  MacroGroup->subPieces.push_back(piece);
3076  }
3077 
3078  // Now take the pieces and construct a new PathDiagnostic.
3079  path.clear();
3080 
3081  path.insert(path.end(), Pieces.begin(), Pieces.end());
3082 }
3083 
3086  ArrayRef<BugReport *> &bugReports) {
3087  assert(!bugReports.empty());
3088 
3089  bool HasValid = false;
3090  bool HasInvalid = false;
3092  for (ArrayRef<BugReport*>::iterator I = bugReports.begin(),
3093  E = bugReports.end(); I != E; ++I) {
3094  if ((*I)->isValid()) {
3095  HasValid = true;
3096  errorNodes.push_back((*I)->getErrorNode());
3097  } else {
3098  // Keep the errorNodes list in sync with the bugReports list.
3099  HasInvalid = true;
3100  errorNodes.push_back(nullptr);
3101  }
3102  }
3103 
3104  // If all the reports have been marked invalid by a previous path generation,
3105  // we're done.
3106  if (!HasValid)
3107  return false;
3108 
3109  typedef PathDiagnosticConsumer::PathGenerationScheme PathGenerationScheme;
3110  PathGenerationScheme ActiveScheme = PC.getGenerationScheme();
3111 
3112  if (ActiveScheme == PathDiagnosticConsumer::Extensive) {
3113  AnalyzerOptions &options = getAnalyzerOptions();
3114  if (options.getBooleanOption("path-diagnostics-alternate", true)) {
3116  }
3117  }
3118 
3119  TrimmedGraph TrimG(&getGraph(), errorNodes);
3120  ReportGraph ErrorGraph;
3121 
3122  while (TrimG.popNextReportGraph(ErrorGraph)) {
3123  // Find the BugReport with the original location.
3124  assert(ErrorGraph.Index < bugReports.size());
3125  BugReport *R = bugReports[ErrorGraph.Index];
3126  assert(R && "No original report found for sliced graph.");
3127  assert(R->isValid() && "Report selected by trimmed graph marked invalid.");
3128 
3129  // Start building the path diagnostic...
3130  PathDiagnosticBuilder PDB(*this, R, ErrorGraph.BackMap, &PC);
3131  const ExplodedNode *N = ErrorGraph.ErrorNode;
3132 
3133  // Register additional node visitors.
3134  R->addVisitor(llvm::make_unique<NilReceiverBRVisitor>());
3135  R->addVisitor(llvm::make_unique<ConditionBRVisitor>());
3136  R->addVisitor(llvm::make_unique<LikelyFalsePositiveSuppressionBRVisitor>());
3137  R->addVisitor(llvm::make_unique<CXXSelfAssignmentBRVisitor>());
3138 
3139  BugReport::VisitorList visitors;
3140  unsigned origReportConfigToken, finalReportConfigToken;
3141  LocationContextMap LCM;
3142 
3143  // While generating diagnostics, it's possible the visitors will decide
3144  // new symbols and regions are interesting, or add other visitors based on
3145  // the information they find. If they do, we need to regenerate the path
3146  // based on our new report configuration.
3147  do {
3148  // Get a clean copy of all the visitors.
3149  for (BugReport::visitor_iterator I = R->visitor_begin(),
3150  E = R->visitor_end(); I != E; ++I)
3151  visitors.push_back((*I)->clone());
3152 
3153  // Clear out the active path from any previous work.
3154  PD.resetPath();
3155  origReportConfigToken = R->getConfigurationChangeToken();
3156 
3157  // Generate the very last diagnostic piece - the piece is visible before
3158  // the trace is expanded.
3159  std::unique_ptr<PathDiagnosticPiece> LastPiece;
3160  for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
3161  I != E; ++I) {
3162  if (std::unique_ptr<PathDiagnosticPiece> Piece =
3163  (*I)->getEndPath(PDB, N, *R)) {
3164  assert (!LastPiece &&
3165  "There can only be one final piece in a diagnostic.");
3166  LastPiece = std::move(Piece);
3167  }
3168  }
3169 
3170  if (ActiveScheme != PathDiagnosticConsumer::None) {
3171  if (!LastPiece)
3172  LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
3173  assert(LastPiece);
3174  PD.setEndOfPath(std::move(LastPiece));
3175  }
3176 
3177  // Make sure we get a clean location context map so we don't
3178  // hold onto old mappings.
3179  LCM.clear();
3180 
3181  switch (ActiveScheme) {
3183  GenerateAlternateExtensivePathDiagnostic(PD, PDB, N, LCM, visitors);
3184  break;
3186  GenerateExtensivePathDiagnostic(PD, PDB, N, LCM, visitors);
3187  break;
3189  GenerateMinimalPathDiagnostic(PD, PDB, N, LCM, visitors);
3190  break;
3192  GenerateVisitorsOnlyPathDiagnostic(PD, PDB, N, visitors);
3193  break;
3194  }
3195 
3196  // Clean up the visitors we used.
3197  visitors.clear();
3198 
3199  // Did anything change while generating this path?
3200  finalReportConfigToken = R->getConfigurationChangeToken();
3201  } while (finalReportConfigToken != origReportConfigToken);
3202 
3203  if (!R->isValid())
3204  continue;
3205 
3206  // Finally, prune the diagnostic path of uninteresting stuff.
3207  if (!PD.path.empty()) {
3208  if (R->shouldPrunePath() && getAnalyzerOptions().shouldPrunePaths()) {
3209  bool stillHasNotes = removeUnneededCalls(PD.getMutablePieces(), R, LCM);
3210  assert(stillHasNotes);
3211  (void)stillHasNotes;
3212  }
3213 
3214  // Redirect all call pieces to have valid locations.
3217 
3218  if (ActiveScheme == PathDiagnosticConsumer::AlternateExtensive) {
3219  SourceManager &SM = getSourceManager();
3220 
3221  // Reduce the number of edges from a very conservative set
3222  // to an aesthetically pleasing subset that conveys the
3223  // necessary information.
3224  OptimizedCallsSet OCS;
3225  while (optimizeEdges(PD.getMutablePieces(), SM, OCS, LCM)) {}
3226 
3227  // Drop the very first function-entry edge. It's not really necessary
3228  // for top-level functions.
3230  }
3231 
3232  // Remove messages that are basically the same, and edges that may not
3233  // make sense.
3234  // We have to do this after edge optimization in the Extensive mode.
3237  }
3238 
3239  // We found a report and didn't suppress it.
3240  return true;
3241  }
3242 
3243  // We suppressed all the reports in this equivalence class.
3244  assert(!HasInvalid && "Inconsistent suppression");
3245  (void)HasInvalid;
3246  return false;
3247 }
3248 
3250  BugTypes = F.add(BugTypes, BT);
3251 }
3252 
3253 void BugReporter::emitReport(std::unique_ptr<BugReport> R) {
3254  if (const ExplodedNode *E = R->getErrorNode()) {
3255  // An error node must either be a sink or have a tag, otherwise
3256  // it could get reclaimed before the path diagnostic is created.
3257  assert((E->isSink() || E->getLocation().getTag()) &&
3258  "Error node must either be a sink or have a tag");
3259 
3260  const AnalysisDeclContext *DeclCtx =
3261  E->getLocationContext()->getAnalysisDeclContext();
3262  // The source of autosynthesized body can be handcrafted AST or a model
3263  // file. The locations from handcrafted ASTs have no valid source locations
3264  // and have to be discarded. Locations from model files should be preserved
3265  // for processing and reporting.
3266  if (DeclCtx->isBodyAutosynthesized() &&
3268  return;
3269  }
3270 
3271  bool ValidSourceLoc = R->getLocation(getSourceManager()).isValid();
3272  assert(ValidSourceLoc);
3273  // If we mess up in a release build, we'd still prefer to just drop the bug
3274  // instead of trying to go on.
3275  if (!ValidSourceLoc)
3276  return;
3277 
3278  // Compute the bug report's hash to determine its equivalence class.
3279  llvm::FoldingSetNodeID ID;
3280  R->Profile(ID);
3281 
3282  // Lookup the equivance class. If there isn't one, create it.
3283  BugType& BT = R->getBugType();
3284  Register(&BT);
3285  void *InsertPos;
3286  BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos);
3287 
3288  if (!EQ) {
3289  EQ = new BugReportEquivClass(std::move(R));
3290  EQClasses.InsertNode(EQ, InsertPos);
3291  EQClassesVector.push_back(EQ);
3292  } else
3293  EQ->AddReport(std::move(R));
3294 }
3295 
3296 
3297 //===----------------------------------------------------------------------===//
3298 // Emitting reports in equivalence classes.
3299 //===----------------------------------------------------------------------===//
3300 
3301 namespace {
3302 struct FRIEC_WLItem {
3303  const ExplodedNode *N;
3305 
3306  FRIEC_WLItem(const ExplodedNode *n)
3307  : N(n), I(N->succ_begin()), E(N->succ_end()) {}
3308 };
3309 }
3310 
3311 static const CFGBlock *findBlockForNode(const ExplodedNode *N) {
3312  ProgramPoint P = N->getLocation();
3313  if (auto BEP = P.getAs<BlockEntrance>())
3314  return BEP->getBlock();
3315 
3316  // Find the node's current statement in the CFG.
3317  if (const Stmt *S = PathDiagnosticLocation::getStmt(N))
3319  ->getCFGStmtMap()->getBlock(S);
3320 
3321  return nullptr;
3322 }
3323 
3324 // Returns true if by simply looking at the block, we can be sure that it
3325 // results in a sink during analysis. This is useful to know when the analysis
3326 // was interrupted, and we try to figure out if it would sink eventually.
3327 // There may be many more reasons why a sink would appear during analysis
3328 // (eg. checkers may generate sinks arbitrarily), but here we only consider
3329 // sinks that would be obvious by looking at the CFG.
3330 static bool isImmediateSinkBlock(const CFGBlock *Blk) {
3331  if (Blk->hasNoReturnElement())
3332  return true;
3333 
3334  // FIXME: Throw-expressions are currently generating sinks during analysis:
3335  // they're not supported yet, and also often used for actually terminating
3336  // the program. So we should treat them as sinks in this analysis as well,
3337  // at least for now, but once we have better support for exceptions,
3338  // we'd need to carefully handle the case when the throw is being
3339  // immediately caught.
3340  if (std::any_of(Blk->begin(), Blk->end(), [](const CFGElement &Elm) {
3341  if (Optional<CFGStmt> StmtElm = Elm.getAs<CFGStmt>())
3342  if (isa<CXXThrowExpr>(StmtElm->getStmt()))
3343  return true;
3344  return false;
3345  }))
3346  return true;
3347 
3348  return false;
3349 }
3350 
3351 // Returns true if by looking at the CFG surrounding the node's program
3352 // point, we can be sure that any analysis starting from this point would
3353 // eventually end with a sink. We scan the child CFG blocks in a depth-first
3354 // manner and see if all paths eventually end up in an immediate sink block.
3355 static bool isInevitablySinking(const ExplodedNode *N) {
3356  const CFG &Cfg = N->getCFG();
3357 
3358  const CFGBlock *StartBlk = findBlockForNode(N);
3359  if (!StartBlk)
3360  return false;
3361  if (isImmediateSinkBlock(StartBlk))
3362  return true;
3363 
3365  llvm::SmallPtrSet<const CFGBlock *, 32> Visited;
3366 
3367  DFSWorkList.push_back(StartBlk);
3368  while (!DFSWorkList.empty()) {
3369  const CFGBlock *Blk = DFSWorkList.back();
3370  DFSWorkList.pop_back();
3371  Visited.insert(Blk);
3372 
3373  for (const auto &Succ : Blk->succs()) {
3374  if (const CFGBlock *SuccBlk = Succ.getReachableBlock()) {
3375  if (SuccBlk == &Cfg.getExit()) {
3376  // If at least one path reaches the CFG exit, it means that control is
3377  // returned to the caller. For now, say that we are not sure what
3378  // happens next. If necessary, this can be improved to analyze
3379  // the parent StackFrameContext's call site in a similar manner.
3380  return false;
3381  }
3382 
3383  if (!isImmediateSinkBlock(SuccBlk) && !Visited.count(SuccBlk)) {
3384  // If the block has reachable child blocks that aren't no-return,
3385  // add them to the worklist.
3386  DFSWorkList.push_back(SuccBlk);
3387  }
3388  }
3389  }
3390  }
3391 
3392  // Nothing reached the exit. It can only mean one thing: there's no return.
3393  return true;
3394 }
3395 
3396 static BugReport *
3398  SmallVectorImpl<BugReport*> &bugReports) {
3399 
3400  BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
3401  assert(I != E);
3402  BugType& BT = I->getBugType();
3403 
3404  // If we don't need to suppress any of the nodes because they are
3405  // post-dominated by a sink, simply add all the nodes in the equivalence class
3406  // to 'Nodes'. Any of the reports will serve as a "representative" report.
3407  if (!BT.isSuppressOnSink()) {
3408  BugReport *R = &*I;
3409  for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) {
3410  const ExplodedNode *N = I->getErrorNode();
3411  if (N) {
3412  R = &*I;
3413  bugReports.push_back(R);
3414  }
3415  }
3416  return R;
3417  }
3418 
3419  // For bug reports that should be suppressed when all paths are post-dominated
3420  // by a sink node, iterate through the reports in the equivalence class
3421  // until we find one that isn't post-dominated (if one exists). We use a
3422  // DFS traversal of the ExplodedGraph to find a non-sink node. We could write
3423  // this as a recursive function, but we don't want to risk blowing out the
3424  // stack for very long paths.
3425  BugReport *exampleReport = nullptr;
3426 
3427  for (; I != E; ++I) {
3428  const ExplodedNode *errorNode = I->getErrorNode();
3429 
3430  if (!errorNode)
3431  continue;
3432  if (errorNode->isSink()) {
3433  llvm_unreachable(
3434  "BugType::isSuppressSink() should not be 'true' for sink end nodes");
3435  }
3436  // No successors? By definition this nodes isn't post-dominated by a sink.
3437  if (errorNode->succ_empty()) {
3438  bugReports.push_back(&*I);
3439  if (!exampleReport)
3440  exampleReport = &*I;
3441  continue;
3442  }
3443 
3444  // See if we are in a no-return CFG block. If so, treat this similarly
3445  // to being post-dominated by a sink. This works better when the analysis
3446  // is incomplete and we have never reached the no-return function call(s)
3447  // that we'd inevitably bump into on this path.
3448  if (isInevitablySinking(errorNode))
3449  continue;
3450 
3451  // At this point we know that 'N' is not a sink and it has at least one
3452  // successor. Use a DFS worklist to find a non-sink end-of-path node.
3453  typedef FRIEC_WLItem WLItem;
3454  typedef SmallVector<WLItem, 10> DFSWorkList;
3455  llvm::DenseMap<const ExplodedNode *, unsigned> Visited;
3456 
3457  DFSWorkList WL;
3458  WL.push_back(errorNode);
3459  Visited[errorNode] = 1;
3460 
3461  while (!WL.empty()) {
3462  WLItem &WI = WL.back();
3463  assert(!WI.N->succ_empty());
3464 
3465  for (; WI.I != WI.E; ++WI.I) {
3466  const ExplodedNode *Succ = *WI.I;
3467  // End-of-path node?
3468  if (Succ->succ_empty()) {
3469  // If we found an end-of-path node that is not a sink.
3470  if (!Succ->isSink()) {
3471  bugReports.push_back(&*I);
3472  if (!exampleReport)
3473  exampleReport = &*I;
3474  WL.clear();
3475  break;
3476  }
3477  // Found a sink? Continue on to the next successor.
3478  continue;
3479  }
3480  // Mark the successor as visited. If it hasn't been explored,
3481  // enqueue it to the DFS worklist.
3482  unsigned &mark = Visited[Succ];
3483  if (!mark) {
3484  mark = 1;
3485  WL.push_back(Succ);
3486  break;
3487  }
3488  }
3489 
3490  // The worklist may have been cleared at this point. First
3491  // check if it is empty before checking the last item.
3492  if (!WL.empty() && &WL.back() == &WI)
3493  WL.pop_back();
3494  }
3495  }
3496 
3497  // ExampleReport will be NULL if all the nodes in the equivalence class
3498  // were post-dominated by sinks.
3499  return exampleReport;
3500 }
3501 
3502 void BugReporter::FlushReport(BugReportEquivClass& EQ) {
3503  SmallVector<BugReport*, 10> bugReports;
3504  BugReport *exampleReport = FindReportInEquivalenceClass(EQ, bugReports);
3505  if (exampleReport) {
3506  for (PathDiagnosticConsumer *PDC : getPathDiagnosticConsumers()) {
3507  FlushReport(exampleReport, *PDC, bugReports);
3508  }
3509  }
3510 }
3511 
3512 void BugReporter::FlushReport(BugReport *exampleReport,
3514  ArrayRef<BugReport*> bugReports) {
3515 
3516  // FIXME: Make sure we use the 'R' for the path that was actually used.
3517  // Probably doesn't make a difference in practice.
3518  BugType& BT = exampleReport->getBugType();
3519 
3520  std::unique_ptr<PathDiagnostic> D(new PathDiagnostic(
3521  exampleReport->getBugType().getCheckName(),
3522  exampleReport->getDeclWithIssue(), exampleReport->getBugType().getName(),
3523  exampleReport->getDescription(),
3524  exampleReport->getShortDescription(/*Fallback=*/false), BT.getCategory(),
3525  exampleReport->getUniqueingLocation(),
3526  exampleReport->getUniqueingDecl()));
3527 
3528  if (exampleReport->isPathSensitive()) {
3529  // Generate the full path diagnostic, using the generation scheme
3530  // specified by the PathDiagnosticConsumer. Note that we have to generate
3531  // path diagnostics even for consumers which do not support paths, because
3532  // the BugReporterVisitors may mark this bug as a false positive.
3533  assert(!bugReports.empty());
3534 
3535  MaxBugClassSize.updateMax(bugReports.size());
3536 
3537  if (!generatePathDiagnostic(*D.get(), PD, bugReports))
3538  return;
3539 
3540  MaxValidBugClassSize.updateMax(bugReports.size());
3541 
3542  // Examine the report and see if the last piece is in a header. Reset the
3543  // report location to the last piece in the main source file.
3544  AnalyzerOptions &Opts = getAnalyzerOptions();
3545  if (Opts.shouldReportIssuesInMainSourceFile() && !Opts.AnalyzeAll)
3546  D->resetDiagnosticLocationToMainFile();
3547  }
3548 
3549  // If the path is empty, generate a single step path with the location
3550  // of the issue.
3551  if (D->path.empty()) {
3552  PathDiagnosticLocation L = exampleReport->getLocation(getSourceManager());
3553  auto piece = llvm::make_unique<PathDiagnosticEventPiece>(
3554  L, exampleReport->getDescription());
3555  for (SourceRange Range : exampleReport->getRanges())
3556  piece->addRange(Range);
3557  D->setEndOfPath(std::move(piece));
3558  }
3559 
3560  PathPieces &Pieces = D->getMutablePieces();
3561  if (getAnalyzerOptions().shouldDisplayNotesAsEvents()) {
3562  // For path diagnostic consumers that don't support extra notes,
3563  // we may optionally convert those to path notes.
3564  for (auto I = exampleReport->getNotes().rbegin(),
3565  E = exampleReport->getNotes().rend(); I != E; ++I) {
3566  PathDiagnosticNotePiece *Piece = I->get();
3567  auto ConvertedPiece = std::make_shared<PathDiagnosticEventPiece>(
3568  Piece->getLocation(), Piece->getString());
3569  for (const auto &R: Piece->getRanges())
3570  ConvertedPiece->addRange(R);
3571 
3572  Pieces.push_front(std::move(ConvertedPiece));
3573  }
3574  } else {
3575  for (auto I = exampleReport->getNotes().rbegin(),
3576  E = exampleReport->getNotes().rend(); I != E; ++I)
3577  Pieces.push_front(*I);
3578  }
3579 
3580  // Get the meta data.
3581  const BugReport::ExtraTextList &Meta = exampleReport->getExtraText();
3582  for (BugReport::ExtraTextList::const_iterator i = Meta.begin(),
3583  e = Meta.end(); i != e; ++i) {
3584  D->addMeta(*i);
3585  }
3586 
3587  PD.HandlePathDiagnostic(std::move(D));
3588 }
3589 
3590 void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
3591  const CheckerBase *Checker,
3592  StringRef Name, StringRef Category,
3593  StringRef Str, PathDiagnosticLocation Loc,
3594  ArrayRef<SourceRange> Ranges) {
3595  EmitBasicReport(DeclWithIssue, Checker->getCheckName(), Name, Category, Str,
3596  Loc, Ranges);
3597 }
3598 void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
3600  StringRef name, StringRef category,
3601  StringRef str, PathDiagnosticLocation Loc,
3602  ArrayRef<SourceRange> Ranges) {
3603 
3604  // 'BT' is owned by BugReporter.
3605  BugType *BT = getBugTypeForName(CheckName, name, category);
3606  auto R = llvm::make_unique<BugReport>(*BT, str, Loc);
3607  R->setDeclWithIssue(DeclWithIssue);
3608  for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
3609  I != E; ++I)
3610  R->addRange(*I);
3611  emitReport(std::move(R));
3612 }
3613 
3614 BugType *BugReporter::getBugTypeForName(CheckName CheckName, StringRef name,
3615  StringRef category) {
3616  SmallString<136> fullDesc;
3617  llvm::raw_svector_ostream(fullDesc) << CheckName.getName() << ":" << name
3618  << ":" << category;
3619  BugType *&BT = StrBugTypes[fullDesc];
3620  if (!BT)
3621  BT = new BugType(CheckName, name, category);
3622  return BT;
3623 }
3624 
3625 LLVM_DUMP_METHOD void PathPieces::dump() const {
3626  unsigned index = 0;
3627  for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
3628  llvm::errs() << "[" << index++ << "] ";
3629  (*I)->dump();
3630  llvm::errs() << "\n";
3631  }
3632 }
3633 
3634 LLVM_DUMP_METHOD void PathDiagnosticCallPiece::dump() const {
3635  llvm::errs() << "CALL\n--------------\n";
3636 
3637  if (const Stmt *SLoc = getLocStmt(getLocation()))
3638  SLoc->dump();
3639  else if (const NamedDecl *ND = dyn_cast<NamedDecl>(getCallee()))
3640  llvm::errs() << *ND << "\n";
3641  else
3642  getLocation().dump();
3643 }
3644 
3645 LLVM_DUMP_METHOD void PathDiagnosticEventPiece::dump() const {
3646  llvm::errs() << "EVENT\n--------------\n";
3647  llvm::errs() << getString() << "\n";
3648  llvm::errs() << " ---- at ----\n";
3649  getLocation().dump();
3650 }
3651 
3652 LLVM_DUMP_METHOD void PathDiagnosticControlFlowPiece::dump() const {
3653  llvm::errs() << "CONTROL\n--------------\n";
3654  getStartLocation().dump();
3655  llvm::errs() << " ---- to ----\n";
3656  getEndLocation().dump();
3657 }
3658 
3659 LLVM_DUMP_METHOD void PathDiagnosticMacroPiece::dump() const {
3660  llvm::errs() << "MACRO\n--------------\n";
3661  // FIXME: Print which macro is being invoked.
3662 }
3663 
3664 LLVM_DUMP_METHOD void PathDiagnosticNotePiece::dump() const {
3665  llvm::errs() << "NOTE\n--------------\n";
3666  llvm::errs() << getString() << "\n";
3667  llvm::errs() << " ---- at ----\n";
3668  getLocation().dump();
3669 }
3670 
3671 LLVM_DUMP_METHOD void PathDiagnosticLocation::dump() const {
3672  if (!isValid()) {
3673  llvm::errs() << "<INVALID>\n";
3674  return;
3675  }
3676 
3677  switch (K) {
3678  case RangeK:
3679  // FIXME: actually print the range.
3680  llvm::errs() << "<range>\n";
3681  break;
3682  case SingleLocK:
3683  asLocation().dump();
3684  llvm::errs() << "\n";
3685  break;
3686  case StmtK:
3687  if (S)
3688  S->dump();
3689  else
3690  llvm::errs() << "<NULL STMT>\n";
3691  break;
3692  case DeclK:
3693  if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
3694  llvm::errs() << *ND << "\n";
3695  else if (isa<BlockDecl>(D))
3696  // FIXME: Make this nicer.
3697  llvm::errs() << "<block>\n";
3698  else if (D)
3699  llvm::errs() << "<unknown decl>\n";
3700  else
3701  llvm::errs() << "<NULL DECL>\n";
3702  break;
3703  }
3704 }
Expr * getInc()
Definition: Stmt.h:1241
VisitorList::iterator visitor_iterator
Definition: BugReporter.h:67
Defines the clang::ASTContext interface.
static void removeEdgesToDefaultInitializers(PathPieces &Pieces)
Remove edges in and out of C++ default initializer expressions.
bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const
Returns true if the spelling locations for both SourceLocations are part of the same file buffer...
static bool isLoopJumpPastBody(const Stmt *Term, const BlockEdge *BE)
Return true if the terminator is a loop and the destination is the false branch.
static bool removeUnneededCalls(PathPieces &pieces, BugReport *R, LocationContextMap &LCM)
Recursively scan through a path and prune out calls and macros pieces that aren&#39;t needed...
An instance of this class is created to represent a function declaration or definition.
Definition: Decl.h:1697
Expr * getLHS() const
Definition: Expr.h:3314
static void removeRedundantMsgs(PathPieces &path)
An optimization pass over PathPieces that removes redundant diagnostics generated by both ConditionBR...
static bool isContainedByStmt(ParentMap &PM, const Stmt *S, const Stmt *SubS)
static Optional< size_t > getLengthOnSingleLine(SourceManager &SM, SourceRange Range)
Returns the number of bytes in the given (character-based) SourceRange.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:79
PathDiagnosticLocation getUniqueingLocation() const
Get the location on which the report should be uniqued.
Definition: BugReporter.h:308
bool isInteresting(SymbolRef sym)
PathDiagnosticLocation getLocation() const override
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
succ_iterator succ_begin()
Definition: CFG.h:624
FullSourceLoc getExpansionLoc() const
Stmt - This represents one statement.
Definition: Stmt.h:66
EnumConstantDecl - An instance of this object exists for each enum constant that is defined...
Definition: Decl.h:2671
Defines the SourceManager interface.
CheckName getCheckName() const
Definition: Checker.cpp:24
const CFGBlock * getSrc() const
Definition: ProgramPoint.h:480
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Represents a point when we begin processing an inlined call.
Definition: ProgramPoint.h:585
StringRef getDescription() const
Definition: BugReporter.h:196
Opcode getOpcode() const
Definition: Expr.h:3026
StringRef P
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:122
void Profile(llvm::FoldingSetNodeID &ID) const
SmallVector< StackDiagPair, 6 > StackDiagVector
Loc getLValue(const VarDecl *D, const LocationContext *LC) const
Get the lvalue for a variable reference.
Definition: ProgramState.h:708
iterator begin()
Definition: CFG.h:576
static void adjustCallLocations(PathPieces &Pieces, PathDiagnosticLocation *LastCallLocation=nullptr)
Recursively scan through a path and make sure that all call pieces have valid locations.
const ProgramStateRef & getState() const
static std::shared_ptr< PathDiagnosticCallPiece > construct(const ExplodedNode *N, const CallExitEnd &CE, const SourceManager &SM)
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
Definition: Decl.h:2176
PathDiagnosticLocation getStartLocation() const
virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const
Return the "definitive" location of the reported bug.
static PathDiagnosticLocation createEndBrace(const CompoundStmt *CS, const SourceManager &SM)
Create a location for the end of the compound statement.
unsigned succ_size() const
Definition: CFG.h:642
static bool optimizeEdges(PathPieces &path, SourceManager &SM, OptimizedCallsSet &OCS, LocationContextMap &LCM)
bool isConsumedExpr(Expr *E) const
Definition: ParentMap.cpp:159
static const Stmt * GetCurrentOrPreviousStmt(const ExplodedNode *N)
Definition: BugReporter.cpp:67
const Decl & getCodeDecl() const
static bool isConditionForTerminator(const Stmt *S, const Stmt *Cond)
Defines the Objective-C statement AST node classes.
static PathDiagnosticLocation createDeclEnd(const LocationContext *LC, const SourceManager &SM)
Constructs a location for the end of the enclosing declaration body.
ParmVarDecl - Represents a parameter to a function.
Definition: Decl.h:1513
Defines the clang::Expr interface and subclasses for C++ expressions.
static PathDiagnosticLocation createSingleLocation(const PathDiagnosticLocation &PDL)
Convert the given location into a single kind location.
static void removePiecesWithInvalidLocations(PathPieces &Pieces)
Remove all pieces with invalid locations as these cannot be serialized.
BoundNodesTreeBuilder Nodes
PathDiagnosticLocation getLocation() const
Symbolic value.
Definition: SymExpr.h:29
PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.
void setStartLocation(const PathDiagnosticLocation &L)
LineState State
bool isValid() const
Returns whether or not this report should be considered valid.
Definition: BugReporter.h:229
succ_iterator succ_begin()
static PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S, SourceManager &SMgr, const ParentMap &P, const LocationContext *LC, bool allowNestedContexts)
AnalysisDeclContext contains the context data for the function or method under analysis.
static void removeIdenticalEvents(PathPieces &path)
StringRef getName() const
Definition: BugType.h:49
static const char StrLoopBodyZero[]
std::unique_ptr< ExplodedGraph > trim(ArrayRef< const NodeTy *> Nodes, InterExplodedGraphMap *ForwardMap=nullptr, InterExplodedGraphMap *InverseMap=nullptr) const
Creates a trimmed version of the graph that only contains paths leading to the given nodes...
static const CFGBlock * findBlockForNode(const ExplodedNode *N)
succ_range succs()
Definition: CFG.h:634
void pushActivePath(PathPieces *p)
int Category
Definition: Format.cpp:1348
void addPredecessor(ExplodedNode *V, ExplodedGraph &G)
addPredeccessor - Adds a predecessor to the current node, and in tandem add this node as a successor ...
virtual bool supportsLogicalOpControlFlow() const
PathPieces & getMutablePieces()
Return a mutable version of &#39;path&#39;.
virtual llvm::iterator_range< ranges_iterator > getRanges()
Get the SourceRanges associated with the report.
static bool IsControlFlowExpr(const Stmt *S)
StringRef getCategory() const
Definition: BugType.h:50
const Stmt * getStmt() const
virtual void FlushReports(BugReporter &BR)
const BugType & getBugType() const
Definition: BugReporter.h:179
ForStmt - This represents a &#39;for (init;cond;inc)&#39; stmt.
Definition: Stmt.h:1207
static void addEdgeToPath(PathPieces &path, PathDiagnosticLocation &PrevLoc, PathDiagnosticLocation NewLoc, const LocationContext *LC)
Adds a sanitized control-flow diagnostic edge to a path.
static bool isJumpToFalseBranch(const BlockEdge *BE)
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
Stmt * getBody()
Definition: Stmt.h:1242
const StackFrameContext * getCurrentStackFrame() const
child_range children()
Definition: Stmt.cpp:226
const LocationContext * getLocationContext() const
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2985
CXXForRangeStmt - This represents C++0x [stmt.ranged]&#39;s ranged for statement, represented as &#39;for (ra...
Definition: StmtCXX.h:128
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
Definition: Expr.cpp:2465
bool generatePathDiagnostic(PathDiagnostic &PD, PathDiagnosticConsumer &PC, ArrayRef< BugReport *> &bugReports) override
Generates a path corresponding to one of the given bug reports.
const Decl * getDeclWithIssue() const
Return the canonical declaration, be it a method or class, where this issue semantically occurred...
static const Stmt * getStmtBeforeCond(ParentMap &PM, const Stmt *Term, const ExplodedNode *N)
ExplodedNode * getFirstPred()
static void reversePropagateIntererstingSymbols(BugReport &R, InterestingExprs &IE, const ProgramState *State, const Expr *Ex, const LocationContext *LCtx)
static BugReport * FindReportInEquivalenceClass(BugReportEquivClass &EQ, SmallVectorImpl< BugReport *> &bugReports)
void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)
Add custom or predefined bug report visitors to this report.
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const
Returns the SVal bound to the statement &#39;S&#39; in the state&#39;s environment.
Definition: ProgramState.h:742
PathDiagnosticLocation getEndLocation() const
virtual const NoteList & getNotes()
Definition: BugReporter.h:285
llvm::DenseSet< const Expr * > InterestingExprs
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Definition: SVals.cpp:116
NodeId Parent
Definition: ASTDiff.cpp:192
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:3269
Const iterator for iterating over Stmt * arrays that contain only Expr *.
Definition: Stmt.h:346
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:595
const Stmt * getCallSite() const
StringRef getName() const
const void * getTag() const
Return the opaque tag (if any) on the PathDiagnosticPiece.
llvm::DenseSet< const PathDiagnosticCallPiece * > OptimizedCallsSet
void HandlePathDiagnostic(std::unique_ptr< PathDiagnostic > D)
CFGBlock - Represents a single basic block in a source-level CFG.
Definition: CFG.h:422
llvm::DenseMap< const ExplodedNode *, const ExplodedNode * > InterExplodedGraphMap
static const char * getTag()
Return the tag associated with this visitor.
Represents a point when we finish the call exit sequence (for inlined call).
Definition: ProgramPoint.h:639
SymbolicRegion - A special, "non-concrete" region.
Definition: MemRegion.h:742
bool isBodyAutosynthesizedFromModelFile() const
Checks if the body of the Decl is generated by the BodyFarm from a model file.
virtual const ExtraTextList & getExtraText()
Definition: BugReporter.h:296
STATISTIC(MaxBugClassSize, "The maximum number of bug reports in the same equivalence class")
Expr * getCond() const
Definition: Expr.h:3303
ProgramState - This class encapsulates:
Definition: ProgramState.h:74
Expr - This represents one expression.
Definition: Expr.h:106
Stmt * getTerminatorCondition(bool StripParens=true)
Definition: CFG.cpp:4898
SourceLocation End
pred_iterator pred_end()
CFG - Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:834
const FunctionProtoType * T
static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece)
CFGBlock * getBlock(Stmt *S)
Returns the CFGBlock the specified Stmt* appears in.
Definition: CFGStmtMap.cpp:27
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:551
static bool lexicalContains(ParentMap &PM, const Stmt *X, const Stmt *Y)
Return true if X is contained by Y.
static void reversePropagateInterestingSymbols(BugReport &R, InterestingExprs &IE, const ProgramState *State, const LocationContext *CalleeCtx, const LocationContext *CallerCtx)
const SourceManager & getManager() const
const Decl * getUniqueingDecl() const
Get the declaration containing the uniqueing location.
Definition: BugReporter.h:313
void Register(BugType *BT)
static const Stmt * getNextStmt(const ExplodedNode *N)
Retrieve the statement corresponding to the successor node.
void FlushReports()
Generate and flush diagnostics for all bug reports.
const CFGBlock * getDst() const
Definition: ProgramPoint.h:484
static void dropFunctionEntryEdge(PathPieces &Path, LocationContextMap &LCM, SourceManager &SM)
Drop the very first edge in a path, which should be a function entry edge.
bool isBodyAutosynthesized() const
Checks if the body of the Decl is generated by the BodyFarm.
SourceLocation getEnd() const
void markInteresting(SymbolRef sym)
static const Stmt * GetPreviousStmt(const ExplodedNode *N)
Definition: BugReporter.cpp:58
unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool getBooleanOption(StringRef Name, bool DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Interprets an option&#39;s string value as a boolean.
const SourceManager & SM
Definition: Format.cpp:1337
ParentMap & getParentMap() const
static bool GenerateVisitorsOnlyPathDiagnostic(PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N, ArrayRef< std::unique_ptr< BugReporterVisitor >> visitors)
llvm::ilist< BugReport >::iterator iterator
Definition: BugReporter.h:376
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
Definition: DeclBase.h:984
BugReporter is a utility class for generating PathDiagnostics for analysis.
Definition: BugReporter.h:403
static const Stmt * getStmt(const ExplodedNode *N)
Given an exploded node, retrieve the statement that should be used for the diagnostic location...
unsigned getFileOffset(SourceLocation SpellingLoc) const
Returns the offset from the start of the file that the specified SourceLocation represents.
static PathDiagnosticLocation createDeclBegin(const LocationContext *LC, const SourceManager &SM)
Create a location for the beginning of the enclosing declaration body.
CFGTerminator getTerminator()
Definition: CFG.h:713
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
static PathDiagnosticEventPiece * eventsDescribeSameCondition(PathDiagnosticEventPiece *X, PathDiagnosticEventPiece *Y)
Definition: BugReporter.cpp:79
static std::unique_ptr< PathDiagnosticPiece > getDefaultEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR)
Generates the default final diagnostic piece.
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
static void simplifySimpleBranches(PathPieces &pieces)
Move edges from a branch condition to a branch target when the condition is simple.
Encodes a location in the source.
void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker, StringRef BugName, StringRef BugCategory, StringRef BugStr, PathDiagnosticLocation Loc, ArrayRef< SourceRange > Ranges=None)
Stmt * getLabel()
Definition: CFG.h:724
Stmt * getParentIgnoreParens(Stmt *) const
Definition: ParentMap.cpp:128
const ExplodedNode *const * const_succ_iterator
const MemRegion * getAsRegion() const
Definition: SVals.cpp:140
Expr * getLHS()
Definition: Stmt.h:764
ExplodedGraph & getGraph()
getGraph - Get the exploded graph created by the analysis engine for the analyzed method or function...
void emitReport(std::unique_ptr< BugReport > R)
Add the given report to the set of reports tracked by BugReporter.
static bool isIncrementOrInitInForLoop(const Stmt *S, const Stmt *FL)
void setCallee(const CallEnter &CE, const SourceManager &SM)
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
PathDiagnosticLocation getLocation() const override
static const Stmt * getEnclosingParent(const Stmt *S, const ParentMap &PM)
static bool isLogicalOp(Opcode Opc)
Definition: Expr.h:3105
static void removePunyEdges(PathPieces &path, SourceManager &SM, ParentMap &PM)
Expr * getLHS() const
Definition: Expr.h:3029
static bool hasImplicitBody(const Decl *D)
Returns true if the given decl has been implicitly given a body, either by the analyzer or by the com...
ast_type_traits::DynTypedNode Node
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
unsigned getExpansionColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
ArrayRef< SourceRange > getRanges() const
Return the SourceRanges associated with this PathDiagnosticPiece.
Dataflow Directional Tag Classes.
static const char StrLoopCollectionEmpty[]
bool isValid() const
Return true if this is a valid SourceLocation object.
static const Stmt * getLocStmt(PathDiagnosticLocation L)
std::pair< SourceLocation, SourceLocation > getExpansionRange(SourceLocation Loc) const
Given a SourceLocation object, return the range of tokens covered by the expansion in the ultimate fi...
PathDiagnosticRange asRange() const
StmtClass getStmtClass() const
Definition: Stmt.h:378
static void updateStackPiecesWithMessage(PathDiagnosticPiece &P, StackDiagVector &CallStack)
StringRef getCheckName() const
Definition: BugType.h:51
static bool GenerateMinimalPathDiagnostic(PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N, LocationContextMap &LCM, ArrayRef< std::unique_ptr< BugReporterVisitor >> visitors)
static const Stmt * getTerminatorCondition(const CFGBlock *B)
A customized wrapper for CFGBlock::getTerminatorCondition() which returns the element for ObjCForColl...
const Decl * getDecl() const
unsigned getExpansionLineNumber(bool *Invalid=nullptr) const
bool isMacroID() const
static bool isLoop(const Stmt *Term)
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
virtual PathGenerationScheme getGenerationScheme() const
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Definition: ASTDumper.cpp:2745
const ExplodedNode *const * const_pred_iterator
Represents Objective-C&#39;s collection statement.
Definition: StmtObjC.h:24
succ_iterator succ_end()
void setEndOfPath(std::unique_ptr< PathDiagnosticPiece > EndPiece)
const ExplodedNode * getErrorNode() const
Definition: BugReporter.h:194
const LocationContext * getLocationContext() const
Definition: ProgramPoint.h:179
virtual void Profile(llvm::FoldingSetNodeID &hash) const
Profile to identify equivalent bug reports for error report coalescing.
SVal getRawSVal(Loc LV, QualType T=QualType()) const
Returns the "raw" SVal bound to LV before any value simplfication.
Definition: ProgramState.h:761
SymbolMetadata - Represents path-dependent metadata about a specific region.
StringRef getShortDescription(bool UseFallback=true) const
Definition: BugReporter.h:198
static bool isInevitablySinking(const ExplodedNode *N)
bool hasNoReturnElement() const
Definition: CFG.h:727
static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO, const SourceManager &SM)
Create the location for the operator of the binary expression.
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:13010
ProgramStateManager & getStateManager()
getStateManager - Return the state manager used by the analysis engine.
static void CompactPathDiagnostic(PathPieces &path, const SourceManager &SM)
CompactPathDiagnostic - This function postprocesses a PathDiagnostic object and collapses PathDiagost...
PathPieces & getActivePath()
Return the path currently used by builders for constructing the PathDiagnostic.
pred_iterator pred_begin()
Expr * getRHS() const
Definition: Expr.h:3315
static const Stmt * getStmtParent(const Stmt *S, const ParentMap &PM)
WhileStmt - This represents a &#39;while&#39; stmt.
Definition: Stmt.h:1102
static PathDiagnosticLocation createEndOfPath(const ExplodedNode *N, const SourceManager &SM)
Create a location corresponding to the next valid ExplodedNode as end of path location.
llvm::DenseMap< const PathPieces *, const LocationContext * > LocationContextMap
A map from PathDiagnosticPiece to the LocationContext of the inlined function call it represents...
CFGElement - Represents a top-level expression in a basic block.
Definition: CFG.h:54
static void removeContextCycles(PathPieces &Path, SourceManager &SM, ParentMap &PM)
Eliminate two-edge cycles created by addContextEdges().
const MemRegion * getBaseRegion() const
Definition: MemRegion.cpp:1093
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:265
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2209
static bool isImmediateSinkBlock(const CFGBlock *Blk)
static bool GenerateAlternateExtensivePathDiagnostic(PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N, LocationContextMap &LCM, ArrayRef< std::unique_ptr< BugReporterVisitor >> visitors)
A SourceLocation and its associated SourceManager.
PathDiagnosticLocation callEnterWithin
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:956
Expr * getRHS() const
Definition: Expr.h:3031
bool isSuppressOnSink() const
isSuppressOnSink - Returns true if bug reports associated with this bug type should be suppressed if ...
Definition: BugType.h:66
static bool GenerateExtensivePathDiagnostic(PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N, LocationContextMap &LCM, ArrayRef< std::unique_ptr< BugReporterVisitor >> visitors)
DeclStmt * getLoopVarStmt()
Definition: StmtCXX.h:161
A trivial tuple used to represent a source range.
static void addContextEdges(PathPieces &pieces, SourceManager &SM, const ParentMap &PM, const LocationContext *LCtx)
Adds synthetic edges from top-level statements to their subexpressions.
NamedDecl - This represents a decl with a name.
Definition: Decl.h:245
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Definition: ProgramPoint.h:151
This class provides an interface through which checkers can create individual bug reports...
Definition: BugReporter.h:55
iterator end()
Definition: CFG.h:577
AnalysisDeclContext * getAnalysisDeclContext() const
bool shouldReportIssuesInMainSourceFile()
Returns whether or not the diagnostic report should be always reported in the main source file and no...
static const char StrEnteringLoop[]
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.cpp:277
SourceLocation getBegin() const
std::pair< PathDiagnosticCallPiece *, const ExplodedNode * > StackDiagPair
static const char StrLoopRangeEmpty[]
This class handles loading and caching of source files into memory.
bool isPathSensitive() const
True when the report has an execution path associated with it.
Definition: BugReporter.h:192
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Definition: Expr.cpp:2434
static const char * getTag()
Return the tag associated with this visitor.
CFGBlock & getExit()
Definition: CFG.h:923
static bool isInLoopBody(ParentMap &PM, const Stmt *S, const Stmt *Term)