BugReporter.cpp revision 77d09441e59d3bced6c3d55505eb3a67a784fe02
161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// BugReporter.cpp - Generate PathDiagnostics for Bugs ------------*- C++ -*--//
261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//                     The LLVM Compiler Infrastructure
461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// This file is distributed under the University of Illinois Open Source
661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek// License. See LICENSE.TXT for details.
761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//===----------------------------------------------------------------------===//
961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
1061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//  This file defines BugReporter, a utility class for generating
116c07bdba93b095b66e2c8c82dd5ed458fa8285eaTed Kremenek//  PathDiagnostics.
1261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//
1361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek//===----------------------------------------------------------------------===//
1461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
159b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
169b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
179b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
1861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#include "clang/AST/ASTContext.h"
19e41611aa2237d06a0ef61db4528fb2883a8defcdTed Kremenek#include "clang/Analysis/CFG.h"
20c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer#include "clang/AST/DeclObjC.h"
2161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#include "clang/AST/Expr.h"
2200605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek#include "clang/AST/ParentMap.h"
2316f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/StmtObjC.h"
2416f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/Basic/SourceManager.h"
2561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek#include "clang/Analysis/ProgramPoint.h"
269b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
27405674c26c52b05df0d833fae6bae818cd52bc32Chris Lattner#include "llvm/Support/raw_ostream.h"
28331b0ac44b9eb0ffcba66b4f3f3f9adb27c2434fTed Kremenek#include "llvm/ADT/DenseMap.h"
298fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h"
30cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek#include "llvm/ADT/STLExtras.h"
3100605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek#include "llvm/ADT/OwningPtr.h"
32802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek#include "llvm/ADT/IntrusiveRefCntPtr.h"
3310aa55410bbecbb658ce14a5f801d50cf06d12dfTed Kremenek#include <queue>
3461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
3561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenekusing namespace clang;
369ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
3761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
388966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed KremenekBugReporterVisitor::~BugReporterVisitor() {}
391b431023814196f87515a540ebcb9e9f1a9176a1Ted Kremenek
4099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid BugReporterContext::anchor() {}
4199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
42cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
433106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Helper routines for walking the ExplodedGraph and fetching statements.
44cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
4561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
469c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic inline const Stmt *GetStmt(const ProgramPoint &P) {
47592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek  if (const StmtPoint* SP = dyn_cast<StmtPoint>(&P))
48592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek    return SP->getStmt();
499c378f705405d37f49795d5e915989de774fe11fTed Kremenek  else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
5061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek    return BE->getSrc()->getTerminator();
511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return 0;
5361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
5461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
55c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic inline const ExplodedNode*
569c378f705405d37f49795d5e915989de774fe11fTed KremenekGetPredecessorNode(const ExplodedNode *N) {
57b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return N->pred_empty() ? NULL : *(N->pred_begin());
58706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek}
59706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek
60c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic inline const ExplodedNode*
619c378f705405d37f49795d5e915989de774fe11fTed KremenekGetSuccessorNode(const ExplodedNode *N) {
62b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return N->succ_empty() ? NULL : *(N->succ_begin());
63bd7efa8ca27ed9676acf00abf31d5e1cd54651ccTed Kremenek}
642673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek
659c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic const Stmt *GetPreviousStmt(const ExplodedNode *N) {
66b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  for (N = GetPredecessorNode(N); N; N = GetPredecessorNode(N))
675f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    if (const Stmt *S = GetStmt(N->getLocation()))
68b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek      return S;
691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return 0;
71b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek}
72b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek
739c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic const Stmt *GetNextStmt(const ExplodedNode *N) {
74b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  for (N = GetSuccessorNode(N); N; N = GetSuccessorNode(N))
755f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    if (const Stmt *S = GetStmt(N->getLocation())) {
76f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek      // Check if the statement is '?' or '&&'/'||'.  These are "merges",
77f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek      // not actual statement points.
78f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek      switch (S->getStmtClass()) {
79f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        case Stmt::ChooseExprClass:
8056ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        case Stmt::BinaryConditionalOperatorClass: continue;
81f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        case Stmt::ConditionalOperatorClass: continue;
82f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        case Stmt::BinaryOperatorClass: {
832de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall          BinaryOperatorKind Op = cast<BinaryOperator>(S)->getOpcode();
842de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall          if (Op == BO_LAnd || Op == BO_LOr)
85f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            continue;
86f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek          break;
87f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        }
88f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        default:
89f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek          break;
90f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek      }
91b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek      return S;
92f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek    }
931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
94b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return 0;
95bd7efa8ca27ed9676acf00abf31d5e1cd54651ccTed Kremenek}
96bd7efa8ca27ed9676acf00abf31d5e1cd54651ccTed Kremenek
975f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekstatic inline const Stmt*
989c378f705405d37f49795d5e915989de774fe11fTed KremenekGetCurrentOrPreviousStmt(const ExplodedNode *N) {
995f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (const Stmt *S = GetStmt(N->getLocation()))
100b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    return S;
1011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
102b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return GetPreviousStmt(N);
103b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek}
1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1055f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekstatic inline const Stmt*
1069c378f705405d37f49795d5e915989de774fe11fTed KremenekGetCurrentOrNextStmt(const ExplodedNode *N) {
1075f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (const Stmt *S = GetStmt(N->getLocation()))
108b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    return S;
1091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
110b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return GetNextStmt(N);
1113148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek}
1123148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek
113b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek//===----------------------------------------------------------------------===//
114c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek// Diagnostic cleanup.
115c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek//===----------------------------------------------------------------------===//
116c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
117c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek/// Recursively scan through a path and prune out calls and macros pieces
118c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek/// that aren't needed.  Return true if afterwards the path contains
119c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek/// "interesting stuff" which means it should be pruned from the parent path.
120c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenekstatic bool RemoveUneededCalls(PathPieces &pieces) {
121c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  bool containsSomethingInteresting = false;
122c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  const unsigned N = pieces.size();
123c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
124c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  for (unsigned i = 0 ; i < N ; ++i) {
125c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    // Remove the front piece from the path.  If it is still something we
126c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    // want to keep once we are done, we will push it back on the end.
127c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    IntrusiveRefCntPtr<PathDiagnosticPiece> piece(pieces.front());
128c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    pieces.pop_front();
129c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
130725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek    switch (piece->getKind()) {
131725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::Call: {
132725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        PathDiagnosticCallPiece *call = cast<PathDiagnosticCallPiece>(piece);
133725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        // Recursively clean out the subclass.  Keep this call around if
134725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        // it contains any informative diagnostics.
135725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        if (!RemoveUneededCalls(call->path))
136725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek          continue;
137725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        containsSomethingInteresting = true;
138725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
139725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      }
140725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::Macro: {
141725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        PathDiagnosticMacroPiece *macro = cast<PathDiagnosticMacroPiece>(piece);
142725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        if (!RemoveUneededCalls(macro->subPieces))
143725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek          continue;
144c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek        containsSomethingInteresting = true;
145725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
146725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      }
147725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::Event: {
148725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        PathDiagnosticEventPiece *event = cast<PathDiagnosticEventPiece>(piece);
149725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        // We never throw away an event, but we do throw it away wholesale
150725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        // as part of a path if we throw the entire path away.
151725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        if (!event->isPrunable())
152725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek          containsSomethingInteresting = true;
153725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
154725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      }
155725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::ControlFlow:
156725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
157c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    }
158c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
159c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    pieces.push_back(piece);
160c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  }
161c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
162c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  return containsSomethingInteresting;
163c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek}
164c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
165c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek//===----------------------------------------------------------------------===//
1663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// PathDiagnosticBuilder and its associated routines and helper objects.
167b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek//===----------------------------------------------------------------------===//
168b479dadea93b93d3f0a335c3518b703f140b3f50Ted Kremenek
169c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xutypedef llvm::DenseMap<const ExplodedNode*,
170c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuconst ExplodedNode*> NodeBackMap;
1717dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek
172babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremeneknamespace {
173ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass NodeMapClosure : public BugReport::NodeResolver {
1747dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeBackMap& M;
1757dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenekpublic:
1767dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeMapClosure(NodeBackMap *m) : M(*m) {}
1777dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  ~NodeMapClosure() {}
1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1799c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *getOriginalNode(const ExplodedNode *N) {
1807dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    NodeBackMap::iterator I = M.find(N);
1817dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    return I == M.end() ? 0 : I->second;
1827dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  }
1837dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek};
1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
185ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass PathDiagnosticBuilder : public BugReporterContext {
1867dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  BugReport *R;
187ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer *PDC;
1886f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ParentMap> PM;
1897dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeMapClosure NMC;
1901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
19159950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  const LocationContext *LC;
19259950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek
1938966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  PathDiagnosticBuilder(GRBugReporter &br,
1941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        BugReport *r, NodeBackMap *Backmap,
195ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie                        PathDiagnosticConsumer *pdc)
1968966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    : BugReporterContext(br),
19759950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek      R(r), PDC(pdc), NMC(Backmap), LC(r->getErrorNode()->getLocationContext())
19859950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  {}
1991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2009c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PathDiagnosticLocation ExecutionContinues(const ExplodedNode *N);
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2029c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream &os,
2039c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                            const ExplodedNode *N);
2041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2058e6431adab313e283a992698f6fc7afe62420999Anna Zaks  BugReport *getBugReport() { return R; }
2068e6431adab313e283a992698f6fc7afe62420999Anna Zaks
207212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care  Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); }
20859950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek
20959950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  ParentMap& getParentMap() { return LC->getParentMap(); }
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
211c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek  const Stmt *getParent(const Stmt *S) {
212c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek    return getParentMap().getParent(S);
213c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek  }
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2158966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual NodeMapClosure& getNodeResolver() { return NMC; }
2167297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor
217d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S);
2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
219ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer::PathGenerationScheme getGenerationScheme() const {
220ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    return PDC ? PDC->getGenerationScheme() : PathDiagnosticConsumer::Extensive;
2217dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  }
2227dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek
223babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek  bool supportsLogicalOpControlFlow() const {
224babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek    return PDC ? PDC->supportsLogicalOpControlFlow() : true;
2251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
226babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek};
227babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek} // end anonymous namespace
228babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek
22900605e0f011ed99225a22026344c5fc1b3212cd7Ted KremenekPathDiagnosticLocation
2309c378f705405d37f49795d5e915989de774fe11fTed KremenekPathDiagnosticBuilder::ExecutionContinues(const ExplodedNode *N) {
2315f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (const Stmt *S = GetNextStmt(N))
23259950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek    return PathDiagnosticLocation(S, getSourceManager(), LC);
23300605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek
2340cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks  return PathDiagnosticLocation::createDeclEnd(N->getLocationContext(),
2350cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                                               getSourceManager());
236082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek}
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23800605e0f011ed99225a22026344c5fc1b3212cd7Ted KremenekPathDiagnosticLocation
2399c378f705405d37f49795d5e915989de774fe11fTed KremenekPathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream &os,
2409c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                          const ExplodedNode *N) {
241babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek
242143ca222583a4a355fdc89af852deef287499300Ted Kremenek  // Slow, but probably doesn't matter.
243b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  if (os.str().empty())
244b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    os << ' ';
2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24600605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek  const PathDiagnosticLocation &Loc = ExecutionContinues(N);
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24800605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek  if (Loc.asStmt())
249b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    os << "Execution continues on line "
250642116259e8df6286063a17361c20e95b5017a0aChandler Carruth       << getSourceManager().getExpansionLineNumber(Loc.asLocation())
2518966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek       << '.';
2524f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek  else {
2534f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    os << "Execution jumps to the end of the ";
2544f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    const Decl *D = N->getLocationContext()->getDecl();
2554f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    if (isa<ObjCMethodDecl>(D))
2564f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "method";
2574f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    else if (isa<FunctionDecl>(D))
2584f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "function";
2594f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    else {
2604f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      assert(isa<BlockDecl>(D));
2614f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "anonymous block";
2624f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    }
2634f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    os << '.';
2644f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek  }
2651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
266082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek  return Loc;
267143ca222583a4a355fdc89af852deef287499300Ted Kremenek}
268143ca222583a4a355fdc89af852deef287499300Ted Kremenek
269ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenekstatic bool IsNested(const Stmt *S, ParentMap &PM) {
270ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  if (isa<Expr>(S) && PM.isConsumedExpr(cast<Expr>(S)))
271ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    return true;
2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
273ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  const Stmt *Parent = PM.getParentIgnoreParens(S);
2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
275ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  if (Parent)
276ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    switch (Parent->getStmtClass()) {
277ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::ForStmtClass:
278ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::DoStmtClass:
279ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::WhileStmtClass:
280ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        return true;
281ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      default:
282ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        break;
283ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    }
2841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return false;
286ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek}
287ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek
288d8c938b0f6b7a7156181be575239e4c6e15a2adbTed KremenekPathDiagnosticLocation
289d8c938b0f6b7a7156181be575239e4c6e15a2adbTed KremenekPathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
2909c378f705405d37f49795d5e915989de774fe11fTed Kremenek  assert(S && "Null Stmt *passed to getEnclosingStmtLocation");
2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ParentMap &P = getParentMap();
2928966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  SourceManager &SMgr = getSourceManager();
293e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
294ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  while (IsNested(S, P)) {
2958c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    const Stmt *Parent = P.getParentIgnoreParens(S);
2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
297af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    if (!Parent)
298af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      break;
2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
300af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    switch (Parent->getStmtClass()) {
3015fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      case Stmt::BinaryOperatorClass: {
3025fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        const BinaryOperator *B = cast<BinaryOperator>(Parent);
3035fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        if (B->isLogicalOp())
304220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
3055fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        break;
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
307af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::CompoundStmtClass:
308af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::StmtExprClass:
309220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks        return PathDiagnosticLocation(S, SMgr, LC);
3101d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek      case Stmt::ChooseExprClass:
3111d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // Similar to '?' if we are referring to condition, just have the edge
3121d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // point to the entire choose expression.
3131d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        if (cast<ChooseExpr>(Parent)->getCond() == S)
314220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
3151d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        else
316220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
31756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      case Stmt::BinaryConditionalOperatorClass:
3181d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek      case Stmt::ConditionalOperatorClass:
3191d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // For '?', if we are referring to condition, just have the edge point
3201d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // to the entire '?' expression.
32156ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        if (cast<AbstractConditionalOperator>(Parent)->getCond() == S)
322220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
3231d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        else
324220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
325af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::DoStmtClass:
326220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
327af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::ForStmtClass:
328af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<ForStmt>(Parent)->getBody() == S)
329220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        break;
331af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::IfStmtClass:
332af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<IfStmt>(Parent)->getCond() != S)
333220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
3348bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek        break;
335af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::ObjCForCollectionStmtClass:
336af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<ObjCForCollectionStmt>(Parent)->getBody() == S)
337220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
338af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
339af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::WhileStmtClass:
340af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<WhileStmt>(Parent)->getCond() != S)
341220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
342af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
343af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      default:
344af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
345af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    }
346af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek
347d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek    S = Parent;
348d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  }
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
350d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  assert(S && "Cannot have null Stmt for PathDiagnosticLocation");
351e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
352e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  // Special case: DeclStmts can appear in for statement declarations, in which
353e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  //  case the ForStmt is the context.
354e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  if (isa<DeclStmt>(S)) {
355e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    if (const Stmt *Parent = P.getParent(S)) {
356e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek      switch (Parent->getStmtClass()) {
357e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        case Stmt::ForStmtClass:
358e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        case Stmt::ObjCForCollectionStmtClass:
359220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
360e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        default:
361e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek          break;
3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
364e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  }
365e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  else if (isa<BinaryOperator>(S)) {
366e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // Special case: the binary operator represents the initialization
367e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // code in a for statement (this can happen when the variable being
368e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // initialized is an old variable.
369e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    if (const ForStmt *FS =
370e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek          dyn_cast_or_null<ForStmt>(P.getParentIgnoreParens(S))) {
371e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek      if (FS->getInit() == S)
372220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks        return PathDiagnosticLocation(FS, SMgr, LC);
373e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    }
374e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  }
375e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
376220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks  return PathDiagnosticLocation(S, SMgr, LC);
377d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek}
378d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
379cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
3803106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// ScanNotableSymbols: closure-like callback for scanning Store bindings.
381cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
382cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
38318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenekstatic const VarDecl* GetMostRecentVarDeclBinding(const ExplodedNode *N,
38418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                                  ProgramStateManager& VMgr,
38518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                                                  SVal X) {
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3873106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) {
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3893106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    ProgramPoint P = N->getLocation();
3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3913106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!isa<PostStmt>(P))
3923106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3949c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(cast<PostStmt>(P).getStmt());
3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3963106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!DR)
3973106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3995eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    SVal Y = N->getState()->getSVal(DR, N->getLocationContext());
4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (X != Y)
4023106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
4031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4049c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!VD)
4073106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4093106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    return VD;
410cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  }
4111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4123106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  return 0;
413bb77e9b908658b354b058509d3801f3aed052becTed Kremenek}
414bb77e9b908658b354b058509d3801f3aed052becTed Kremenek
4153106198188ac6eb2753f1764d5c28376b0b76351Ted Kremeneknamespace {
416ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass NotableSymbolHandler
4173106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek: public StoreManager::BindingsHandler {
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  SymbolRef Sym;
4208bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef PrevSt;
4219c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Stmt *S;
42218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  ProgramStateManager& VMgr;
4239c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *Pred;
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  PathDiagnostic& PD;
4253106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  BugReporter& BR;
4261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4273106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekpublic:
4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  NotableSymbolHandler(SymbolRef sym,
4308bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek                       ProgramStateRef prevst,
43118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                       const Stmt *s,
43218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                       ProgramStateManager& vmgr,
43318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                       const ExplodedNode *pred,
43418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                       PathDiagnostic& pd,
43518c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek                       BugReporter& br)
43618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  : Sym(sym),
43718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    PrevSt(prevst),
43818c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    S(s),
43918c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    VMgr(vmgr),
44018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    Pred(pred),
44118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    PD(pd),
44218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek    BR(br) {}
4431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4443106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
4453106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                     SVal V) {
4461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4473106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    SymbolRef ScanSym = V.getAsSymbol();
4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4493106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (ScanSym != Sym)
4503106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      return true;
4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Check if the previous state has this binding.
4531397663af9dbcc24dbf0e11de43931b3dc08fdbbTed Kremenek    SVal X = PrevSt->getSVal(loc::MemRegionVal(R));
4541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (X == V) // Same binding?
4563106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      return true;
4571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4583106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Different binding.  Only handle assignments for now.  We don't pull
4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // this check out of the loop because we will eventually handle other
4603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // cases.
4611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4623106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    VarDecl *VD = 0;
4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4643106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (const BinaryOperator* B = dyn_cast<BinaryOperator>(S)) {
4653106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (!B->isAssignmentOp())
4663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        return true;
4671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4683106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // What variable did we assign to?
4699c378f705405d37f49795d5e915989de774fe11fTed Kremenek      DeclRefExpr *DR = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParenCasts());
4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4713106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (!DR)
4723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        return true;
4731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4743106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      VD = dyn_cast<VarDecl>(DR->getDecl());
4753106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
4769c378f705405d37f49795d5e915989de774fe11fTed Kremenek    else if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
4773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // FIXME: Eventually CFGs won't have DeclStmts.  Right now we
4783106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      //  assume that each DeclStmt has a single Decl.  This invariant
479fc8f0e14ad142ed811e90fbd9a30e419e301c717Chris Lattner      //  holds by construction in the CFG.
4803106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      VD = dyn_cast<VarDecl>(*DS->decl_begin());
4813106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4833106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!VD)
4843106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      return true;
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4863106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // What is the most recently referenced variable with this binding?
4879c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const VarDecl *MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V);
4881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4893106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!MostRecent)
4903106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      return true;
4911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4923106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Create the diagnostic.
4937dfc9420babe83e236a47e752f8723bd06070d9dZhanyong Wan    if (Loc::isLocType(VD->getType())) {
494f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith      SmallString<64> buf;
4957df1234c2e62b2a23dc4417e527f941c20ebe858Jordy Rose      llvm::raw_svector_ostream os(buf);
496b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer      os << '\'' << *VD << "' now aliases '" << *MostRecent << '\'';
497590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      PathDiagnosticLocation L =
498590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        PathDiagnosticLocation::createBegin(S, BR.getSourceManager(),
499590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                                   Pred->getLocationContext());
5002042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PD.getActivePath().push_front(new PathDiagnosticEventPiece(L, os.str()));
5013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
5021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5033106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    return true;
5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
5053106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek};
5063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
5073106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
5089c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic void HandleNotableSymbol(const ExplodedNode *N,
5099c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                const Stmt *S,
5103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                SymbolRef Sym, BugReporter& BR,
5113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                PathDiagnostic& PD) {
5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5139c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *Pred = N->pred_empty() ? 0 : *N->pred_begin();
5148bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef PrevSt = Pred ? Pred->getState() : 0;
5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  if (!PrevSt)
5173106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    return;
5181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Look at the region bindings of the current state that map to the
5203106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // specified symbol.  Are any of them not in the previous state?
52118c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek  ProgramStateManager& VMgr = cast<GRBugReporter>(BR).getStateManager();
5223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  NotableSymbolHandler H(Sym, PrevSt, S, VMgr, Pred, PD, BR);
5233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  cast<GRBugReporter>(BR).getStateManager().iterBindings(N->getState(), H);
52461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
52561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
5263106198188ac6eb2753f1764d5c28376b0b76351Ted Kremeneknamespace {
527ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass ScanNotableSymbols
5283106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek: public StoreManager::BindingsHandler {
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  llvm::SmallSet<SymbolRef, 10> AlreadyProcessed;
5319c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *N;
5329c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const Stmt *S;
5333106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  GRBugReporter& BR;
5343106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  PathDiagnostic& PD;
5351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5363106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekpublic:
5379c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ScanNotableSymbols(const ExplodedNode *n, const Stmt *s,
5385f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek                     GRBugReporter& br, PathDiagnostic& pd)
5393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  : N(n), S(s), BR(br), PD(pd) {}
5401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5413106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  bool HandleBinding(StoreManager& SMgr, Store store,
5423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                     const MemRegion* R, SVal V) {
5431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5443106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    SymbolRef ScanSym = V.getAsSymbol();
5451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!ScanSym)
5473106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      return true;
5481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5493106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!BR.isNotable(ScanSym))
5503106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      return true;
5511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5523106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (AlreadyProcessed.count(ScanSym))
5533106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      return true;
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    AlreadyProcessed.insert(ScanSym);
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5573106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    HandleNotableSymbol(N, S, ScanSym, BR, PD);
5583106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    return true;
559bb77e9b908658b354b058509d3801f3aed052becTed Kremenek  }
5603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek};
5613106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek} // end anonymous namespace
56250a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek
563cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
5643106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// "Minimal" path diagnostic generation algorithm.
565cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
566cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
56777d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenekstatic void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
56814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
5693106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekstatic void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
5703106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                          PathDiagnosticBuilder &PDB,
571c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                                          const ExplodedNode *N) {
5728966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
5733106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  SourceManager& SMgr = PDB.getSourceManager();
57459950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  const LocationContext *LC = PDB.LC;
5759c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *NextNode = N->pred_empty()
5763106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                        ? NULL : *(N->pred_begin());
5773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  while (NextNode) {
5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    N = NextNode;
57959950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek    PDB.LC = N->getLocationContext();
5803106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    NextNode = GetPredecessorNode(N);
5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
58261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek    ProgramPoint P = N->getLocation();
5832042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek
5842042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    if (const CallExit *CE = dyn_cast<CallExit>(&P)) {
5852042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PathDiagnosticCallPiece *C =
5862042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PathDiagnosticCallPiece::construct(N, *CE, SMgr);
5872042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PD.getActivePath().push_front(C);
5882042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PD.pushActivePath(&C->path);
5892042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      continue;
5902042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    }
5912042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek
5922042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
5932042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PD.popActivePath();
5942042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // The current active path should never be empty.  Either we
5952042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // just added a bunch of stuff to the top-level path, or
5962042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // we have a previous CallExit.  If the front of the active
5972042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // path is not a PathDiagnosticCallPiece, it means that the
5982042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // path terminated within a function call.  We must then take the
5992042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // current contents of the active path and place it within
6002042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // a new PathDiagnosticCallPiece.
6012042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      assert(!PD.getActivePath().empty());
6022042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PathDiagnosticCallPiece *C =
6032042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
6042042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      if (!C)
6052042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        C = PathDiagnosticCallPiece::construct(PD.getActivePath());
6062042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      C->setCallee(*CE, SMgr);
6072042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      continue;
6082042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    }
6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6109c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
6119c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const CFGBlock *Src = BE->getSrc();
6129c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const CFGBlock *Dst = BE->getDst();
6139c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const Stmt *T = Src->getTerminator();
6141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek      if (!T)
61661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        continue;
6171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
618590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      PathDiagnosticLocation Start =
619590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        PathDiagnosticLocation::createBegin(T, SMgr,
620590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                                N->getLocationContext());
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek      switch (T->getStmtClass()) {
62361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        default:
62461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
6251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        case Stmt::GotoStmtClass:
6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::IndirectGotoStmtClass: {
6289c378f705405d37f49795d5e915989de774fe11fTed Kremenek          const Stmt *S = GetNextStmt(N);
6291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          if (!S)
63161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek            continue;
6321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
633297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          llvm::raw_string_ostream os(sbuf);
635d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek          const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S);
6361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63700605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          os << "Control jumps to line "
638642116259e8df6286063a17361c20e95b5017a0aChandler Carruth          << End.asLocation().getExpansionLineNumber();
6392042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
640802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek                                                                os.str()));
64161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
64261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        }
6431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::SwitchStmtClass: {
64561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          // Figure out what case arm we took.
646297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
647297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
6481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6499c378f705405d37f49795d5e915989de774fe11fTed Kremenek          if (const Stmt *S = Dst->getLabel()) {
650220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks            PathDiagnosticLocation End(S, SMgr, LC);
6511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6525a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek            switch (S->getStmtClass()) {
653082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek              default:
654082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                os << "No cases match in the switch statement. "
6553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                "Control jumps to line "
656642116259e8df6286063a17361c20e95b5017a0aChandler Carruth                << End.asLocation().getExpansionLineNumber();
657082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                break;
658082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek              case Stmt::DefaultStmtClass:
659082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                os << "Control jumps to the 'default' case at line "
660642116259e8df6286063a17361c20e95b5017a0aChandler Carruth                << End.asLocation().getExpansionLineNumber();
661082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                break;
6621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
663082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek              case Stmt::CaseStmtClass: {
6641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                os << "Control jumps to 'case ";
6659c378f705405d37f49795d5e915989de774fe11fTed Kremenek                const CaseStmt *Case = cast<CaseStmt>(S);
6669c378f705405d37f49795d5e915989de774fe11fTed Kremenek                const Expr *LHS = Case->getLHS()->IgnoreParenCasts();
6671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                // Determine if it is an enum.
669082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                bool GetRawInt = true;
6701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6719c378f705405d37f49795d5e915989de774fe11fTed Kremenek                if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS)) {
672082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                  // FIXME: Maybe this should be an assertion.  Are there cases
673082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                  // were it is not an EnumConstantDecl?
6749c378f705405d37f49795d5e915989de774fe11fTed Kremenek                  const EnumConstantDecl *D =
67503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                    dyn_cast<EnumConstantDecl>(DR->getDecl());
6761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
677082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                  if (D) {
678082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                    GetRawInt = false;
679b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer                    os << *D;
680082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                  }
6815a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek                }
6829ec64d6e2fe575b297e1eaa5051efc2983373e25Eli Friedman
6839ec64d6e2fe575b297e1eaa5051efc2983373e25Eli Friedman                if (GetRawInt)
684a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith                  os << LHS->EvaluateKnownConstInt(PDB.getASTContext());
6859ec64d6e2fe575b297e1eaa5051efc2983373e25Eli Friedman
68600605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek                os << ":'  at line "
687642116259e8df6286063a17361c20e95b5017a0aChandler Carruth                << End.asLocation().getExpansionLineNumber();
688082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                break;
689082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek              }
69061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek            }
6912042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
69200605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek                                                             os.str()));
69361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          }
694567839273dfc395a459cbe77d5f8d128b9ae85bfTed Kremenek          else {
695c3517ebb48a51e146badc08bc3684520c41da6c8Ted Kremenek            os << "'Default' branch taken. ";
6961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
6972042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
69800605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek                                                             os.str()));
699567839273dfc395a459cbe77d5f8d128b9ae85bfTed Kremenek          }
7001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
70261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        }
7031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7042673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        case Stmt::BreakStmtClass:
7052673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        case Stmt::ContinueStmtClass: {
706297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
707297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
70800605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
7092042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
710082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                                                           os.str()));
7112673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek          break;
7122673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        }
7131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          // Determine control-flow for ternary '?'.
71556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        case Stmt::BinaryConditionalOperatorClass:
716706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek        case Stmt::ConditionalOperatorClass: {
717297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
718297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
7191d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek          os << "'?' condition is ";
7201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
721706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          if (*(Src->succ_begin()+1) == Dst)
722082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek            os << "false";
723706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          else
724082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek            os << "true";
7251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72600605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
7271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7281d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek          if (const Stmt *S = End.asStmt())
7291d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek            End = PDB.getEnclosingStmtLocation(S);
7301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7312042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
732babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek                                                           os.str()));
733babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          break;
734babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek        }
7351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7363106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          // Determine control-flow for short-circuited '&&' and '||'.
737babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek        case Stmt::BinaryOperatorClass: {
738babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          if (!PDB.supportsLogicalOpControlFlow())
739babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek            break;
7401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu          const BinaryOperator *B = cast<BinaryOperator>(T);
742babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          std::string sbuf;
743babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          llvm::raw_string_ostream os(sbuf);
744babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          os << "Left side of '";
7451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7462de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall          if (B->getOpcode() == BO_LAnd) {
747f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            os << "&&" << "' is ";
7481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
749f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            if (*(Src->succ_begin()+1) == Dst) {
750f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "false";
751220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
7520cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation Start =
7530cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                PathDiagnosticLocation::createOperatorLoc(B, SMgr);
7542042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
755f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek                                                               os.str()));
7561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
757f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            else {
758f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "true";
759220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
760f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
7612042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
762f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek                                                               os.str()));
7631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
764babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          }
765babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          else {
7662de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall            assert(B->getOpcode() == BO_LOr);
767f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            os << "||" << "' is ";
7681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
769f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            if (*(Src->succ_begin()+1) == Dst) {
770f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "false";
771220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
772f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
7732042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
7741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                               os.str()));
775f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            }
776f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            else {
777f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "true";
778220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
7790cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation Start =
7800cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                PathDiagnosticLocation::createOperatorLoc(B, SMgr);
7812042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
7821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                               os.str()));
783f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            }
784babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          }
7851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
786706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          break;
787706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek        }
7881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::DoStmtClass:  {
790706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          if (*(Src->succ_begin()) == Dst) {
791297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek            std::string sbuf;
792297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek            llvm::raw_string_ostream os(sbuf);
7931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
794c3517ebb48a51e146badc08bc3684520c41da6c8Ted Kremenek            os << "Loop condition is true. ";
795d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
7961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
797d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            if (const Stmt *S = End.asStmt())
798d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek              End = PDB.getEnclosingStmtLocation(S);
7991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8002042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
801082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                                                             os.str()));
802082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek          }
803082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek          else {
80400605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
8051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
806d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            if (const Stmt *S = End.asStmt())
807d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek              End = PDB.getEnclosingStmtLocation(S);
8081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8092042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
8103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                              "Loop condition is false.  Exiting loop"));
8113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
8121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8133106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
8143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
8151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        case Stmt::WhileStmtClass:
8171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::ForStmtClass: {
8183106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (*(Src->succ_begin()+1) == Dst) {
8193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            std::string sbuf;
8203106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            llvm::raw_string_ostream os(sbuf);
8211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            os << "Loop condition is false. ";
8233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
8243106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            if (const Stmt *S = End.asStmt())
8253106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek              End = PDB.getEnclosingStmtLocation(S);
8261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8272042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
8283106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                                             os.str()));
8293106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
8303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          else {
8313106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
8323106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            if (const Stmt *S = End.asStmt())
8333106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek              End = PDB.getEnclosingStmtLocation(S);
8341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8352042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
8365fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek                            "Loop condition is true.  Entering loop body"));
8373106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
8381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
8403106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
8411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        case Stmt::IfStmtClass: {
8433106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
8441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8453106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (const Stmt *S = End.asStmt())
8463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            End = PDB.getEnclosingStmtLocation(S);
8471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8483106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (*(Src->succ_begin()+1) == Dst)
8492042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
8505fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek                                                        "Taking false branch"));
8511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          else
8522042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
8535fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek                                                         "Taking true branch"));
8541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
8563106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
8573106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
8583106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
8591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
860dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    if (NextNode) {
8618e6431adab313e283a992698f6fc7afe62420999Anna Zaks      // Add diagnostic pieces from custom visitors.
8628e6431adab313e283a992698f6fc7afe62420999Anna Zaks      BugReport *R = PDB.getBugReport();
8638e6431adab313e283a992698f6fc7afe62420999Anna Zaks      for (BugReport::visitor_iterator I = R->visitor_begin(),
8648e6431adab313e283a992698f6fc7afe62420999Anna Zaks           E = R->visitor_end(); I!=E; ++I) {
8658e6431adab313e283a992698f6fc7afe62420999Anna Zaks        if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R))
8662042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(p);
867dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      }
8688966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    }
8691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8709c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
8713106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // Scan the region bindings, and see if a "notable" symbol has a new
8723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // lval binding.
8733106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      ScanNotableSymbols SNS(N, PS->getStmt(), PDB.getBugReporter(), PD);
8743106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      PDB.getStateManager().iterBindings(N->getState(), SNS);
8753106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
8763106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
8771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
87814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // After constructing the full PathDiagnostic, do a pass over it to compact
87914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // PathDiagnosticPieces that occur within a macro.
88077d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  CompactPathDiagnostic(PD.getMutablePieces(), PDB.getSourceManager());
8813106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
8823106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
8833106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
8845fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek// "Extensive" PathDiagnostic generation.
8855fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek//===----------------------------------------------------------------------===//
8865fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek
8875fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenekstatic bool IsControlFlowExpr(const Stmt *S) {
8885fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  const Expr *E = dyn_cast<Expr>(S);
8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8905fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  if (!E)
8915fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    return false;
8921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  E = E->IgnoreParenCasts();
8941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
89556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  if (isa<AbstractConditionalOperator>(E))
8965fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    return true;
8971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8985fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E))
8995fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    if (B->isLogicalOp())
9005fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      return true;
9011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return false;
9035fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek}
9045fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek
90514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremeneknamespace {
906ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass ContextLocation : public PathDiagnosticLocation {
9078f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool IsDead;
9088f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenekpublic:
9098f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  ContextLocation(const PathDiagnosticLocation &L, bool isdead = false)
9108f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    : PathDiagnosticLocation(L), IsDead(isdead) {}
9111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void markDead() { IsDead = true; }
9138f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool isDead() const { return IsDead; }
9148f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek};
9151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
916ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass EdgeBuilder {
9178f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  std::vector<ContextLocation> CLocs;
9188f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  typedef std::vector<ContextLocation>::iterator iterator;
91914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnostic &PD;
92014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticBuilder &PDB;
92114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticLocation PrevLoc;
9221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9238f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool IsConsumedExpr(const PathDiagnosticLocation &L);
9241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
92514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  bool containsLocation(const PathDiagnosticLocation &Container,
92614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                        const PathDiagnosticLocation &Containee);
9271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
92814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L);
9291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9309650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek  PathDiagnosticLocation cleanUpLocation(PathDiagnosticLocation L,
9319650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek                                         bool firstCharOnly = false) {
9328c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    if (const Stmt *S = L.asStmt()) {
9339650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek      const Stmt *Original = S;
9348c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek      while (1) {
9358c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek        // Adjust the location for some expressions that are best referenced
9368c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek        // by one of their subexpressions.
9379650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        switch (S->getStmtClass()) {
9389650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          default:
9399650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            break;
9409650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ParenExprClass:
941f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne          case Stmt::GenericSelectionExprClass:
942f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne            S = cast<Expr>(S)->IgnoreParens();
9439650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
9449650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
94556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall          case Stmt::BinaryConditionalOperatorClass:
9469650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ConditionalOperatorClass:
94756ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall            S = cast<AbstractConditionalOperator>(S)->getCond();
9489650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
9499650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
9509650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ChooseExprClass:
9519650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            S = cast<ChooseExpr>(S)->getCond();
9529650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
9539650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
9549650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::BinaryOperatorClass:
9559650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            S = cast<BinaryOperator>(S)->getLHS();
9569650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
9579650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
9589650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        }
9591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9609650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        break;
9618c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek      }
9621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9639650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek      if (S != Original)
96459950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek        L = PathDiagnosticLocation(S, L.getManager(), PDB.LC);
9658c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    }
9661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9679650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek    if (firstCharOnly)
9681531bb0c69d9afff6a6434e4cadf345eb628b287Anna Zaks      L  = PathDiagnosticLocation::createSingleLocation(L);
9699650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek
9708c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    return L;
9718c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  }
9721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
97314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void popLocation() {
9748f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    if (!CLocs.back().isDead() && CLocs.back().asLocation().isFileID()) {
9755c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek      // For contexts, we only one the first character as the range.
97607c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek      rawAddEdge(cleanUpLocation(CLocs.back(), true));
9775c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek    }
97814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    CLocs.pop_back();
97914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
9801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekpublic:
98214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  EdgeBuilder(PathDiagnostic &pd, PathDiagnosticBuilder &pdb)
98314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    : PD(pd), PDB(pdb) {
9841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
985a301a6773db085575ac51e3c966858180390c25bTed Kremenek      // If the PathDiagnostic already has pieces, add the enclosing statement
986a301a6773db085575ac51e3c966858180390c25bTed Kremenek      // of the first piece as a context as well.
987802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek      if (!PD.path.empty()) {
988802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek        PrevLoc = (*PD.path.begin())->getLocation();
9891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
99014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        if (const Stmt *S = PrevLoc.asStmt())
991e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek          addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
99214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      }
99314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
99414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
99514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  ~EdgeBuilder() {
99614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    while (!CLocs.empty()) popLocation();
9970cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks
998a301a6773db085575ac51e3c966858180390c25bTed Kremenek    // Finally, add an initial edge from the start location of the first
999a301a6773db085575ac51e3c966858180390c25bTed Kremenek    // statement (if it doesn't already exist).
10000cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks    PathDiagnosticLocation L = PathDiagnosticLocation::createDeclBegin(
100159950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek                                                       PDB.LC,
10020cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                                                       PDB.getSourceManager());
10030cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks    if (L.isValid())
10040cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks      rawAddEdge(L);
100514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
100614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
10075de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek  void flushLocations() {
10085de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek    while (!CLocs.empty())
10095de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      popLocation();
10105de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek    PrevLoc = PathDiagnosticLocation();
10115de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek  }
10125de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
101314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd = false);
10141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10158bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek  void rawAddEdge(PathDiagnosticLocation NewLoc);
10161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
101714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void addContext(const Stmt *S);
1018e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  void addExtendedContext(const Stmt *S);
10191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
102014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek} // end anonymous namespace
102114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
102214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
102314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted KremenekPathDiagnosticLocation
102414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted KremenekEdgeBuilder::getContextLocation(const PathDiagnosticLocation &L) {
102514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (const Stmt *S = L.asStmt()) {
102614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (IsControlFlowExpr(S))
102714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return L;
10281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return PDB.getEnclosingStmtLocation(S);
103014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
10311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
103214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  return L;
103314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
103414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
103514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekbool EdgeBuilder::containsLocation(const PathDiagnosticLocation &Container,
103614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                                   const PathDiagnosticLocation &Containee) {
103714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
103814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (Container == Containee)
103914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return true;
10401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (Container.asDecl())
104214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return true;
10431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
104414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (const Stmt *S = Containee.asStmt())
104514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (const Stmt *ContainerS = Container.asStmt()) {
104614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      while (S) {
104714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        if (S == ContainerS)
104814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          return true;
104914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        S = PDB.getParent(S);
105014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      }
105114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return false;
105214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
105314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
105414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // Less accurate: compare using source ranges.
105514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceRange ContainerR = Container.asRange();
105614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceRange ContaineeR = Containee.asRange();
10571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
105814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceManager &SM = PDB.getSourceManager();
1059402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContainerRBeg = SM.getExpansionLoc(ContainerR.getBegin());
1060402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContainerREnd = SM.getExpansionLoc(ContainerR.getEnd());
1061402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContaineeRBeg = SM.getExpansionLoc(ContaineeR.getBegin());
1062402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContaineeREnd = SM.getExpansionLoc(ContaineeR.getEnd());
10631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1064642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContainerBegLine = SM.getExpansionLineNumber(ContainerRBeg);
1065642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContainerEndLine = SM.getExpansionLineNumber(ContainerREnd);
1066642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContaineeBegLine = SM.getExpansionLineNumber(ContaineeRBeg);
1067642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContaineeEndLine = SM.getExpansionLineNumber(ContaineeREnd);
10681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
106914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  assert(ContainerBegLine <= ContainerEndLine);
10701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert(ContaineeBegLine <= ContaineeEndLine);
10711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
107214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  return (ContainerBegLine <= ContaineeBegLine &&
107314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          ContainerEndLine >= ContaineeEndLine &&
107414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          (ContainerBegLine != ContaineeBegLine ||
1075a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContainerRBeg) <=
1076a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContaineeRBeg)) &&
107714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          (ContainerEndLine != ContaineeEndLine ||
1078a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContainerREnd) >=
1079a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContainerREnd)));
108014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
108114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
108214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) {
108314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (!PrevLoc.isValid()) {
108414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    PrevLoc = NewLoc;
108514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
108614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
10871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10888c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  const PathDiagnosticLocation &NewLocClean = cleanUpLocation(NewLoc);
10898c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  const PathDiagnosticLocation &PrevLocClean = cleanUpLocation(PrevLoc);
10901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10918c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  if (NewLocClean.asLocation() == PrevLocClean.asLocation())
109214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
10931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
109414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // FIXME: Ignore intra-macro edges for now.
1095402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  if (NewLocClean.asLocation().getExpansionLoc() ==
1096402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth      PrevLocClean.asLocation().getExpansionLoc())
109714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
109814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
10992042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek  PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
11008c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  PrevLoc = NewLoc;
110114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
110214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
110314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd) {
11041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1105a301a6773db085575ac51e3c966858180390c25bTed Kremenek  if (!alwaysAdd && NewLoc.asLocation().isMacroID())
1106a301a6773db085575ac51e3c966858180390c25bTed Kremenek    return;
11071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
110814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  const PathDiagnosticLocation &CLoc = getContextLocation(NewLoc);
110914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
111014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (!CLocs.empty()) {
11118f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    ContextLocation &TopContextLoc = CLocs.back();
11121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
111314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Is the top location context the same as the one for the new location?
111414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (TopContextLoc == CLoc) {
11158f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      if (alwaysAdd) {
11164c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek        if (IsConsumedExpr(TopContextLoc) &&
11174c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek            !IsControlFlowExpr(TopContextLoc.asStmt()))
11188f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek            TopContextLoc.markDead();
11198f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek
112014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        rawAddEdge(NewLoc);
11218f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      }
112214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
112314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return;
112414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
112514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
112614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (containsLocation(TopContextLoc, CLoc)) {
11278f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      if (alwaysAdd) {
112814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        rawAddEdge(NewLoc);
11291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11304c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek        if (IsConsumedExpr(CLoc) && !IsControlFlowExpr(CLoc.asStmt())) {
11318f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek          CLocs.push_back(ContextLocation(CLoc, true));
11328f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek          return;
11338f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek        }
11348f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      }
11351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      CLocs.push_back(CLoc);
11371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return;
113814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
113914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
114014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Context does not contain the location.  Flush it.
114114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    popLocation();
114214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
11431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11445c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek  // If we reach here, there is no enclosing context.  Just add the edge.
11455c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek  rawAddEdge(NewLoc);
114614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
114714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
11488f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenekbool EdgeBuilder::IsConsumedExpr(const PathDiagnosticLocation &L) {
11498f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  if (const Expr *X = dyn_cast_or_null<Expr>(L.asStmt()))
11508f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    return PDB.getParentMap().isConsumedExpr(X) && !IsControlFlowExpr(X);
11511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11528f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  return false;
11538f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek}
11541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1155e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenekvoid EdgeBuilder::addExtendedContext(const Stmt *S) {
1156e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  if (!S)
1157e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    return;
11581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const Stmt *Parent = PDB.getParent(S);
1160e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  while (Parent) {
1161e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    if (isa<CompoundStmt>(Parent))
1162e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      Parent = PDB.getParent(Parent);
1163e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    else
1164e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      break;
1165e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  }
1166e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek
1167e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  if (Parent) {
1168e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    switch (Parent->getStmtClass()) {
1169e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      case Stmt::DoStmtClass:
1170e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      case Stmt::ObjCAtSynchronizedStmtClass:
1171e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek        addContext(Parent);
1172e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      default:
1173e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek        break;
1174e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    }
1175e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  }
11761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1177e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  addContext(S);
1178e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek}
11791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
118014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::addContext(const Stmt *S) {
118114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (!S)
118214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
118314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
118459950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.LC);
11851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
118614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (!CLocs.empty()) {
118714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    const PathDiagnosticLocation &TopContextLoc = CLocs.back();
118814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
118914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Is the top location context the same as the one for the new location?
119014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (TopContextLoc == L)
119114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return;
119214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
119314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (containsLocation(TopContextLoc, L)) {
119414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      CLocs.push_back(L);
11951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return;
119614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
119714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
119814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Context does not contain the location.  Flush it.
119914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    popLocation();
120014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
120114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
120214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  CLocs.push_back(L);
120314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
120414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
120514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekstatic void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
120614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                                            PathDiagnosticBuilder &PDB,
1207c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                                            const ExplodedNode *N) {
120814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  EdgeBuilder EB(PD, PDB);
12090cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks  const SourceManager& SM = PDB.getSourceManager();
121014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
12119c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
121214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (NextNode) {
121314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    N = NextNode;
121414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    NextNode = GetPredecessorNode(N);
121514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    ProgramPoint P = N->getLocation();
121614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
1217dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    do {
12185de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      if (const CallExit *CE = dyn_cast<CallExit>(&P)) {
12195de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        const StackFrameContext *LCtx =
12205de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        CE->getLocationContext()->getCurrentStackFrame();
12215de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        PathDiagnosticLocation Loc(LCtx->getCallSite(),
12225de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek                                   PDB.getSourceManager(),
12235de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek                                   LCtx);
12245de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        EB.addEdge(Loc, true);
12255de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        EB.flushLocations();
12262042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PathDiagnosticCallPiece *C =
12272042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PathDiagnosticCallPiece::construct(N, *CE, SM);
12282042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.getActivePath().push_front(C);
12292042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.pushActivePath(&C->path);
12305de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        break;
12315de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      }
123259950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek
123359950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek      // Note that is important that we update the LocationContext
123459950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek      // after looking at CallExits.  CallExit basically adds an
123559950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek      // edge in the *caller*, so we don't want to update the LocationContext
123659950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek      // too soon.
123759950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek      PDB.LC = N->getLocationContext();
123859950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek
12392042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // Pop the call hierarchy if we are done walking the contents
12402042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // of a function call.
12412042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
12422042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.popActivePath();
12432042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // The current active path should never be empty.  Either we
12442042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // just added a bunch of stuff to the top-level path, or
12452042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // we have a previous CallExit.  If the front of the active
12462042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // path is not a PathDiagnosticCallPiece, it means that the
12472042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // path terminated within a function call.  We must then take the
12482042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // current contents of the active path and place it within
12492042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // a new PathDiagnosticCallPiece.
12502042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        assert(!PD.getActivePath().empty());
12512042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PathDiagnosticCallPiece *C =
12522042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
12532042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        if (!C)
12542042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          C = PathDiagnosticCallPiece::construct(PD.getActivePath());
12552042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        C->setCallee(*CE, SM);
125659950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek        EB.flushLocations();
12572042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        EB.addContext(CE->getCallExpr());
12582042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        break;
12592042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      }
12605de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
1261dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      // Block edges.
12625de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
1263dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        const CFGBlock &Blk = *BE->getSrc();
1264dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        const Stmt *Term = Blk.getTerminator();
12651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1266dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        // Are we jumping to the head of a loop?  Add a special diagnostic.
1267ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        if (const Stmt *Loop = BE->getDst()->getLoopTarget()) {
126859950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek          PathDiagnosticLocation L(Loop, SM, PDB.LC);
1269ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          const CompoundStmt *CS = NULL;
12701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1271ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          if (!Term) {
1272ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek            if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
1273ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek              CS = dyn_cast<CompoundStmt>(FS->getBody());
1274ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek            else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
12751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump              CS = dyn_cast<CompoundStmt>(WS->getBody());
1276ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          }
12771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1278dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          PathDiagnosticEventPiece *p =
1279dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek            new PathDiagnosticEventPiece(L,
128007c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek                                        "Looping back to the head of the loop");
12811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1282dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          EB.addEdge(p->getLocation(), true);
12832042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(p);
12841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1285ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          if (CS) {
12860cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks            PathDiagnosticLocation BL =
12870cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation::createEndBrace(CS, SM);
128807c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek            EB.addEdge(BL);
1289dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          }
12908bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek        }
12911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1292ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        if (Term)
1293ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          EB.addContext(Term);
12941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1295dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        break;
12968bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek      }
129714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
12981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
12993c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek        if (const CFGStmt *S = BE->getFirstElement().getAs<CFGStmt>()) {
13003c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          const Stmt *stmt = S->getStmt();
13013c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          if (IsControlFlowExpr(stmt)) {
1302b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu            // Add the proper context for '&&', '||', and '?'.
13033c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            EB.addContext(stmt);
1304b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu          }
1305b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu          else
13063c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt());
1307dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        }
1308b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu
1309dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        break;
1310dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      }
13115de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
13125de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
1313dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    } while (0);
13141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1315dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    if (!NextNode)
131614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      continue;
13171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13188e6431adab313e283a992698f6fc7afe62420999Anna Zaks    // Add pieces from custom visitors.
13198e6431adab313e283a992698f6fc7afe62420999Anna Zaks    BugReport *R = PDB.getBugReport();
13208e6431adab313e283a992698f6fc7afe62420999Anna Zaks    for (BugReport::visitor_iterator I = R->visitor_begin(),
13218e6431adab313e283a992698f6fc7afe62420999Anna Zaks                                     E = R->visitor_end(); I!=E; ++I) {
13228e6431adab313e283a992698f6fc7afe62420999Anna Zaks      if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
13238966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        const PathDiagnosticLocation &Loc = p->getLocation();
13248966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        EB.addEdge(Loc, true);
13252042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.getActivePath().push_front(p);
13268966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        if (const Stmt *S = Loc.asStmt())
13271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
13288966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek      }
13291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
133014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
133114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
133214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
13335fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek//===----------------------------------------------------------------------===//
13343106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugType and subclasses.
13353106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
1336404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios KyrtzidisBugType::~BugType() { }
1337404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
13383106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekvoid BugType::FlushReports(BugReporter &BR) {}
13393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
134099ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid BuiltinBug::anchor() {}
134199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
13423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
13433106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugReport and subclasses.
13443106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
1345e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
134699ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid BugReport::NodeResolver::anchor() {}
134799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
13488e6431adab313e283a992698f6fc7afe62420999Anna Zaksvoid BugReport::addVisitor(BugReporterVisitor* visitor) {
13498e6431adab313e283a992698f6fc7afe62420999Anna Zaks  if (!visitor)
13508e6431adab313e283a992698f6fc7afe62420999Anna Zaks    return;
13518e6431adab313e283a992698f6fc7afe62420999Anna Zaks
13528e6431adab313e283a992698f6fc7afe62420999Anna Zaks  llvm::FoldingSetNodeID ID;
13538e6431adab313e283a992698f6fc7afe62420999Anna Zaks  visitor->Profile(ID);
13548e6431adab313e283a992698f6fc7afe62420999Anna Zaks  void *InsertPos;
13558e6431adab313e283a992698f6fc7afe62420999Anna Zaks
13568e6431adab313e283a992698f6fc7afe62420999Anna Zaks  if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) {
13578e6431adab313e283a992698f6fc7afe62420999Anna Zaks    delete visitor;
13588e6431adab313e283a992698f6fc7afe62420999Anna Zaks    return;
13598e6431adab313e283a992698f6fc7afe62420999Anna Zaks  }
13608e6431adab313e283a992698f6fc7afe62420999Anna Zaks
13618e6431adab313e283a992698f6fc7afe62420999Anna Zaks  CallbacksSet.InsertNode(visitor, InsertPos);
13628e6431adab313e283a992698f6fc7afe62420999Anna Zaks  Callbacks = F.add(visitor, Callbacks);
13638e6431adab313e283a992698f6fc7afe62420999Anna Zaks}
13648e6431adab313e283a992698f6fc7afe62420999Anna Zaks
13658e6431adab313e283a992698f6fc7afe62420999Anna ZaksBugReport::~BugReport() {
13668e6431adab313e283a992698f6fc7afe62420999Anna Zaks  for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I) {
1367dc757b049796949e4b11646445a6598f0bdabd7aAnna Zaks    delete *I;
13688e6431adab313e283a992698f6fc7afe62420999Anna Zaks  }
13698e6431adab313e283a992698f6fc7afe62420999Anna Zaks}
1370e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
1371e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaksvoid BugReport::Profile(llvm::FoldingSetNodeID& hash) const {
1372e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  hash.AddPointer(&BT);
1373e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  hash.AddString(Description);
1374ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks  if (UniqueingLocation.isValid()) {
1375ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks    UniqueingLocation.Profile(hash);
1376ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks  } else if (Location.isValid()) {
1377590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    Location.Profile(hash);
1378590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  } else {
1379590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    assert(ErrorNode);
1380590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    hash.AddPointer(GetCurrentOrPreviousStmt(ErrorNode));
1381590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  }
1382e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
1383e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  for (SmallVectorImpl<SourceRange>::const_iterator I =
1384e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      Ranges.begin(), E = Ranges.end(); I != E; ++I) {
1385e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    const SourceRange range = *I;
1386e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    if (!range.isValid())
1387e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      continue;
1388e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    hash.AddInteger(range.getBegin().getRawEncoding());
1389e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    hash.AddInteger(range.getEnd().getRawEncoding());
1390e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  }
1391e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks}
13923106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
13939c378f705405d37f49795d5e915989de774fe11fTed Kremenekconst Stmt *BugReport::getStmt() const {
1394e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  if (!ErrorNode)
1395e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    return 0;
1396e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
1397212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care  ProgramPoint ProgP = ErrorNode->getLocation();
13985f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const Stmt *S = NULL;
13991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14009c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (BlockEntrance *BE = dyn_cast<BlockEntrance>(&ProgP)) {
1401fafd3834754d2093e0ad7a1c005860fd527ecb7fZhongxing Xu    CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit();
140250d5bc4e3b53eb8bb4ebf198f1213348a3fa0f38Zhongxing Xu    if (BE->getBlock() == &Exit)
1403212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care      S = GetPreviousStmt(ErrorNode);
14043106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
14055f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (!S)
14061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    S = GetStmt(ProgP);
14071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return S;
14093106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
14103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1411640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidisstd::pair<BugReport::ranges_iterator, BugReport::ranges_iterator>
1412e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna ZaksBugReport::getRanges() {
1413e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    // If no custom ranges, add the range of the statement corresponding to
1414e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    // the error node.
1415e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    if (Ranges.empty()) {
1416e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      if (const Expr *E = dyn_cast_or_null<Expr>(getStmt()))
1417e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks        addRange(E->getSourceRange());
1418e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      else
1419e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks        return std::make_pair(ranges_iterator(), ranges_iterator());
1420e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    }
1421e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
142214924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks    // User-specified absence of range info.
142314924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks    if (Ranges.size() == 1 && !Ranges.begin()->isValid())
142414924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks      return std::make_pair(ranges_iterator(), ranges_iterator());
142514924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks
1426e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    return std::make_pair(Ranges.begin(), Ranges.end());
14273106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
14283106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1429590dd8e0959d8df5621827768987c4792b74fc06Anna ZaksPathDiagnosticLocation BugReport::getLocation(const SourceManager &SM) const {
1430b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  if (ErrorNode) {
1431590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    assert(!Location.isValid() &&
1432b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks     "Either Location or ErrorNode should be specified but not both.");
1433b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks
14349c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (const Stmt *S = GetCurrentOrPreviousStmt(ErrorNode)) {
1435590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      const LocationContext *LC = ErrorNode->getLocationContext();
1436590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks
14373106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // For member expressions, return the location of the '.' or '->'.
14385b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      if (const MemberExpr *ME = dyn_cast<MemberExpr>(S))
1439590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        return PathDiagnosticLocation::createMemberLoc(ME, SM);
14405b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      // For binary operators, return the location of the operator.
14415b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
1442590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        return PathDiagnosticLocation::createOperatorLoc(B, SM);
14433106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1444590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      return PathDiagnosticLocation::createBegin(S, SM, LC);
14453106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1446b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  } else {
1447b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks    assert(Location.isValid());
1448b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks    return Location;
1449b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  }
1450b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks
1451590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  return PathDiagnosticLocation();
14523106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
14533106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14543106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
14553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugReporter and subclasses.
14563106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
14573106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14583106198188ac6eb2753f1764d5c28376b0b76351Ted KremenekBugReportEquivClass::~BugReportEquivClass() {
14598966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  for (iterator I=begin(), E=end(); I!=E; ++I) delete *I;
14603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
14613106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1462a2f4ec0df645fc249d2945beef9653f03b175417Zhongxing XuGRBugReporter::~GRBugReporter() { }
14633106198188ac6eb2753f1764d5c28376b0b76351Ted KremenekBugReporterData::~BugReporterData() {}
14643106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
146538b02b912e1a55c912f603c4369431264d36a381Zhongxing XuExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); }
14663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
146718c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekProgramStateManager&
14683106198188ac6eb2753f1764d5c28376b0b76351Ted KremenekGRBugReporter::getStateManager() { return Eng.getStateManager(); }
14693106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14703b030a28cda2b953758507769c1d436bec5ec45eAnna ZaksBugReporter::~BugReporter() {
14713b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  FlushReports();
14723b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks
14733b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  // Free the bug reports we are tracking.
14743b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  typedef std::vector<BugReportEquivClass *> ContTy;
14753b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  for (ContTy::iterator I = EQClassesVector.begin(), E = EQClassesVector.end();
14763b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks       I != E; ++I) {
14773b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks    delete *I;
14783b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  }
14793b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks}
14803106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14813106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekvoid BugReporter::FlushReports() {
14823106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  if (BugTypes.isEmpty())
14833106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    return;
14843106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14853106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // First flush the warnings for each BugType.  This may end up creating new
1486404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // warnings and new BugTypes.
1487404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // FIXME: Only NSErrorChecker needs BugType's FlushReports.
1488404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // Turn NSErrorChecker into a proper checker and remove this.
14895f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const BugType*, 16> bugTypes;
14903106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  for (BugTypesTy::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
1491404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    bugTypes.push_back(*I);
14925f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVector<const BugType*, 16>::iterator
1493404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis         I = bugTypes.begin(), E = bugTypes.end(); I != E; ++I)
14943106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    const_cast<BugType*>(*I)->FlushReports(*this);
14953106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1496404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  typedef llvm::FoldingSet<BugReportEquivClass> SetTy;
1497404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  for (SetTy::iterator EI=EQClasses.begin(), EE=EQClasses.end(); EI!=EE;++EI){
1498404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    BugReportEquivClass& EQ = *EI;
1499404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    FlushReport(EQ);
15003106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
15013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1502404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // BugReporter owns and deletes only BugTypes created implicitly through
1503404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // EmitBasicReport.
1504404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // FIXME: There are leaks from checkers that assume that the BugTypes they
1505404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // create will be destroyed by the BugReporter.
1506404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  for (llvm::StringMap<BugType*>::iterator
1507404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis         I = StrBugTypes.begin(), E = StrBugTypes.end(); I != E; ++I)
1508404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    delete I->second;
1509404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
15103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Remove all references to the BugType objects.
15113baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek  BugTypes = F.getEmptySet();
15123106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
15133106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
15143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
15153106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// PathDiagnostics generation.
15163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
15173106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
151838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xustatic std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
1519c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                 std::pair<ExplodedNode*, unsigned> >
152038b02b912e1a55c912f603c4369431264d36a381Zhongxing XuMakeReportGraph(const ExplodedGraph* G,
15215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                SmallVectorImpl<const ExplodedNode*> &nodes) {
15221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create the trimmed graph.  It will contain the shortest paths from the
15241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // error nodes to the root.  In the new graph we should only have one
15253106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // error node unless there are two or more error nodes with the same minimum
15263106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // path length.
152738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  ExplodedGraph* GTrim;
1528c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  InterExplodedGraphMap* NMap;
15293106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
15303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  llvm::DenseMap<const void*, const void*> InverseMap;
153140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  llvm::tie(GTrim, NMap) = G->Trim(nodes.data(), nodes.data() + nodes.size(),
153240406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek                                   &InverseMap);
15331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15343106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create owning pointers for GTrim and NMap just to ensure that they are
15353106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // released when this function exists.
15366f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ExplodedGraph> AutoReleaseGTrim(GTrim);
15376f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<InterExplodedGraphMap> AutoReleaseNMap(NMap);
15381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Find the (first) error node in the trimmed graph.  We just need to consult
15403106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // the node map (NMap) which maps from nodes in the original graph to nodes
15413106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // in the new graph.
1542938332c657390d1e782e0adc03b092993edae962Ted Kremenek
1543c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  std::queue<const ExplodedNode*> WS;
154438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef llvm::DenseMap<const ExplodedNode*, unsigned> IndexMapTy;
1545938332c657390d1e782e0adc03b092993edae962Ted Kremenek  IndexMapTy IndexMap;
15463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
154740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  for (unsigned nodeIndex = 0 ; nodeIndex < nodes.size(); ++nodeIndex) {
154840406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    const ExplodedNode *originalNode = nodes[nodeIndex];
154940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (const ExplodedNode *N = NMap->getMappedNode(originalNode)) {
1550938332c657390d1e782e0adc03b092993edae962Ted Kremenek      WS.push(N);
155140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      IndexMap[originalNode] = nodeIndex;
15523106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
155340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  }
15541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1555938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(!WS.empty() && "No error node found in the trimmed graph.");
15563106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
15573106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create a new (third!) graph with a single path.  This is the graph
15583106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // that will be returned to the caller.
1559c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu  ExplodedGraph *GNew = new ExplodedGraph();
15601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15613106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Sometimes the trimmed graph can contain a cycle.  Perform a reverse BFS
15623106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // to the root node, and then construct a new graph that contains only
15633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // a single path.
15643106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  llvm::DenseMap<const void*,unsigned> Visited;
15651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  unsigned cnt = 0;
15679c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *Root = 0;
15681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15693106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  while (!WS.empty()) {
15709c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const ExplodedNode *Node = WS.front();
15713106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    WS.pop();
15721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15733106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Visited.find(Node) != Visited.end())
15743106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
15751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15763106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    Visited[Node] = cnt++;
15771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15783106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Node->pred_empty()) {
15793106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      Root = Node;
15803106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
15813106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
15821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1583c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    for (ExplodedNode::const_pred_iterator I=Node->pred_begin(),
15843106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek         E=Node->pred_end(); I!=E; ++I)
15853106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      WS.push(*I);
15863106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
15871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1588938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(Root);
15891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15903106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Now walk from the root down the BFS path, always taking the successor
15913106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // with the lowest number.
15921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ExplodedNode *Last = 0, *First = 0;
15933106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  NodeBackMap *BM = new NodeBackMap();
1594938332c657390d1e782e0adc03b092993edae962Ted Kremenek  unsigned NodeIndex = 0;
15951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1596c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  for ( const ExplodedNode *N = Root ;;) {
15973106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Lookup the number associated with the current node.
15983106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    llvm::DenseMap<const void*,unsigned>::iterator I = Visited.find(N);
1599938332c657390d1e782e0adc03b092993edae962Ted Kremenek    assert(I != Visited.end());
16001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Create the equivalent node in the new graph with the same state
16023106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // and location.
16039c378f705405d37f49795d5e915989de774fe11fTed Kremenek    ExplodedNode *NewN = GNew->getNode(N->getLocation(), N->getState());
16041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16053106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Store the mapping to the original node.
16063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    llvm::DenseMap<const void*, const void*>::iterator IMitr=InverseMap.find(N);
16073106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    assert(IMitr != InverseMap.end() && "No mapping to original node.");
1608c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    (*BM)[NewN] = (const ExplodedNode*) IMitr->second;
16091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Link up the new node with the previous node.
16113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Last)
16125fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek      NewN->addPredecessor(Last, *GNew);
16131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    Last = NewN;
16151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Are we at the final node?
1617938332c657390d1e782e0adc03b092993edae962Ted Kremenek    IndexMapTy::iterator IMI =
1618c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu      IndexMap.find((const ExplodedNode*)(IMitr->second));
1619938332c657390d1e782e0adc03b092993edae962Ted Kremenek    if (IMI != IndexMap.end()) {
16203106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      First = NewN;
1621938332c657390d1e782e0adc03b092993edae962Ted Kremenek      NodeIndex = IMI->second;
16223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
16233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
16241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16253106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Find the next successor node.  We choose the node that is marked
16263106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // with the lowest DFS number.
1627c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::const_succ_iterator SI = N->succ_begin();
1628c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::const_succ_iterator SE = N->succ_end();
16293106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    N = 0;
16301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16313106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    for (unsigned MinVal = 0; SI != SE; ++SI) {
16321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16333106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      I = Visited.find(*SI);
16341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16353106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (I == Visited.end())
16363106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        continue;
16371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16383106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (!N || I->second < MinVal) {
16393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        N = *SI;
16403106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MinVal = I->second;
16413106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
16423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
16431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1644938332c657390d1e782e0adc03b092993edae962Ted Kremenek    assert(N);
16453106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
16461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1647938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(First);
1648938332c657390d1e782e0adc03b092993edae962Ted Kremenek
16493106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  return std::make_pair(std::make_pair(GNew, BM),
16503106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                        std::make_pair(First, NodeIndex));
16513106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
1652d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
16533106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
16543106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek///  and collapses PathDiagosticPieces that are expanded by macros.
165577d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenekstatic void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
16562042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek  typedef std::vector<std::pair<IntrusiveRefCntPtr<PathDiagnosticMacroPiece>,
16572042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek                                SourceLocation> > MacroStackTy;
16581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1659c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  typedef std::vector<IntrusiveRefCntPtr<PathDiagnosticPiece> >
16603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          PiecesTy;
16611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16623106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  MacroStackTy MacroStack;
16633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  PiecesTy Pieces;
16641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
166577d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  for (PathPieces::const_iterator I = path.begin(), E = path.end();
16662042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek       I!=E; ++I) {
166777d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
166877d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    PathDiagnosticPiece *piece = I->getPtr();
166977d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
167077d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    // Recursively compact calls.
167177d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
167277d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      CompactPathDiagnostic(call->path, SM);
167377d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    }
167477d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
16753106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Get the location of the PathDiagnosticPiece.
167677d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    const FullSourceLoc Loc = piece->getLocation().asLocation();
16771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16783106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Determine the instantiation location, which is the location we group
16793106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // related PathDiagnosticPieces.
16801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SourceLocation InstantiationLoc = Loc.isMacroID() ?
1681402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth                                      SM.getExpansionLoc(Loc) :
16823106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                      SourceLocation();
16831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16843106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Loc.isFileID()) {
16853106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.clear();
168677d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      Pieces.push_back(piece);
16873106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
16883106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1689706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek
16903106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    assert(Loc.isMacroID());
16911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16923106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Is the PathDiagnosticPiece within the same macro group?
16933106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
169477d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      MacroStack.back().first->subPieces.push_back(piece);
16953106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
16963106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1697d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
16983106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // We aren't in the same group.  Are we descending into a new macro
16993106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // or are part of an old one?
1700c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith    IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
1701d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
17023106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
1703402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth                                          SM.getExpansionLoc(Loc) :
17043106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                          SourceLocation();
17051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Walk the entire macro stack.
17073106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    while (!MacroStack.empty()) {
17083106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (InstantiationLoc == MacroStack.back().second) {
17093106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MacroGroup = MacroStack.back().first;
17103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        break;
17113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
17121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17133106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (ParentInstantiationLoc == MacroStack.back().second) {
17143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MacroGroup = MacroStack.back().first;
17153106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        break;
171661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek      }
17171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17183106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.pop_back();
17196837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek    }
17201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17213106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) {
17223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // Create a new macro group and add it to the stack.
1723590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      PathDiagnosticMacroPiece *NewGroup =
1724590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        new PathDiagnosticMacroPiece(
172577d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek          PathDiagnosticLocation::createSingleLocation(piece->getLocation()));
17265a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek
17273106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (MacroGroup)
1728802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek        MacroGroup->subPieces.push_back(NewGroup);
17293106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      else {
17303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        assert(InstantiationLoc.isFileID());
17313106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        Pieces.push_back(NewGroup);
17323106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
17331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17343106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroGroup = NewGroup;
17353106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.push_back(std::make_pair(MacroGroup, InstantiationLoc));
17367dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    }
17373106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
17383106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Finally, add the PathDiagnosticPiece to the group.
173977d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    MacroGroup->subPieces.push_back(piece);
17403106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
17411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Now take the pieces and construct a new PathDiagnostic.
174377d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  path.clear();
17441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
174577d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I)
174677d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    path.push_back(*I);
174761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
174861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
17493106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekvoid GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
17505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                        SmallVectorImpl<BugReport *> &bugReports) {
17511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
175240406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  assert(!bugReports.empty());
17535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const ExplodedNode *, 10> errorNodes;
17545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVectorImpl<BugReport*>::iterator I = bugReports.begin(),
175540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    E = bugReports.end(); I != E; ++I) {
175640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      errorNodes.push_back((*I)->getErrorNode());
175740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  }
17581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17593106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Construct a new graph that contains only a single path from the error
17601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // node to a root.
176138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
1762c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  std::pair<ExplodedNode*, unsigned> >&
176340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    GPair = MakeReportGraph(&getGraph(), errorNodes);
17641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17653106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Find the BugReport with the original location.
176640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  assert(GPair.second.second < bugReports.size());
176740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *R = bugReports[GPair.second.second];
17683106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  assert(R && "No original report found for sliced graph.");
17691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17706f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ExplodedGraph> ReportGraph(GPair.first.first);
17716f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<NodeBackMap> BackMap(GPair.first.second);
1772c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  const ExplodedNode *N = GPair.second.first;
17731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Start building the path diagnostic...
1775ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticBuilder PDB(*this, R, BackMap.get(),
1776ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie                            getPathDiagnosticConsumer());
17771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17788e6431adab313e283a992698f6fc7afe62420999Anna Zaks  // Register additional node visitors.
177950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  R->addVisitor(new NilReceiverBRVisitor());
178050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  R->addVisitor(new ConditionBRVisitor());
17811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
178223f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  // Generate the very last diagnostic piece - the piece is visible before
178323f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  // the trace is expanded.
178423f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  PathDiagnosticPiece *LastPiece = 0;
178523f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  for (BugReport::visitor_iterator I = R->visitor_begin(),
178623f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                                   E = R->visitor_end(); I!=E; ++I) {
178723f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks    if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
178823f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks      assert (!LastPiece &&
178923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks              "There can only be one final piece in a diagnostic.");
179023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks      LastPiece = Piece;
179123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks    }
179223f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  }
179323f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  if (!LastPiece)
179423f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks    LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
179523f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  if (LastPiece)
17962042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    PD.getActivePath().push_back(LastPiece);
179723f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  else
179823f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks    return;
179923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
18003106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  switch (PDB.getGenerationScheme()) {
1801ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    case PathDiagnosticConsumer::Extensive:
18028966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek      GenerateExtensivePathDiagnostic(PD, PDB, N);
18035fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      break;
1804ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    case PathDiagnosticConsumer::Minimal:
18053106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      GenerateMinimalPathDiagnostic(PD, PDB, N);
18063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
18073106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
1808c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
1809c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  // Finally, prune the diagnostic path of uninteresting stuff.
1810c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces());
1811c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  assert(hasSomethingInteresting);
1812c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  (void) hasSomethingInteresting;
18133106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
18141aa44c7c9198796085b77c6bdd7c90030845a688Ted Kremenek
1815cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekvoid BugReporter::Register(BugType *BT) {
18163baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek  BugTypes = F.add(BugTypes, BT);
181776d90c8bf83d071fd1bdbffa6d9f2af87c6bb7b5Ted Kremenek}
181876d90c8bf83d071fd1bdbffa6d9f2af87c6bb7b5Ted Kremenek
18191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid BugReporter::EmitReport(BugReport* R) {
1820cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // Compute the bug report's hash to determine its equivalence class.
1821cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  llvm::FoldingSetNodeID ID;
1822cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  R->Profile(ID);
18231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Lookup the equivance class.  If there isn't one, create it.
1825cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugType& BT = R->getBugType();
1826cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  Register(&BT);
1827cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void *InsertPos;
1828404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos);
18291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1830cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  if (!EQ) {
1831cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    EQ = new BugReportEquivClass(R);
1832404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    EQClasses.InsertNode(EQ, InsertPos);
18333b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks    EQClassesVector.push_back(EQ);
1834cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  }
1835cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  else
1836cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    EQ->AddReport(R);
183761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
183861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
183906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
184006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek//===----------------------------------------------------------------------===//
184106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek// Emitting reports in equivalence classes.
184206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek//===----------------------------------------------------------------------===//
184306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
184406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremeneknamespace {
1845ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamstruct FRIEC_WLItem {
184606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  const ExplodedNode *N;
184706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  ExplodedNode::const_succ_iterator I, E;
184806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
184906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  FRIEC_WLItem(const ExplodedNode *n)
185006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  : N(n), I(N->succ_begin()), E(N->succ_end()) {}
185106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek};
185206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek}
185306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
185461f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenekstatic BugReport *
185561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted KremenekFindReportInEquivalenceClass(BugReportEquivClass& EQ,
18565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                             SmallVectorImpl<BugReport*> &bugReports) {
185761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
185806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
185906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  assert(I != E);
186006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  BugReport *R = *I;
186106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  BugType& BT = R->getBugType();
186261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
186340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // If we don't need to suppress any of the nodes because they are
186440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // post-dominated by a sink, simply add all the nodes in the equivalence class
186540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // to 'Nodes'.  Any of the reports will serve as a "representative" report.
186661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  if (!BT.isSuppressOnSink()) {
186761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) {
18689c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const ExplodedNode *N = I->getErrorNode();
186961f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      if (N) {
187061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek        R = *I;
187140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek        bugReports.push_back(R);
187261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      }
187361f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    }
187406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    return R;
187561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  }
187661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
187706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // For bug reports that should be suppressed when all paths are post-dominated
187806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // by a sink node, iterate through the reports in the equivalence class
187906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // until we find one that isn't post-dominated (if one exists).  We use a
188006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // DFS traversal of the ExplodedGraph to find a non-sink node.  We could write
188106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // this as a recursive function, but we don't want to risk blowing out the
188206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // stack for very long paths.
188340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *exampleReport = 0;
188461f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
188506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  for (; I != E; ++I) {
188606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    R = *I;
188740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    const ExplodedNode *errorNode = R->getErrorNode();
188806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
188940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (!errorNode)
189006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      continue;
189140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (errorNode->isSink()) {
1892b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable(
189306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek           "BugType::isSuppressSink() should not be 'true' for sink end nodes");
189406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    }
189561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    // No successors?  By definition this nodes isn't post-dominated by a sink.
189640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (errorNode->succ_empty()) {
189740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      bugReports.push_back(R);
189840406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      if (!exampleReport)
189940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek        exampleReport = R;
190061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      continue;
190161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    }
190261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
190306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    // At this point we know that 'N' is not a sink and it has at least one
190406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    // successor.  Use a DFS worklist to find a non-sink end-of-path node.
190506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    typedef FRIEC_WLItem WLItem;
19065f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    typedef SmallVector<WLItem, 10> DFSWorkList;
190706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    llvm::DenseMap<const ExplodedNode *, unsigned> Visited;
190806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
190906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    DFSWorkList WL;
191040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    WL.push_back(errorNode);
191140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    Visited[errorNode] = 1;
191206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
191306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    while (!WL.empty()) {
191406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      WLItem &WI = WL.back();
191506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      assert(!WI.N->succ_empty());
191606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
191706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      for (; WI.I != WI.E; ++WI.I) {
191806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        const ExplodedNode *Succ = *WI.I;
191906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // End-of-path node?
192006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        if (Succ->succ_empty()) {
192161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          // If we found an end-of-path node that is not a sink.
192261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          if (!Succ->isSink()) {
192340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek            bugReports.push_back(R);
192440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek            if (!exampleReport)
192540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek              exampleReport = R;
192661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek            WL.clear();
192761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek            break;
192861f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          }
192906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          // Found a sink?  Continue on to the next successor.
193006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          continue;
193106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        }
193206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // Mark the successor as visited.  If it hasn't been explored,
193306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // enqueue it to the DFS worklist.
193406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        unsigned &mark = Visited[Succ];
193506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        if (!mark) {
193606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          mark = 1;
193706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          WL.push_back(Succ);
193806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          break;
193906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        }
194006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      }
194161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
194261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      // The worklist may have been cleared at this point.  First
194361f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      // check if it is empty before checking the last item.
194461f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      if (!WL.empty() && &WL.back() == &WI)
194506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        WL.pop_back();
194606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    }
194706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  }
194806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
194961f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  // ExampleReport will be NULL if all the nodes in the equivalence class
195061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  // were post-dominated by sinks.
195140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  return exampleReport;
195261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek}
1953e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1954e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek//===----------------------------------------------------------------------===//
1955e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek// DiagnosticCache.  This is a hack to cache analyzer diagnostics.  It
1956e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek// uses global state, which eventually should go elsewhere.
1957e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek//===----------------------------------------------------------------------===//
1958e0a58073b76fc016325a35152533b8468df2bf4aTed Kremeneknamespace {
1959ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass DiagCacheItem : public llvm::FoldingSetNode {
1960e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  llvm::FoldingSetNodeID ID;
1961e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenekpublic:
1962e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  DiagCacheItem(BugReport *R, PathDiagnostic *PD) {
19634522e2a9e7fa0313e8e5a388d8f0ab66feccc6afAnna Zaks    R->Profile(ID);
19644522e2a9e7fa0313e8e5a388d8f0ab66feccc6afAnna Zaks    PD->Profile(ID);
1965e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  }
1966e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1967e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  void Profile(llvm::FoldingSetNodeID &id) {
1968e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek    id = ID;
1969e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  }
1970e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1971e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  llvm::FoldingSetNodeID &getID() { return ID; }
1972e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek};
1973e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek}
1974e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1975e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenekstatic bool IsCachedDiagnostic(BugReport *R, PathDiagnostic *PD) {
1976e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  // FIXME: Eventually this diagnostic cache should reside in something
1977e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  // like AnalysisManager instead of being a static variable.  This is
1978e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  // really unsafe in the long term.
1979e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  typedef llvm::FoldingSet<DiagCacheItem> DiagnosticCache;
1980e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  static DiagnosticCache DC;
1981e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1982e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  void *InsertPos;
1983e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  DiagCacheItem *Item = new DiagCacheItem(R, PD);
1984e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1985e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  if (DC.FindNodeOrInsertPos(Item->getID(), InsertPos)) {
1986e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek    delete Item;
1987e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek    return true;
1988e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  }
1989e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1990e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  DC.InsertNode(Item, InsertPos);
1991e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  return false;
1992e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek}
1993e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1994cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekvoid BugReporter::FlushReport(BugReportEquivClass& EQ) {
19955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<BugReport*, 10> bugReports;
199640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *exampleReport = FindReportInEquivalenceClass(EQ, bugReports);
199740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  if (!exampleReport)
199806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    return;
199906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
2000ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer* PD = getPathDiagnosticConsumer();
20011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2002cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Make sure we use the 'R' for the path that was actually used.
20031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Probably doesn't make a difference in practice.
200440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugType& BT = exampleReport->getBugType();
20051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20066f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<PathDiagnostic>
200740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    D(new PathDiagnostic(exampleReport->getBugType().getName(),
2008da0e8429a3598acfdd0ecf15135d432e4dd3517cTed Kremenek                         !PD || PD->useVerboseDescription()
200940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek                         ? exampleReport->getDescription()
201040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek                         : exampleReport->getShortDescription(),
2011d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek                         BT.getCategory()));
2012d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
201340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  if (!bugReports.empty())
201440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    GeneratePathDiagnostic(*D.get(), bugReports);
20151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
201640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  if (IsCachedDiagnostic(exampleReport, D.get()))
2017e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek    return;
2018e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
2019072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek  // Get the meta data.
20207f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks  const BugReport::ExtraTextList &Meta =
20217f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks                                  exampleReport->getExtraText();
20227f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks  for (BugReport::ExtraTextList::const_iterator i = Meta.begin(),
20237f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks                                                e = Meta.end(); i != e; ++i) {
20247f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks    D->addMeta(*i);
20257f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks  }
202675840e1501563fe7c3dcb5600b75965ba1fe1bc4Ted Kremenek
20273148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  // Emit a summary diagnostic to the regular Diagnostics engine.
2028640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis  BugReport::ranges_iterator Beg, End;
2029640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis  llvm::tie(Beg, End) = exampleReport->getRanges();
2030d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diag = getDiagnostic();
2031c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek
2032c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek  // Search the description for '%', as that will be interpretted as a
2033c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek  // format character by FormatDiagnostics.
20345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  StringRef desc = exampleReport->getShortDescription();
2035c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek  unsigned ErrorDiag;
2036c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek  {
2037f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith    SmallString<512> TmpStr;
2038c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek    llvm::raw_svector_ostream Out(TmpStr);
20395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    for (StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I)
2040c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek      if (*I == '%')
2041c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek        Out << "%%";
2042c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek      else
2043c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek        Out << *I;
2044c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek
2045c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek    Out.flush();
2046d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie    ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning, TmpStr);
2047c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek  }
20480a14eee528a901c16f0e288fbc10a3abc1660d87Chris Lattner
2049b6b7e7bff3101062521de6e79533a3c25e2195d9Argyrios Kyrtzidis  {
2050590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    DiagnosticBuilder diagBuilder = Diag.Report(
2051590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      exampleReport->getLocation(getSourceManager()).asLocation(), ErrorDiag);
2052640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis    for (BugReport::ranges_iterator I = Beg; I != End; ++I)
2053b6b7e7bff3101062521de6e79533a3c25e2195d9Argyrios Kyrtzidis      diagBuilder << *I;
20542f0e89ea96292d2974eb1a7dddc0e9870aa86bb7Ted Kremenek  }
20553148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek
2056ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  // Emit a full diagnostic for the path if we have a PathDiagnosticConsumer.
20573148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  if (!PD)
20583148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek    return;
20591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2060802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek  if (D->path.empty()) {
2061590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    PathDiagnosticPiece *piece = new PathDiagnosticEventPiece(
2062590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                 exampleReport->getLocation(getSourceManager()),
2063590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                 exampleReport->getDescription());
20641fbfd5b9b8b82aea084773b76dd1ec6796a7000cTed Kremenek
20653148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek    for ( ; Beg != End; ++Beg) piece->addRange(*Beg);
20662042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    D->getActivePath().push_back(piece);
20673148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  }
20681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20693148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  PD->HandlePathDiagnostic(D.take());
207061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
207157202071e477530e9348bc76671ee369b2399b92Ted Kremenek
20725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid BugReporter::EmitBasicReport(StringRef name, StringRef str,
2073590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                  PathDiagnosticLocation Loc,
20748c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek                                  SourceRange* RBeg, unsigned NumRanges) {
20758c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek  EmitBasicReport(name, "", str, Loc, RBeg, NumRanges);
20768c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek}
2077cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
20785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid BugReporter::EmitBasicReport(StringRef name,
20795f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  StringRef category,
2080590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                  StringRef str, PathDiagnosticLocation Loc,
20818c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek                                  SourceRange* RBeg, unsigned NumRanges) {
20821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2083404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // 'BT' is owned by BugReporter.
2084404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugType *BT = getBugTypeForName(name, category);
2085590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  BugReport *R = new BugReport(*BT, str, Loc);
2086cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  for ( ; NumRanges > 0 ; --NumRanges, ++RBeg) R->addRange(*RBeg);
2087cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  EmitReport(R);
2088cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek}
2089404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
20905f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerBugType *BugReporter::getBugTypeForName(StringRef name,
20915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                        StringRef category) {
2092f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<136> fullDesc;
2093404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  llvm::raw_svector_ostream(fullDesc) << name << ":" << category;
2094404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  llvm::StringMapEntry<BugType *> &
2095404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis      entry = StrBugTypes.GetOrCreateValue(fullDesc);
2096404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugType *BT = entry.getValue();
2097404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  if (!BT) {
2098404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    BT = new BugType(name, category);
2099404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    entry.setValue(BT);
2100404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  }
2101404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  return BT;
2102404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis}
2103