BugReporter.cpp revision 0b3ade86a1c60cf0c7b56aa238aff458eb7f5974
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.
15176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        if (event->isPrunable())
15276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek          continue;
15376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        containsSomethingInteresting = true;
154725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
155725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      }
156725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::ControlFlow:
157725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
158c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    }
159c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
160c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    pieces.push_back(piece);
161c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  }
162c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
163c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  return containsSomethingInteresting;
164c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek}
165c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
166c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek//===----------------------------------------------------------------------===//
1673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// PathDiagnosticBuilder and its associated routines and helper objects.
168b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek//===----------------------------------------------------------------------===//
169b479dadea93b93d3f0a335c3518b703f140b3f50Ted Kremenek
170c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xutypedef llvm::DenseMap<const ExplodedNode*,
171c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuconst ExplodedNode*> NodeBackMap;
1727dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek
173babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremeneknamespace {
174ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass NodeMapClosure : public BugReport::NodeResolver {
1757dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeBackMap& M;
1767dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenekpublic:
1777dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeMapClosure(NodeBackMap *m) : M(*m) {}
1787dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  ~NodeMapClosure() {}
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1809c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *getOriginalNode(const ExplodedNode *N) {
1817dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    NodeBackMap::iterator I = M.find(N);
1827dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    return I == M.end() ? 0 : I->second;
1837dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  }
1847dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek};
1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
186ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass PathDiagnosticBuilder : public BugReporterContext {
1877dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  BugReport *R;
188ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer *PDC;
1896f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ParentMap> PM;
1907dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeMapClosure NMC;
1911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
19259950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  const LocationContext *LC;
19359950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek
1948966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  PathDiagnosticBuilder(GRBugReporter &br,
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        BugReport *r, NodeBackMap *Backmap,
196ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie                        PathDiagnosticConsumer *pdc)
1978966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    : BugReporterContext(br),
19859950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek      R(r), PDC(pdc), NMC(Backmap), LC(r->getErrorNode()->getLocationContext())
19959950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  {}
2001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2019c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PathDiagnosticLocation ExecutionContinues(const ExplodedNode *N);
2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2039c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream &os,
2049c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                            const ExplodedNode *N);
2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2068e6431adab313e283a992698f6fc7afe62420999Anna Zaks  BugReport *getBugReport() { return R; }
2078e6431adab313e283a992698f6fc7afe62420999Anna Zaks
208212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care  Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); }
20959950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek
21059950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  ParentMap& getParentMap() { return LC->getParentMap(); }
2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
212c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek  const Stmt *getParent(const Stmt *S) {
213c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek    return getParentMap().getParent(S);
214c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek  }
2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2168966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual NodeMapClosure& getNodeResolver() { return NMC; }
2177297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor
218d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S);
2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
220ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer::PathGenerationScheme getGenerationScheme() const {
221ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    return PDC ? PDC->getGenerationScheme() : PathDiagnosticConsumer::Extensive;
2227dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  }
2237dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek
224babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek  bool supportsLogicalOpControlFlow() const {
225babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek    return PDC ? PDC->supportsLogicalOpControlFlow() : true;
2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
227babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek};
228babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek} // end anonymous namespace
229babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek
23000605e0f011ed99225a22026344c5fc1b3212cd7Ted KremenekPathDiagnosticLocation
2319c378f705405d37f49795d5e915989de774fe11fTed KremenekPathDiagnosticBuilder::ExecutionContinues(const ExplodedNode *N) {
2325f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (const Stmt *S = GetNextStmt(N))
23359950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek    return PathDiagnosticLocation(S, getSourceManager(), LC);
23400605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek
2350cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks  return PathDiagnosticLocation::createDeclEnd(N->getLocationContext(),
2360cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                                               getSourceManager());
237082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek}
2381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23900605e0f011ed99225a22026344c5fc1b3212cd7Ted KremenekPathDiagnosticLocation
2409c378f705405d37f49795d5e915989de774fe11fTed KremenekPathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream &os,
2419c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                          const ExplodedNode *N) {
242babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek
243143ca222583a4a355fdc89af852deef287499300Ted Kremenek  // Slow, but probably doesn't matter.
244b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  if (os.str().empty())
245b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    os << ' ';
2461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24700605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek  const PathDiagnosticLocation &Loc = ExecutionContinues(N);
2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24900605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek  if (Loc.asStmt())
250b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    os << "Execution continues on line "
251642116259e8df6286063a17361c20e95b5017a0aChandler Carruth       << getSourceManager().getExpansionLineNumber(Loc.asLocation())
2528966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek       << '.';
2534f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek  else {
2544f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    os << "Execution jumps to the end of the ";
2554f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    const Decl *D = N->getLocationContext()->getDecl();
2564f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    if (isa<ObjCMethodDecl>(D))
2574f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "method";
2584f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    else if (isa<FunctionDecl>(D))
2594f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "function";
2604f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    else {
2614f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      assert(isa<BlockDecl>(D));
2624f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "anonymous block";
2634f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    }
2644f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    os << '.';
2654f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek  }
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
267082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek  return Loc;
268143ca222583a4a355fdc89af852deef287499300Ted Kremenek}
269143ca222583a4a355fdc89af852deef287499300Ted Kremenek
270ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenekstatic bool IsNested(const Stmt *S, ParentMap &PM) {
271ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  if (isa<Expr>(S) && PM.isConsumedExpr(cast<Expr>(S)))
272ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    return true;
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
274ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  const Stmt *Parent = PM.getParentIgnoreParens(S);
2751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
276ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  if (Parent)
277ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    switch (Parent->getStmtClass()) {
278ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::ForStmtClass:
279ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::DoStmtClass:
280ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::WhileStmtClass:
281ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        return true;
282ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      default:
283ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        break;
284ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    }
2851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return false;
287ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek}
288ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek
289d8c938b0f6b7a7156181be575239e4c6e15a2adbTed KremenekPathDiagnosticLocation
290d8c938b0f6b7a7156181be575239e4c6e15a2adbTed KremenekPathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
2919c378f705405d37f49795d5e915989de774fe11fTed Kremenek  assert(S && "Null Stmt *passed to getEnclosingStmtLocation");
2921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ParentMap &P = getParentMap();
2938966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  SourceManager &SMgr = getSourceManager();
294e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
295ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  while (IsNested(S, P)) {
2968c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    const Stmt *Parent = P.getParentIgnoreParens(S);
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
298af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    if (!Parent)
299af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      break;
3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
301af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    switch (Parent->getStmtClass()) {
3025fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      case Stmt::BinaryOperatorClass: {
3035fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        const BinaryOperator *B = cast<BinaryOperator>(Parent);
3045fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        if (B->isLogicalOp())
305220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
3065fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        break;
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
308af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::CompoundStmtClass:
309af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::StmtExprClass:
310220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks        return PathDiagnosticLocation(S, SMgr, LC);
3111d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek      case Stmt::ChooseExprClass:
3121d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // Similar to '?' if we are referring to condition, just have the edge
3131d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // point to the entire choose expression.
3141d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        if (cast<ChooseExpr>(Parent)->getCond() == S)
315220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
3161d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        else
317220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
31856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      case Stmt::BinaryConditionalOperatorClass:
3191d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek      case Stmt::ConditionalOperatorClass:
3201d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // For '?', if we are referring to condition, just have the edge point
3211d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // to the entire '?' expression.
32256ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        if (cast<AbstractConditionalOperator>(Parent)->getCond() == S)
323220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
3241d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        else
325220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
326af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::DoStmtClass:
327220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
328af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::ForStmtClass:
329af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<ForStmt>(Parent)->getBody() == S)
330220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
3311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        break;
332af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::IfStmtClass:
333af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<IfStmt>(Parent)->getCond() != S)
334220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
3358bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek        break;
336af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::ObjCForCollectionStmtClass:
337af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<ObjCForCollectionStmt>(Parent)->getBody() == S)
338220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
339af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
340af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::WhileStmtClass:
341af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<WhileStmt>(Parent)->getCond() != S)
342220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
343af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
344af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      default:
345af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
346af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    }
347af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek
348d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek    S = Parent;
349d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  }
3501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
351d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  assert(S && "Cannot have null Stmt for PathDiagnosticLocation");
352e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
353e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  // Special case: DeclStmts can appear in for statement declarations, in which
354e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  //  case the ForStmt is the context.
355e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  if (isa<DeclStmt>(S)) {
356e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    if (const Stmt *Parent = P.getParent(S)) {
357e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek      switch (Parent->getStmtClass()) {
358e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        case Stmt::ForStmtClass:
359e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        case Stmt::ObjCForCollectionStmtClass:
360220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
361e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        default:
362e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek          break;
3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
3641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
365e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  }
366e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  else if (isa<BinaryOperator>(S)) {
367e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // Special case: the binary operator represents the initialization
368e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // code in a for statement (this can happen when the variable being
369e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // initialized is an old variable.
370e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    if (const ForStmt *FS =
371e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek          dyn_cast_or_null<ForStmt>(P.getParentIgnoreParens(S))) {
372e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek      if (FS->getInit() == S)
373220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks        return PathDiagnosticLocation(FS, SMgr, LC);
374e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    }
375e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  }
376e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
377220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks  return PathDiagnosticLocation(S, SMgr, LC);
378d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek}
379d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
380cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
3813106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// "Minimal" path diagnostic generation algorithm.
382cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
38356a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zakstypedef std::pair<PathDiagnosticCallPiece*, const ExplodedNode*> StackDiagPair;
38456a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zakstypedef SmallVector<StackDiagPair, 6> StackDiagVector;
38556a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks
386368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaksstatic void updateStackPiecesWithMessage(PathDiagnosticPiece *P,
38756a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks                                         StackDiagVector &CallStack) {
388368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks  // If the piece contains a special message, add it to all the call
389368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks  // pieces on the active stack.
390368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks  if (PathDiagnosticEventPiece *ep =
391368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        dyn_cast<PathDiagnosticEventPiece>(P)) {
392368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
39356a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks    if (ep->hasCallStackHint())
39456a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks      for (StackDiagVector::iterator I = CallStack.begin(),
39556a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks                                     E = CallStack.end(); I != E; ++I) {
39656a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks        PathDiagnosticCallPiece *CP = I->first;
39756a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks        const ExplodedNode *N = I->second;
3988fe4525680ce72e90cee3e58b5654e3ae955447fNAKAMURA Takumi        std::string stackMsg = ep->getCallStackMessage(N);
39956a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks
400368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        // The last message on the path to final bug is the most important
401368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        // one. Since we traverse the path backwards, do not add the message
402368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        // if one has been previously added.
40356a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks        if  (!CP->hasCallStackMessage())
40456a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks          CP->setCallStackMessage(stackMsg);
40556a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks      }
406368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks  }
407368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks}
408cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
40977d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenekstatic void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
41014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
4113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekstatic void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
4123106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                          PathDiagnosticBuilder &PDB,
4133bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                          const ExplodedNode *N,
4143bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                      ArrayRef<BugReporterVisitor *> visitors) {
4158966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
4163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  SourceManager& SMgr = PDB.getSourceManager();
41759950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  const LocationContext *LC = PDB.LC;
4189c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *NextNode = N->pred_empty()
4193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                        ? NULL : *(N->pred_begin());
420368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
42156a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks  StackDiagVector CallStack;
422368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
4233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  while (NextNode) {
4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    N = NextNode;
42559950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek    PDB.LC = N->getLocationContext();
4263106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    NextNode = GetPredecessorNode(N);
4271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
42861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek    ProgramPoint P = N->getLocation();
4292042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek
4300b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks    if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
4312042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PathDiagnosticCallPiece *C =
4322042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PathDiagnosticCallPiece::construct(N, *CE, SMgr);
4332042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PD.getActivePath().push_front(C);
4342042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PD.pushActivePath(&C->path);
43556a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks      CallStack.push_back(StackDiagPair(C, N));
4362042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      continue;
4372042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    }
4382042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek
4392042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
4402042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PD.popActivePath();
4412042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // The current active path should never be empty.  Either we
4422042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // just added a bunch of stuff to the top-level path, or
4430b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      // we have a previous CallExitEnd.  If the front of the active
4442042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // path is not a PathDiagnosticCallPiece, it means that the
4452042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // path terminated within a function call.  We must then take the
4462042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // current contents of the active path and place it within
4472042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // a new PathDiagnosticCallPiece.
4482042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      assert(!PD.getActivePath().empty());
4492042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      PathDiagnosticCallPiece *C =
4502042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
4519373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks      if (!C) {
4529373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks        const Decl *Caller = CE->getLocationContext()->getDecl();
4539373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks        C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
4549373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks      }
4552042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      C->setCallee(*CE, SMgr);
456368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks      if (!CallStack.empty()) {
45756a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks        assert(CallStack.back().first == C);
458368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        CallStack.pop_back();
459368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks      }
4602042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      continue;
4612042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    }
4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4639c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
4649c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const CFGBlock *Src = BE->getSrc();
4659c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const CFGBlock *Dst = BE->getDst();
4669c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const Stmt *T = Src->getTerminator();
4671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
46861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek      if (!T)
46961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        continue;
4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
471590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      PathDiagnosticLocation Start =
472590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        PathDiagnosticLocation::createBegin(T, SMgr,
473590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                                N->getLocationContext());
4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek      switch (T->getStmtClass()) {
47661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        default:
47761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
4781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
47961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        case Stmt::GotoStmtClass:
4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::IndirectGotoStmtClass: {
4819c378f705405d37f49795d5e915989de774fe11fTed Kremenek          const Stmt *S = GetNextStmt(N);
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          if (!S)
48461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek            continue;
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
486297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
4871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          llvm::raw_string_ostream os(sbuf);
488d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek          const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S);
4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49000605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          os << "Control jumps to line "
491642116259e8df6286063a17361c20e95b5017a0aChandler Carruth          << End.asLocation().getExpansionLineNumber();
4922042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
493802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek                                                                os.str()));
49461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
49561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        }
4961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::SwitchStmtClass: {
49861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          // Figure out what case arm we took.
499297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
500297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
5011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5029c378f705405d37f49795d5e915989de774fe11fTed Kremenek          if (const Stmt *S = Dst->getLabel()) {
503220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks            PathDiagnosticLocation End(S, SMgr, LC);
5041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5055a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek            switch (S->getStmtClass()) {
506082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek              default:
507082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                os << "No cases match in the switch statement. "
5083106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                "Control jumps to line "
509642116259e8df6286063a17361c20e95b5017a0aChandler Carruth                << End.asLocation().getExpansionLineNumber();
510082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                break;
511082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek              case Stmt::DefaultStmtClass:
512082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                os << "Control jumps to the 'default' case at line "
513642116259e8df6286063a17361c20e95b5017a0aChandler Carruth                << End.asLocation().getExpansionLineNumber();
514082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                break;
5151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
516082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek              case Stmt::CaseStmtClass: {
5171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                os << "Control jumps to 'case ";
5189c378f705405d37f49795d5e915989de774fe11fTed Kremenek                const CaseStmt *Case = cast<CaseStmt>(S);
5199c378f705405d37f49795d5e915989de774fe11fTed Kremenek                const Expr *LHS = Case->getLHS()->IgnoreParenCasts();
5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                // Determine if it is an enum.
522082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                bool GetRawInt = true;
5231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5249c378f705405d37f49795d5e915989de774fe11fTed Kremenek                if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS)) {
525082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                  // FIXME: Maybe this should be an assertion.  Are there cases
526082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                  // were it is not an EnumConstantDecl?
5279c378f705405d37f49795d5e915989de774fe11fTed Kremenek                  const EnumConstantDecl *D =
52803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                    dyn_cast<EnumConstantDecl>(DR->getDecl());
5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
530082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                  if (D) {
531082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                    GetRawInt = false;
532b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer                    os << *D;
533082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                  }
5345a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek                }
5359ec64d6e2fe575b297e1eaa5051efc2983373e25Eli Friedman
5369ec64d6e2fe575b297e1eaa5051efc2983373e25Eli Friedman                if (GetRawInt)
537a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith                  os << LHS->EvaluateKnownConstInt(PDB.getASTContext());
5389ec64d6e2fe575b297e1eaa5051efc2983373e25Eli Friedman
53900605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek                os << ":'  at line "
540642116259e8df6286063a17361c20e95b5017a0aChandler Carruth                << End.asLocation().getExpansionLineNumber();
541082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                break;
542082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek              }
54361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek            }
5442042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
54500605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek                                                             os.str()));
54661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          }
547567839273dfc395a459cbe77d5f8d128b9ae85bfTed Kremenek          else {
548c3517ebb48a51e146badc08bc3684520c41da6c8Ted Kremenek            os << "'Default' branch taken. ";
5491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
5502042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
55100605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek                                                             os.str()));
552567839273dfc395a459cbe77d5f8d128b9ae85bfTed Kremenek          }
5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
55561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        }
5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5572673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        case Stmt::BreakStmtClass:
5582673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        case Stmt::ContinueStmtClass: {
559297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
560297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
56100605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
5622042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
563082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                                                           os.str()));
5642673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek          break;
5652673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        }
5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          // Determine control-flow for ternary '?'.
56856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        case Stmt::BinaryConditionalOperatorClass:
569706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek        case Stmt::ConditionalOperatorClass: {
570297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
571297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
5721d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek          os << "'?' condition is ";
5731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
574706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          if (*(Src->succ_begin()+1) == Dst)
575082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek            os << "false";
576706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          else
577082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek            os << "true";
5781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
57900605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
5801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5811d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek          if (const Stmt *S = End.asStmt())
5821d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek            End = PDB.getEnclosingStmtLocation(S);
5831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5842042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
585babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek                                                           os.str()));
586babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          break;
587babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek        }
5881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5893106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          // Determine control-flow for short-circuited '&&' and '||'.
590babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek        case Stmt::BinaryOperatorClass: {
591babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          if (!PDB.supportsLogicalOpControlFlow())
592babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek            break;
5931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu          const BinaryOperator *B = cast<BinaryOperator>(T);
595babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          std::string sbuf;
596babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          llvm::raw_string_ostream os(sbuf);
597babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          os << "Left side of '";
5981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5992de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall          if (B->getOpcode() == BO_LAnd) {
600f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            os << "&&" << "' is ";
6011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
602f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            if (*(Src->succ_begin()+1) == Dst) {
603f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "false";
604220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
6050cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation Start =
6060cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                PathDiagnosticLocation::createOperatorLoc(B, SMgr);
6072042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
608f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek                                                               os.str()));
6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
610f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            else {
611f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "true";
612220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
613f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
6142042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
615f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek                                                               os.str()));
6161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
617babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          }
618babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          else {
6192de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall            assert(B->getOpcode() == BO_LOr);
620f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            os << "||" << "' is ";
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
622f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            if (*(Src->succ_begin()+1) == Dst) {
623f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "false";
624220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
625f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
6262042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                               os.str()));
628f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            }
629f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            else {
630f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "true";
631220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
6320cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation Start =
6330cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                PathDiagnosticLocation::createOperatorLoc(B, SMgr);
6342042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
6351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                                               os.str()));
636f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            }
637babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          }
6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
639706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          break;
640706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek        }
6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::DoStmtClass:  {
643706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          if (*(Src->succ_begin()) == Dst) {
644297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek            std::string sbuf;
645297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek            llvm::raw_string_ostream os(sbuf);
6461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
647c3517ebb48a51e146badc08bc3684520c41da6c8Ted Kremenek            os << "Loop condition is true. ";
648d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
6491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
650d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            if (const Stmt *S = End.asStmt())
651d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek              End = PDB.getEnclosingStmtLocation(S);
6521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6532042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
654082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek                                                             os.str()));
655082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek          }
656082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek          else {
65700605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
6581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
659d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            if (const Stmt *S = End.asStmt())
660d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek              End = PDB.getEnclosingStmtLocation(S);
6611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6622042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
6633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                              "Loop condition is false.  Exiting loop"));
6643106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
6651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
6673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
6681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6693106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        case Stmt::WhileStmtClass:
6701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::ForStmtClass: {
6713106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (*(Src->succ_begin()+1) == Dst) {
6723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            std::string sbuf;
6733106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            llvm::raw_string_ostream os(sbuf);
6741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6753106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            os << "Loop condition is false. ";
6763106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
6773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            if (const Stmt *S = End.asStmt())
6783106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek              End = PDB.getEnclosingStmtLocation(S);
6791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6802042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
6813106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                                             os.str()));
6823106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
6833106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          else {
6843106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
6853106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            if (const Stmt *S = End.asStmt())
6863106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek              End = PDB.getEnclosingStmtLocation(S);
6871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6882042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
6895fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek                            "Loop condition is true.  Entering loop body"));
6903106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
6911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6923106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
6933106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
6941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6953106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        case Stmt::IfStmtClass: {
6963106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
6971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6983106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (const Stmt *S = End.asStmt())
6993106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            End = PDB.getEnclosingStmtLocation(S);
7001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (*(Src->succ_begin()+1) == Dst)
7022042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
7035fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek                                                        "Taking false branch"));
7041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          else
7052042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
7065fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek                                                         "Taking true branch"));
7071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7083106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
7093106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
7103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
7113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
713dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    if (NextNode) {
7148e6431adab313e283a992698f6fc7afe62420999Anna Zaks      // Add diagnostic pieces from custom visitors.
7158e6431adab313e283a992698f6fc7afe62420999Anna Zaks      BugReport *R = PDB.getBugReport();
7163bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
7173bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                                    E = visitors.end();
7183bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose           I != E; ++I) {
719368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
7202042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(p);
721368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks          updateStackPiecesWithMessage(p, CallStack);
722368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        }
723dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      }
7248966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    }
7253106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
7261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // After constructing the full PathDiagnostic, do a pass over it to compact
72814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // PathDiagnosticPieces that occur within a macro.
72977d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  CompactPathDiagnostic(PD.getMutablePieces(), PDB.getSourceManager());
7303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
7313106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
7323106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
7335fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek// "Extensive" PathDiagnostic generation.
7345fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek//===----------------------------------------------------------------------===//
7355fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek
7365fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenekstatic bool IsControlFlowExpr(const Stmt *S) {
7375fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  const Expr *E = dyn_cast<Expr>(S);
7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7395fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  if (!E)
7405fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    return false;
7411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  E = E->IgnoreParenCasts();
7431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  if (isa<AbstractConditionalOperator>(E))
7455fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    return true;
7461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7475fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E))
7485fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    if (B->isLogicalOp())
7495fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      return true;
7501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return false;
7525fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek}
7535fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek
75414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremeneknamespace {
755ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass ContextLocation : public PathDiagnosticLocation {
7568f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool IsDead;
7578f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenekpublic:
7588f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  ContextLocation(const PathDiagnosticLocation &L, bool isdead = false)
7598f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    : PathDiagnosticLocation(L), IsDead(isdead) {}
7601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void markDead() { IsDead = true; }
7628f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool isDead() const { return IsDead; }
7638f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek};
7641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
765ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass EdgeBuilder {
7668f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  std::vector<ContextLocation> CLocs;
7678f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  typedef std::vector<ContextLocation>::iterator iterator;
76814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnostic &PD;
76914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticBuilder &PDB;
77014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticLocation PrevLoc;
7711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7728f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool IsConsumedExpr(const PathDiagnosticLocation &L);
7731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  bool containsLocation(const PathDiagnosticLocation &Container,
77514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                        const PathDiagnosticLocation &Containee);
7761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L);
7781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7799650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek  PathDiagnosticLocation cleanUpLocation(PathDiagnosticLocation L,
7809650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek                                         bool firstCharOnly = false) {
7818c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    if (const Stmt *S = L.asStmt()) {
7829650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek      const Stmt *Original = S;
7838c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek      while (1) {
7848c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek        // Adjust the location for some expressions that are best referenced
7858c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek        // by one of their subexpressions.
7869650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        switch (S->getStmtClass()) {
7879650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          default:
7889650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            break;
7899650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ParenExprClass:
790f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne          case Stmt::GenericSelectionExprClass:
791f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne            S = cast<Expr>(S)->IgnoreParens();
7929650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
7939650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
79456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall          case Stmt::BinaryConditionalOperatorClass:
7959650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ConditionalOperatorClass:
79656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall            S = cast<AbstractConditionalOperator>(S)->getCond();
7979650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
7989650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
7999650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ChooseExprClass:
8009650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            S = cast<ChooseExpr>(S)->getCond();
8019650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
8029650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
8039650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::BinaryOperatorClass:
8049650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            S = cast<BinaryOperator>(S)->getLHS();
8059650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
8069650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
8079650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        }
8081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8099650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        break;
8108c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek      }
8111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8129650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek      if (S != Original)
81359950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek        L = PathDiagnosticLocation(S, L.getManager(), PDB.LC);
8148c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    }
8151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8169650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek    if (firstCharOnly)
8171531bb0c69d9afff6a6434e4cadf345eb628b287Anna Zaks      L  = PathDiagnosticLocation::createSingleLocation(L);
8189650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek
8198c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    return L;
8208c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  }
8211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
82214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void popLocation() {
8238f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    if (!CLocs.back().isDead() && CLocs.back().asLocation().isFileID()) {
8245c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek      // For contexts, we only one the first character as the range.
82507c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek      rawAddEdge(cleanUpLocation(CLocs.back(), true));
8265c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek    }
82714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    CLocs.pop_back();
82814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
8291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
83014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekpublic:
83114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  EdgeBuilder(PathDiagnostic &pd, PathDiagnosticBuilder &pdb)
83214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    : PD(pd), PDB(pdb) {
8331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
834a301a6773db085575ac51e3c966858180390c25bTed Kremenek      // If the PathDiagnostic already has pieces, add the enclosing statement
835a301a6773db085575ac51e3c966858180390c25bTed Kremenek      // of the first piece as a context as well.
836802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek      if (!PD.path.empty()) {
837802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek        PrevLoc = (*PD.path.begin())->getLocation();
8381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
83914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        if (const Stmt *S = PrevLoc.asStmt())
840e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek          addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
84114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      }
84214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
84314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
84414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  ~EdgeBuilder() {
84514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    while (!CLocs.empty()) popLocation();
8460cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks
847a301a6773db085575ac51e3c966858180390c25bTed Kremenek    // Finally, add an initial edge from the start location of the first
848a301a6773db085575ac51e3c966858180390c25bTed Kremenek    // statement (if it doesn't already exist).
8490cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks    PathDiagnosticLocation L = PathDiagnosticLocation::createDeclBegin(
85059950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek                                                       PDB.LC,
8510cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                                                       PDB.getSourceManager());
8520cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks    if (L.isValid())
8530cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks      rawAddEdge(L);
85414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
85514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
8565de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek  void flushLocations() {
8575de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek    while (!CLocs.empty())
8585de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      popLocation();
8595de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek    PrevLoc = PathDiagnosticLocation();
8605de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek  }
8615de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
86214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd = false);
8631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8648bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek  void rawAddEdge(PathDiagnosticLocation NewLoc);
8651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
86614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void addContext(const Stmt *S);
867e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  void addExtendedContext(const Stmt *S);
8681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
86914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek} // end anonymous namespace
87014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
87114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
87214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted KremenekPathDiagnosticLocation
87314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted KremenekEdgeBuilder::getContextLocation(const PathDiagnosticLocation &L) {
87414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (const Stmt *S = L.asStmt()) {
87514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (IsControlFlowExpr(S))
87614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return L;
8771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return PDB.getEnclosingStmtLocation(S);
87914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
8801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
88114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  return L;
88214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
88314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
88414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekbool EdgeBuilder::containsLocation(const PathDiagnosticLocation &Container,
88514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                                   const PathDiagnosticLocation &Containee) {
88614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
88714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (Container == Containee)
88814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return true;
8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
89014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (Container.asDecl())
89114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return true;
8921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
89314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (const Stmt *S = Containee.asStmt())
89414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (const Stmt *ContainerS = Container.asStmt()) {
89514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      while (S) {
89614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        if (S == ContainerS)
89714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          return true;
89814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        S = PDB.getParent(S);
89914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      }
90014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return false;
90114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
90214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
90314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // Less accurate: compare using source ranges.
90414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceRange ContainerR = Container.asRange();
90514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceRange ContaineeR = Containee.asRange();
9061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
90714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceManager &SM = PDB.getSourceManager();
908402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContainerRBeg = SM.getExpansionLoc(ContainerR.getBegin());
909402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContainerREnd = SM.getExpansionLoc(ContainerR.getEnd());
910402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContaineeRBeg = SM.getExpansionLoc(ContaineeR.getBegin());
911402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContaineeREnd = SM.getExpansionLoc(ContaineeR.getEnd());
9121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
913642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContainerBegLine = SM.getExpansionLineNumber(ContainerRBeg);
914642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContainerEndLine = SM.getExpansionLineNumber(ContainerREnd);
915642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContaineeBegLine = SM.getExpansionLineNumber(ContaineeRBeg);
916642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContaineeEndLine = SM.getExpansionLineNumber(ContaineeREnd);
9171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
91814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  assert(ContainerBegLine <= ContainerEndLine);
9191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert(ContaineeBegLine <= ContaineeEndLine);
9201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
92114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  return (ContainerBegLine <= ContaineeBegLine &&
92214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          ContainerEndLine >= ContaineeEndLine &&
92314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          (ContainerBegLine != ContaineeBegLine ||
924a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContainerRBeg) <=
925a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContaineeRBeg)) &&
92614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          (ContainerEndLine != ContaineeEndLine ||
927a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContainerREnd) >=
9286488dc31153be6f98b404c7860be6c66bb4ec917Ted Kremenek           SM.getExpansionColumnNumber(ContaineeREnd)));
92914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
93014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
93114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) {
93214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (!PrevLoc.isValid()) {
93314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    PrevLoc = NewLoc;
93414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
93514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
9361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9378c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  const PathDiagnosticLocation &NewLocClean = cleanUpLocation(NewLoc);
9388c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  const PathDiagnosticLocation &PrevLocClean = cleanUpLocation(PrevLoc);
9391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9408c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  if (NewLocClean.asLocation() == PrevLocClean.asLocation())
94114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
9421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
94314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // FIXME: Ignore intra-macro edges for now.
944402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  if (NewLocClean.asLocation().getExpansionLoc() ==
945402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth      PrevLocClean.asLocation().getExpansionLoc())
94614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
94714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
9482042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek  PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
9498c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  PrevLoc = NewLoc;
95014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
95114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
95214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd) {
9531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
954a301a6773db085575ac51e3c966858180390c25bTed Kremenek  if (!alwaysAdd && NewLoc.asLocation().isMacroID())
955a301a6773db085575ac51e3c966858180390c25bTed Kremenek    return;
9561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
95714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  const PathDiagnosticLocation &CLoc = getContextLocation(NewLoc);
95814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
95914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (!CLocs.empty()) {
9608f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    ContextLocation &TopContextLoc = CLocs.back();
9611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
96214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Is the top location context the same as the one for the new location?
96314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (TopContextLoc == CLoc) {
9648f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      if (alwaysAdd) {
9654c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek        if (IsConsumedExpr(TopContextLoc) &&
9664c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek            !IsControlFlowExpr(TopContextLoc.asStmt()))
9678f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek            TopContextLoc.markDead();
9688f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek
96914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        rawAddEdge(NewLoc);
9708f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      }
97114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
97214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return;
97314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
97414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
97514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (containsLocation(TopContextLoc, CLoc)) {
9768f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      if (alwaysAdd) {
97714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        rawAddEdge(NewLoc);
9781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9794c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek        if (IsConsumedExpr(CLoc) && !IsControlFlowExpr(CLoc.asStmt())) {
9808f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek          CLocs.push_back(ContextLocation(CLoc, true));
9818f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek          return;
9828f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek        }
9838f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      }
9841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      CLocs.push_back(CLoc);
9861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return;
98714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
98814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
98914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Context does not contain the location.  Flush it.
99014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    popLocation();
99114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
9921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9935c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek  // If we reach here, there is no enclosing context.  Just add the edge.
9945c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek  rawAddEdge(NewLoc);
99514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
99614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
9978f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenekbool EdgeBuilder::IsConsumedExpr(const PathDiagnosticLocation &L) {
9988f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  if (const Expr *X = dyn_cast_or_null<Expr>(L.asStmt()))
9998f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    return PDB.getParentMap().isConsumedExpr(X) && !IsControlFlowExpr(X);
10001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10018f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  return false;
10028f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek}
10031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1004e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenekvoid EdgeBuilder::addExtendedContext(const Stmt *S) {
1005e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  if (!S)
1006e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    return;
10071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const Stmt *Parent = PDB.getParent(S);
1009e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  while (Parent) {
1010e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    if (isa<CompoundStmt>(Parent))
1011e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      Parent = PDB.getParent(Parent);
1012e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    else
1013e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      break;
1014e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  }
1015e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek
1016e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  if (Parent) {
1017e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    switch (Parent->getStmtClass()) {
1018e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      case Stmt::DoStmtClass:
1019e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      case Stmt::ObjCAtSynchronizedStmtClass:
1020e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek        addContext(Parent);
1021e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      default:
1022e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek        break;
1023e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    }
1024e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  }
10251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1026e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  addContext(S);
1027e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek}
10281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
102914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::addContext(const Stmt *S) {
103014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (!S)
103114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
103214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
103359950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.LC);
10341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
103514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (!CLocs.empty()) {
103614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    const PathDiagnosticLocation &TopContextLoc = CLocs.back();
103714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
103814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Is the top location context the same as the one for the new location?
103914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (TopContextLoc == L)
104014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return;
104114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
104214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (containsLocation(TopContextLoc, L)) {
104314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      CLocs.push_back(L);
10441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return;
104514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
104614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
104714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Context does not contain the location.  Flush it.
104814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    popLocation();
104914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
105014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
105114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  CLocs.push_back(L);
105214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
105314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
105414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekstatic void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
105514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                                            PathDiagnosticBuilder &PDB,
10563bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                            const ExplodedNode *N,
10573bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                      ArrayRef<BugReporterVisitor *> visitors) {
105814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  EdgeBuilder EB(PD, PDB);
10590cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks  const SourceManager& SM = PDB.getSourceManager();
106056a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks  StackDiagVector CallStack;
106114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
10629c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
106314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (NextNode) {
106414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    N = NextNode;
106514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    NextNode = GetPredecessorNode(N);
106614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    ProgramPoint P = N->getLocation();
106714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
1068dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    do {
10690b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
10705de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        const StackFrameContext *LCtx =
10715de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        CE->getLocationContext()->getCurrentStackFrame();
10720b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        PathDiagnosticLocation Loc(CE->getStmt(),
10735de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek                                   PDB.getSourceManager(),
10745de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek                                   LCtx);
10755de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        EB.addEdge(Loc, true);
10765de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        EB.flushLocations();
10772042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PathDiagnosticCallPiece *C =
10782042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PathDiagnosticCallPiece::construct(N, *CE, SM);
10792042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.getActivePath().push_front(C);
10802042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.pushActivePath(&C->path);
108156a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks        CallStack.push_back(StackDiagPair(C, N));
10825de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        break;
10835de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      }
10844ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek
10852042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // Pop the call hierarchy if we are done walking the contents
10862042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // of a function call.
10872042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
1088097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        // Add an edge to the start of the function.
1089097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        const Decl *D = CE->getCalleeContext()->getDecl();
1090097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        PathDiagnosticLocation pos =
1091097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek          PathDiagnosticLocation::createBegin(D, SM);
1092097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        EB.addEdge(pos);
1093097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek
1094097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        // Flush all locations, and pop the active path.
10954ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek        EB.flushLocations();
10962042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.popActivePath();
10974ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek        assert(!PD.getActivePath().empty());
10984ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek        PDB.LC = N->getLocationContext();
1099097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek
11002042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // The current active path should never be empty.  Either we
11012042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // just added a bunch of stuff to the top-level path, or
11020b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks        // we have a previous CallExitEnd.  If the front of the active
11032042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // path is not a PathDiagnosticCallPiece, it means that the
11042042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // path terminated within a function call.  We must then take the
11052042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // current contents of the active path and place it within
11062042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // a new PathDiagnosticCallPiece.
11074ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek        PathDiagnosticCallPiece *C =
11082042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
11099373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks        if (!C) {
11109373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks          const Decl * Caller = CE->getLocationContext()->getDecl();
11119373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks          C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
11129373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks        }
11132042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        C->setCallee(*CE, SM);
11142042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        EB.addContext(CE->getCallExpr());
1115368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
1116368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        if (!CallStack.empty()) {
111756a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks          assert(CallStack.back().first == C);
1118368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks          CallStack.pop_back();
1119368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        }
11202042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        break;
11212042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      }
11224ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek
11234ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      // Note that is important that we update the LocationContext
11244ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      // after looking at CallExits.  CallExit basically adds an
11254ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      // edge in the *caller*, so we don't want to update the LocationContext
11264ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      // too soon.
11274ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      PDB.LC = N->getLocationContext();
11285de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
1129dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      // Block edges.
11305de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
1131dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        const CFGBlock &Blk = *BE->getSrc();
1132dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        const Stmt *Term = Blk.getTerminator();
11331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1134dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        // Are we jumping to the head of a loop?  Add a special diagnostic.
1135ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        if (const Stmt *Loop = BE->getDst()->getLoopTarget()) {
113659950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek          PathDiagnosticLocation L(Loop, SM, PDB.LC);
1137ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          const CompoundStmt *CS = NULL;
11381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1139ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          if (!Term) {
1140ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek            if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
1141ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek              CS = dyn_cast<CompoundStmt>(FS->getBody());
1142ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek            else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
11431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump              CS = dyn_cast<CompoundStmt>(WS->getBody());
1144ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          }
11451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1146dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          PathDiagnosticEventPiece *p =
1147dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek            new PathDiagnosticEventPiece(L,
114807c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek                                        "Looping back to the head of the loop");
11492dd17abf11ae64339fa6bfaa57d76e13a5fbe5b8Ted Kremenek          p->setPrunable(true);
11501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1151dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          EB.addEdge(p->getLocation(), true);
11522042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(p);
11531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1154ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          if (CS) {
11550cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks            PathDiagnosticLocation BL =
11560cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation::createEndBrace(CS, SM);
115707c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek            EB.addEdge(BL);
1158dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          }
11598bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek        }
11601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1161ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        if (Term)
1162ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          EB.addContext(Term);
11631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1164dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        break;
11658bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek      }
116614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
11671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
11683c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek        if (const CFGStmt *S = BE->getFirstElement().getAs<CFGStmt>()) {
11693c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          const Stmt *stmt = S->getStmt();
11703c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          if (IsControlFlowExpr(stmt)) {
1171b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu            // Add the proper context for '&&', '||', and '?'.
11723c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            EB.addContext(stmt);
1173b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu          }
1174b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu          else
11753c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt());
1176dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        }
1177b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu
1178dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        break;
1179dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      }
11805de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
11815de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
1182dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    } while (0);
11831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1184dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    if (!NextNode)
118514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      continue;
11861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11878e6431adab313e283a992698f6fc7afe62420999Anna Zaks    // Add pieces from custom visitors.
11888e6431adab313e283a992698f6fc7afe62420999Anna Zaks    BugReport *R = PDB.getBugReport();
11893bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
11903bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                                  E = visitors.end();
11913bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose         I != E; ++I) {
11928e6431adab313e283a992698f6fc7afe62420999Anna Zaks      if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
11938966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        const PathDiagnosticLocation &Loc = p->getLocation();
11948966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        EB.addEdge(Loc, true);
11952042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.getActivePath().push_front(p);
1196368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        updateStackPiecesWithMessage(p, CallStack);
1197368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
11988966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        if (const Stmt *S = Loc.asStmt())
11991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
12008966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek      }
12011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
120214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
120314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
120414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
12055fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek//===----------------------------------------------------------------------===//
12063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugType and subclasses.
12073106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
1208404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios KyrtzidisBugType::~BugType() { }
1209404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
12103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekvoid BugType::FlushReports(BugReporter &BR) {}
12113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
121299ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid BuiltinBug::anchor() {}
121399ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
12143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
12153106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugReport and subclasses.
12163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
1217e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
121899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid BugReport::NodeResolver::anchor() {}
121999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
12208e6431adab313e283a992698f6fc7afe62420999Anna Zaksvoid BugReport::addVisitor(BugReporterVisitor* visitor) {
12218e6431adab313e283a992698f6fc7afe62420999Anna Zaks  if (!visitor)
12228e6431adab313e283a992698f6fc7afe62420999Anna Zaks    return;
12238e6431adab313e283a992698f6fc7afe62420999Anna Zaks
12248e6431adab313e283a992698f6fc7afe62420999Anna Zaks  llvm::FoldingSetNodeID ID;
12258e6431adab313e283a992698f6fc7afe62420999Anna Zaks  visitor->Profile(ID);
12268e6431adab313e283a992698f6fc7afe62420999Anna Zaks  void *InsertPos;
12278e6431adab313e283a992698f6fc7afe62420999Anna Zaks
12288e6431adab313e283a992698f6fc7afe62420999Anna Zaks  if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) {
12298e6431adab313e283a992698f6fc7afe62420999Anna Zaks    delete visitor;
12308e6431adab313e283a992698f6fc7afe62420999Anna Zaks    return;
12318e6431adab313e283a992698f6fc7afe62420999Anna Zaks  }
12328e6431adab313e283a992698f6fc7afe62420999Anna Zaks
12338e6431adab313e283a992698f6fc7afe62420999Anna Zaks  CallbacksSet.InsertNode(visitor, InsertPos);
12343bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  Callbacks.push_back(visitor);
12353bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  ++ConfigurationChangeToken;
12368e6431adab313e283a992698f6fc7afe62420999Anna Zaks}
12378e6431adab313e283a992698f6fc7afe62420999Anna Zaks
12388e6431adab313e283a992698f6fc7afe62420999Anna ZaksBugReport::~BugReport() {
12398e6431adab313e283a992698f6fc7afe62420999Anna Zaks  for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I) {
1240dc757b049796949e4b11646445a6598f0bdabd7aAnna Zaks    delete *I;
12418e6431adab313e283a992698f6fc7afe62420999Anna Zaks  }
12428e6431adab313e283a992698f6fc7afe62420999Anna Zaks}
1243e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
124407189521a15d9c088216b943649cb9fe231cbb57Ted Kremenekconst Decl *BugReport::getDeclWithIssue() const {
124507189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  if (DeclWithIssue)
124607189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek    return DeclWithIssue;
124707189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek
124807189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  const ExplodedNode *N = getErrorNode();
124907189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  if (!N)
125007189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek    return 0;
125107189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek
125207189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  const LocationContext *LC = N->getLocationContext();
125307189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  return LC->getCurrentStackFrame()->getDecl();
125407189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek}
125507189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek
1256e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaksvoid BugReport::Profile(llvm::FoldingSetNodeID& hash) const {
1257e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  hash.AddPointer(&BT);
1258e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  hash.AddString(Description);
1259ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks  if (UniqueingLocation.isValid()) {
1260ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks    UniqueingLocation.Profile(hash);
1261ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks  } else if (Location.isValid()) {
1262590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    Location.Profile(hash);
1263590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  } else {
1264590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    assert(ErrorNode);
1265590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    hash.AddPointer(GetCurrentOrPreviousStmt(ErrorNode));
1266590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  }
1267e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
1268e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  for (SmallVectorImpl<SourceRange>::const_iterator I =
1269e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      Ranges.begin(), E = Ranges.end(); I != E; ++I) {
1270e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    const SourceRange range = *I;
1271e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    if (!range.isValid())
1272e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      continue;
1273e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    hash.AddInteger(range.getBegin().getRawEncoding());
1274e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    hash.AddInteger(range.getEnd().getRawEncoding());
1275e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  }
1276e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks}
12773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
127876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekvoid BugReport::markInteresting(SymbolRef sym) {
127976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (!sym)
128076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return;
12813bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
12823bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // If the symbol wasn't already in our set, note a configuration change.
12833bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  if (interestingSymbols.insert(sym).second)
12843bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    ++ConfigurationChangeToken;
12858ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose
12868ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose  if (const SymbolMetadata *meta = dyn_cast<SymbolMetadata>(sym))
12878ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose    interestingRegions.insert(meta->getRegion());
128876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
128976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
129076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekvoid BugReport::markInteresting(const MemRegion *R) {
129176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (!R)
129276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return;
12933bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
12943bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // If the base region wasn't already in our set, note a configuration change.
129576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  R = R->getBaseRegion();
12963bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  if (interestingRegions.insert(R).second)
12973bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    ++ConfigurationChangeToken;
12988ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose
129976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
130076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    interestingSymbols.insert(SR->getSymbol());
130176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
130276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
130376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekvoid BugReport::markInteresting(SVal V) {
130476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  markInteresting(V.getAsRegion());
130576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  markInteresting(V.getAsSymbol());
130676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
130776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
130876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekbool BugReport::isInteresting(SVal V) const {
130976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  return isInteresting(V.getAsRegion()) || isInteresting(V.getAsSymbol());
131076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
131176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
131276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekbool BugReport::isInteresting(SymbolRef sym) const {
131376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (!sym)
131476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return false;
13158ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose  // We don't currently consider metadata symbols to be interesting
13168ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose  // even if we know their region is interesting. Is that correct behavior?
131776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  return interestingSymbols.count(sym);
131876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
131976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
132076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekbool BugReport::isInteresting(const MemRegion *R) const {
132176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (!R)
132276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return false;
132376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  R = R->getBaseRegion();
132476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  bool b = interestingRegions.count(R);
132576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (b)
132676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return true;
132776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
132876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return interestingSymbols.count(SR->getSymbol());
132976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  return false;
133076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
133176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
133276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
13339c378f705405d37f49795d5e915989de774fe11fTed Kremenekconst Stmt *BugReport::getStmt() const {
1334e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  if (!ErrorNode)
1335e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    return 0;
1336e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
1337212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care  ProgramPoint ProgP = ErrorNode->getLocation();
13385f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const Stmt *S = NULL;
13391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13409c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (BlockEntrance *BE = dyn_cast<BlockEntrance>(&ProgP)) {
1341fafd3834754d2093e0ad7a1c005860fd527ecb7fZhongxing Xu    CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit();
134250d5bc4e3b53eb8bb4ebf198f1213348a3fa0f38Zhongxing Xu    if (BE->getBlock() == &Exit)
1343212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care      S = GetPreviousStmt(ErrorNode);
13443106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
13455f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (!S)
13461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    S = GetStmt(ProgP);
13471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
13481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return S;
13493106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
13503106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1351640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidisstd::pair<BugReport::ranges_iterator, BugReport::ranges_iterator>
1352e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna ZaksBugReport::getRanges() {
1353e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    // If no custom ranges, add the range of the statement corresponding to
1354e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    // the error node.
1355e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    if (Ranges.empty()) {
1356e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      if (const Expr *E = dyn_cast_or_null<Expr>(getStmt()))
1357e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks        addRange(E->getSourceRange());
1358e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      else
1359e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks        return std::make_pair(ranges_iterator(), ranges_iterator());
1360e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    }
1361e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
136214924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks    // User-specified absence of range info.
136314924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks    if (Ranges.size() == 1 && !Ranges.begin()->isValid())
136414924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks      return std::make_pair(ranges_iterator(), ranges_iterator());
136514924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks
1366e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    return std::make_pair(Ranges.begin(), Ranges.end());
13673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
13683106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1369590dd8e0959d8df5621827768987c4792b74fc06Anna ZaksPathDiagnosticLocation BugReport::getLocation(const SourceManager &SM) const {
1370b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  if (ErrorNode) {
1371590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    assert(!Location.isValid() &&
1372b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks     "Either Location or ErrorNode should be specified but not both.");
1373b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks
13749c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (const Stmt *S = GetCurrentOrPreviousStmt(ErrorNode)) {
1375590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      const LocationContext *LC = ErrorNode->getLocationContext();
1376590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks
13773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // For member expressions, return the location of the '.' or '->'.
13785b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      if (const MemberExpr *ME = dyn_cast<MemberExpr>(S))
1379590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        return PathDiagnosticLocation::createMemberLoc(ME, SM);
13805b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      // For binary operators, return the location of the operator.
13815b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
1382590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        return PathDiagnosticLocation::createOperatorLoc(B, SM);
13833106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1384590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      return PathDiagnosticLocation::createBegin(S, SM, LC);
13853106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1386b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  } else {
1387b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks    assert(Location.isValid());
1388b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks    return Location;
1389b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  }
1390b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks
1391590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  return PathDiagnosticLocation();
13923106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
13933106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
13943106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
13953106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugReporter and subclasses.
13963106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
13973106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
13984a5f724538cbc275370c9504e8169ce92503256cBenjamin KramerBugReportEquivClass::~BugReportEquivClass() { }
1399a2f4ec0df645fc249d2945beef9653f03b175417Zhongxing XuGRBugReporter::~GRBugReporter() { }
14003106198188ac6eb2753f1764d5c28376b0b76351Ted KremenekBugReporterData::~BugReporterData() {}
14013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
140238b02b912e1a55c912f603c4369431264d36a381Zhongxing XuExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); }
14033106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
140418c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekProgramStateManager&
14053106198188ac6eb2753f1764d5c28376b0b76351Ted KremenekGRBugReporter::getStateManager() { return Eng.getStateManager(); }
14063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14073b030a28cda2b953758507769c1d436bec5ec45eAnna ZaksBugReporter::~BugReporter() {
14083b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  FlushReports();
14093b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks
14103b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  // Free the bug reports we are tracking.
14113b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  typedef std::vector<BugReportEquivClass *> ContTy;
14123b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  for (ContTy::iterator I = EQClassesVector.begin(), E = EQClassesVector.end();
14133b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks       I != E; ++I) {
14143b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks    delete *I;
14153b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  }
14163b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks}
14173106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14183106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekvoid BugReporter::FlushReports() {
14193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  if (BugTypes.isEmpty())
14203106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    return;
14213106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // First flush the warnings for each BugType.  This may end up creating new
1423404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // warnings and new BugTypes.
1424404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // FIXME: Only NSErrorChecker needs BugType's FlushReports.
1425404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // Turn NSErrorChecker into a proper checker and remove this.
14265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const BugType*, 16> bugTypes;
14273106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  for (BugTypesTy::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
1428404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    bugTypes.push_back(*I);
14295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVector<const BugType*, 16>::iterator
1430404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis         I = bugTypes.begin(), E = bugTypes.end(); I != E; ++I)
14313106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    const_cast<BugType*>(*I)->FlushReports(*this);
14323106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1433404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  typedef llvm::FoldingSet<BugReportEquivClass> SetTy;
1434404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  for (SetTy::iterator EI=EQClasses.begin(), EE=EQClasses.end(); EI!=EE;++EI){
1435404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    BugReportEquivClass& EQ = *EI;
1436404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    FlushReport(EQ);
14373106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
14383106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1439404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // BugReporter owns and deletes only BugTypes created implicitly through
1440404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // EmitBasicReport.
1441404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // FIXME: There are leaks from checkers that assume that the BugTypes they
1442404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // create will be destroyed by the BugReporter.
1443404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  for (llvm::StringMap<BugType*>::iterator
1444404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis         I = StrBugTypes.begin(), E = StrBugTypes.end(); I != E; ++I)
1445404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    delete I->second;
1446404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
14473106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Remove all references to the BugType objects.
14483baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek  BugTypes = F.getEmptySet();
14493106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
14503106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14513106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
14523106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// PathDiagnostics generation.
14533106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
14543106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
145538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xustatic std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
1456c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                 std::pair<ExplodedNode*, unsigned> >
145738b02b912e1a55c912f603c4369431264d36a381Zhongxing XuMakeReportGraph(const ExplodedGraph* G,
14585f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                SmallVectorImpl<const ExplodedNode*> &nodes) {
14591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create the trimmed graph.  It will contain the shortest paths from the
14611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // error nodes to the root.  In the new graph we should only have one
14623106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // error node unless there are two or more error nodes with the same minimum
14633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // path length.
146438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  ExplodedGraph* GTrim;
1465c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  InterExplodedGraphMap* NMap;
14663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  llvm::DenseMap<const void*, const void*> InverseMap;
146840406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  llvm::tie(GTrim, NMap) = G->Trim(nodes.data(), nodes.data() + nodes.size(),
146940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek                                   &InverseMap);
14701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14713106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create owning pointers for GTrim and NMap just to ensure that they are
14723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // released when this function exists.
14736f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ExplodedGraph> AutoReleaseGTrim(GTrim);
14746f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<InterExplodedGraphMap> AutoReleaseNMap(NMap);
14751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14763106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Find the (first) error node in the trimmed graph.  We just need to consult
14773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // the node map (NMap) which maps from nodes in the original graph to nodes
14783106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // in the new graph.
1479938332c657390d1e782e0adc03b092993edae962Ted Kremenek
1480c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  std::queue<const ExplodedNode*> WS;
148138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef llvm::DenseMap<const ExplodedNode*, unsigned> IndexMapTy;
1482938332c657390d1e782e0adc03b092993edae962Ted Kremenek  IndexMapTy IndexMap;
14833106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
148440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  for (unsigned nodeIndex = 0 ; nodeIndex < nodes.size(); ++nodeIndex) {
148540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    const ExplodedNode *originalNode = nodes[nodeIndex];
148640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (const ExplodedNode *N = NMap->getMappedNode(originalNode)) {
1487938332c657390d1e782e0adc03b092993edae962Ted Kremenek      WS.push(N);
148840406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      IndexMap[originalNode] = nodeIndex;
14893106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
149040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  }
14911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1492938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(!WS.empty() && "No error node found in the trimmed graph.");
14933106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
14943106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create a new (third!) graph with a single path.  This is the graph
14953106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // that will be returned to the caller.
1496c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu  ExplodedGraph *GNew = new ExplodedGraph();
14971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14983106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Sometimes the trimmed graph can contain a cycle.  Perform a reverse BFS
14993106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // to the root node, and then construct a new graph that contains only
15003106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // a single path.
15013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  llvm::DenseMap<const void*,unsigned> Visited;
15021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15033106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  unsigned cnt = 0;
15049c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *Root = 0;
15051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  while (!WS.empty()) {
15079c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const ExplodedNode *Node = WS.front();
15083106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    WS.pop();
15091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Visited.find(Node) != Visited.end())
15113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
15121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15133106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    Visited[Node] = cnt++;
15141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15153106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Node->pred_empty()) {
15163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      Root = Node;
15173106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
15183106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
15191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1520c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    for (ExplodedNode::const_pred_iterator I=Node->pred_begin(),
15213106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek         E=Node->pred_end(); I!=E; ++I)
15223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      WS.push(*I);
15233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
15241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1525938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(Root);
15261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15273106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Now walk from the root down the BFS path, always taking the successor
15283106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // with the lowest number.
15291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ExplodedNode *Last = 0, *First = 0;
15303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  NodeBackMap *BM = new NodeBackMap();
1531938332c657390d1e782e0adc03b092993edae962Ted Kremenek  unsigned NodeIndex = 0;
15321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1533c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  for ( const ExplodedNode *N = Root ;;) {
15343106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Lookup the number associated with the current node.
15353106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    llvm::DenseMap<const void*,unsigned>::iterator I = Visited.find(N);
1536938332c657390d1e782e0adc03b092993edae962Ted Kremenek    assert(I != Visited.end());
15371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15383106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Create the equivalent node in the new graph with the same state
15393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // and location.
15409c378f705405d37f49795d5e915989de774fe11fTed Kremenek    ExplodedNode *NewN = GNew->getNode(N->getLocation(), N->getState());
15411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Store the mapping to the original node.
15433106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    llvm::DenseMap<const void*, const void*>::iterator IMitr=InverseMap.find(N);
15443106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    assert(IMitr != InverseMap.end() && "No mapping to original node.");
1545c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    (*BM)[NewN] = (const ExplodedNode*) IMitr->second;
15461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15473106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Link up the new node with the previous node.
15483106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Last)
15495fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek      NewN->addPredecessor(Last, *GNew);
15501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15513106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    Last = NewN;
15521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15533106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Are we at the final node?
1554938332c657390d1e782e0adc03b092993edae962Ted Kremenek    IndexMapTy::iterator IMI =
1555c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu      IndexMap.find((const ExplodedNode*)(IMitr->second));
1556938332c657390d1e782e0adc03b092993edae962Ted Kremenek    if (IMI != IndexMap.end()) {
15573106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      First = NewN;
1558938332c657390d1e782e0adc03b092993edae962Ted Kremenek      NodeIndex = IMI->second;
15593106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
15603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
15611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15623106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Find the next successor node.  We choose the node that is marked
15633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // with the lowest DFS number.
1564c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::const_succ_iterator SI = N->succ_begin();
1565c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::const_succ_iterator SE = N->succ_end();
15663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    N = 0;
15671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15683106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    for (unsigned MinVal = 0; SI != SE; ++SI) {
15691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15703106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      I = Visited.find(*SI);
15711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (I == Visited.end())
15733106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        continue;
15741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15753106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (!N || I->second < MinVal) {
15763106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        N = *SI;
15773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MinVal = I->second;
15783106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
15793106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
15801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1581938332c657390d1e782e0adc03b092993edae962Ted Kremenek    assert(N);
15823106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
15831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1584938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(First);
1585938332c657390d1e782e0adc03b092993edae962Ted Kremenek
15863106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  return std::make_pair(std::make_pair(GNew, BM),
15873106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                        std::make_pair(First, NodeIndex));
15883106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
1589d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
15903106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
15913106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek///  and collapses PathDiagosticPieces that are expanded by macros.
159277d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenekstatic void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
15932042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek  typedef std::vector<std::pair<IntrusiveRefCntPtr<PathDiagnosticMacroPiece>,
15942042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek                                SourceLocation> > MacroStackTy;
15951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1596c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  typedef std::vector<IntrusiveRefCntPtr<PathDiagnosticPiece> >
15973106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          PiecesTy;
15981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
15993106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  MacroStackTy MacroStack;
16003106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  PiecesTy Pieces;
16011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
160277d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  for (PathPieces::const_iterator I = path.begin(), E = path.end();
16032042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek       I!=E; ++I) {
160477d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
160577d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    PathDiagnosticPiece *piece = I->getPtr();
160677d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
160777d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    // Recursively compact calls.
160877d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
160977d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      CompactPathDiagnostic(call->path, SM);
161077d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    }
161177d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
16123106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Get the location of the PathDiagnosticPiece.
161377d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    const FullSourceLoc Loc = piece->getLocation().asLocation();
16141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16153106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Determine the instantiation location, which is the location we group
16163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // related PathDiagnosticPieces.
16171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SourceLocation InstantiationLoc = Loc.isMacroID() ?
1618402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth                                      SM.getExpansionLoc(Loc) :
16193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                      SourceLocation();
16201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16213106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Loc.isFileID()) {
16223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.clear();
162377d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      Pieces.push_back(piece);
16243106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
16253106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1626706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek
16273106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    assert(Loc.isMacroID());
16281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16293106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Is the PathDiagnosticPiece within the same macro group?
16303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
163177d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      MacroStack.back().first->subPieces.push_back(piece);
16323106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
16333106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1634d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
16353106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // We aren't in the same group.  Are we descending into a new macro
16363106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // or are part of an old one?
1637c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith    IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
1638d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
16393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
1640402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth                                          SM.getExpansionLoc(Loc) :
16413106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                          SourceLocation();
16421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16433106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Walk the entire macro stack.
16443106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    while (!MacroStack.empty()) {
16453106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (InstantiationLoc == MacroStack.back().second) {
16463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MacroGroup = MacroStack.back().first;
16473106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        break;
16483106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
16491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16503106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (ParentInstantiationLoc == MacroStack.back().second) {
16513106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MacroGroup = MacroStack.back().first;
16523106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        break;
165361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek      }
16541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.pop_back();
16566837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek    }
16571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16583106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) {
16593106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // Create a new macro group and add it to the stack.
1660590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      PathDiagnosticMacroPiece *NewGroup =
1661590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        new PathDiagnosticMacroPiece(
166277d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek          PathDiagnosticLocation::createSingleLocation(piece->getLocation()));
16635a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek
16643106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (MacroGroup)
1665802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek        MacroGroup->subPieces.push_back(NewGroup);
16663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      else {
16673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        assert(InstantiationLoc.isFileID());
16683106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        Pieces.push_back(NewGroup);
16693106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
16701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16713106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroGroup = NewGroup;
16723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.push_back(std::make_pair(MacroGroup, InstantiationLoc));
16737dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    }
16743106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
16753106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Finally, add the PathDiagnosticPiece to the group.
167677d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    MacroGroup->subPieces.push_back(piece);
16773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
16781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16793106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Now take the pieces and construct a new PathDiagnostic.
168077d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  path.clear();
16811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
168277d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I)
168377d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    path.push_back(*I);
168461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
168561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
16863106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekvoid GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
16875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                        SmallVectorImpl<BugReport *> &bugReports) {
16881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
168940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  assert(!bugReports.empty());
16905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const ExplodedNode *, 10> errorNodes;
16915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVectorImpl<BugReport*>::iterator I = bugReports.begin(),
169240406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    E = bugReports.end(); I != E; ++I) {
169340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      errorNodes.push_back((*I)->getErrorNode());
169440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  }
16951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16963106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Construct a new graph that contains only a single path from the error
16971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // node to a root.
169838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
1699c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  std::pair<ExplodedNode*, unsigned> >&
170040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    GPair = MakeReportGraph(&getGraph(), errorNodes);
17011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17023106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Find the BugReport with the original location.
170340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  assert(GPair.second.second < bugReports.size());
170440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *R = bugReports[GPair.second.second];
17053106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  assert(R && "No original report found for sliced graph.");
17061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17076f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ExplodedGraph> ReportGraph(GPair.first.first);
17086f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<NodeBackMap> BackMap(GPair.first.second);
1709c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  const ExplodedNode *N = GPair.second.first;
17101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Start building the path diagnostic...
1712ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticBuilder PDB(*this, R, BackMap.get(),
1713ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie                            getPathDiagnosticConsumer());
17141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17158e6431adab313e283a992698f6fc7afe62420999Anna Zaks  // Register additional node visitors.
171650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  R->addVisitor(new NilReceiverBRVisitor());
171750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  R->addVisitor(new ConditionBRVisitor());
17181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17193bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  BugReport::VisitorList visitors;
17203bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  unsigned originalReportConfigToken, finalReportConfigToken;
17213bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
17223bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // While generating diagnostics, it's possible the visitors will decide
17233bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // new symbols and regions are interesting, or add other visitors based on
17243bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // the information they find. If they do, we need to regenerate the path
17253bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // based on our new report configuration.
17263bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  do {
17273bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Get a clean copy of all the visitors.
17283bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    for (BugReport::visitor_iterator I = R->visitor_begin(),
17293bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                     E = R->visitor_end(); I != E; ++I)
17303bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose       visitors.push_back((*I)->clone());
17313bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
17323bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Clear out the active path from any previous work.
17333bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    PD.getActivePath().clear();
17343bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    originalReportConfigToken = R->getConfigurationChangeToken();
17353bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
17363bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Generate the very last diagnostic piece - the piece is visible before
17373bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // the trace is expanded.
17383bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    PathDiagnosticPiece *LastPiece = 0;
17393bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
17403bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose         I != E; ++I) {
17413bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
17423bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose        assert (!LastPiece &&
17433bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                "There can only be one final piece in a diagnostic.");
17443bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose        LastPiece = Piece;
17453bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      }
174623f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks    }
17473bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    if (!LastPiece)
17483bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
17493bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    if (LastPiece)
17503bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      PD.getActivePath().push_back(LastPiece);
17513bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    else
17523bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      return;
175323f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
17543bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    switch (PDB.getGenerationScheme()) {
1755ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    case PathDiagnosticConsumer::Extensive:
17563bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      GenerateExtensivePathDiagnostic(PD, PDB, N, visitors);
17575fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      break;
1758ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    case PathDiagnosticConsumer::Minimal:
17593bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      GenerateMinimalPathDiagnostic(PD, PDB, N, visitors);
17603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
17613bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    }
17623bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
17633bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Clean up the visitors we used.
17643bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    llvm::DeleteContainerPointers(visitors);
17653bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
17663bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Did anything change while generating this path?
17673bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    finalReportConfigToken = R->getConfigurationChangeToken();
17683bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  } while(finalReportConfigToken != originalReportConfigToken);
17693bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
1770c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  // Finally, prune the diagnostic path of uninteresting stuff.
1771c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces());
1772c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  assert(hasSomethingInteresting);
1773c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  (void) hasSomethingInteresting;
17743106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
17751aa44c7c9198796085b77c6bdd7c90030845a688Ted Kremenek
1776cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekvoid BugReporter::Register(BugType *BT) {
17773baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek  BugTypes = F.add(BugTypes, BT);
177876d90c8bf83d071fd1bdbffa6d9f2af87c6bb7b5Ted Kremenek}
177976d90c8bf83d071fd1bdbffa6d9f2af87c6bb7b5Ted Kremenek
17801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid BugReporter::EmitReport(BugReport* R) {
1781cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // Compute the bug report's hash to determine its equivalence class.
1782cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  llvm::FoldingSetNodeID ID;
1783cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  R->Profile(ID);
17841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Lookup the equivance class.  If there isn't one, create it.
1786cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugType& BT = R->getBugType();
1787cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  Register(&BT);
1788cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void *InsertPos;
1789404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos);
17901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1791cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  if (!EQ) {
1792cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    EQ = new BugReportEquivClass(R);
1793404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    EQClasses.InsertNode(EQ, InsertPos);
17943b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks    EQClassesVector.push_back(EQ);
1795cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  }
1796cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  else
1797cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    EQ->AddReport(R);
179861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
179961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
180006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
180106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek//===----------------------------------------------------------------------===//
180206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek// Emitting reports in equivalence classes.
180306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek//===----------------------------------------------------------------------===//
180406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
180506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremeneknamespace {
1806ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamstruct FRIEC_WLItem {
180706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  const ExplodedNode *N;
180806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  ExplodedNode::const_succ_iterator I, E;
180906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
181006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  FRIEC_WLItem(const ExplodedNode *n)
181106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  : N(n), I(N->succ_begin()), E(N->succ_end()) {}
181206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek};
181306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek}
181406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
181561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenekstatic BugReport *
181661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted KremenekFindReportInEquivalenceClass(BugReportEquivClass& EQ,
18175f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                             SmallVectorImpl<BugReport*> &bugReports) {
181861f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
181906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
182006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  assert(I != E);
18214a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer  BugType& BT = I->getBugType();
182261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
182340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // If we don't need to suppress any of the nodes because they are
182440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // post-dominated by a sink, simply add all the nodes in the equivalence class
182540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // to 'Nodes'.  Any of the reports will serve as a "representative" report.
182661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  if (!BT.isSuppressOnSink()) {
18274a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer    BugReport *R = I;
182861f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) {
18299c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const ExplodedNode *N = I->getErrorNode();
183061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      if (N) {
18314a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer        R = I;
183240406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek        bugReports.push_back(R);
183361f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      }
183461f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    }
183506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    return R;
183661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  }
183761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
183806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // For bug reports that should be suppressed when all paths are post-dominated
183906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // by a sink node, iterate through the reports in the equivalence class
184006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // until we find one that isn't post-dominated (if one exists).  We use a
184106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // DFS traversal of the ExplodedGraph to find a non-sink node.  We could write
184206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // this as a recursive function, but we don't want to risk blowing out the
184306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // stack for very long paths.
184440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *exampleReport = 0;
184561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
184606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  for (; I != E; ++I) {
18474a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer    const ExplodedNode *errorNode = I->getErrorNode();
184806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
184940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (!errorNode)
185006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      continue;
185140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (errorNode->isSink()) {
1852b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable(
185306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek           "BugType::isSuppressSink() should not be 'true' for sink end nodes");
185406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    }
185561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    // No successors?  By definition this nodes isn't post-dominated by a sink.
185640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (errorNode->succ_empty()) {
18574a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer      bugReports.push_back(I);
185840406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      if (!exampleReport)
18594a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer        exampleReport = I;
186061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      continue;
186161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    }
186261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
186306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    // At this point we know that 'N' is not a sink and it has at least one
186406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    // successor.  Use a DFS worklist to find a non-sink end-of-path node.
186506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    typedef FRIEC_WLItem WLItem;
18665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    typedef SmallVector<WLItem, 10> DFSWorkList;
186706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    llvm::DenseMap<const ExplodedNode *, unsigned> Visited;
186806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
186906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    DFSWorkList WL;
187040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    WL.push_back(errorNode);
187140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    Visited[errorNode] = 1;
187206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
187306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    while (!WL.empty()) {
187406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      WLItem &WI = WL.back();
187506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      assert(!WI.N->succ_empty());
187606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
187706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      for (; WI.I != WI.E; ++WI.I) {
187806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        const ExplodedNode *Succ = *WI.I;
187906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // End-of-path node?
188006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        if (Succ->succ_empty()) {
188161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          // If we found an end-of-path node that is not a sink.
188261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          if (!Succ->isSink()) {
18834a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer            bugReports.push_back(I);
188440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek            if (!exampleReport)
18854a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer              exampleReport = I;
188661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek            WL.clear();
188761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek            break;
188861f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          }
188906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          // Found a sink?  Continue on to the next successor.
189006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          continue;
189106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        }
189206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // Mark the successor as visited.  If it hasn't been explored,
189306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // enqueue it to the DFS worklist.
189406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        unsigned &mark = Visited[Succ];
189506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        if (!mark) {
189606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          mark = 1;
189706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          WL.push_back(Succ);
189806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          break;
189906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        }
190006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      }
190161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
190261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      // The worklist may have been cleared at this point.  First
190361f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      // check if it is empty before checking the last item.
190461f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      if (!WL.empty() && &WL.back() == &WI)
190506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        WL.pop_back();
190606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    }
190706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  }
190806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
190961f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  // ExampleReport will be NULL if all the nodes in the equivalence class
191061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  // were post-dominated by sinks.
191140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  return exampleReport;
191261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek}
1913e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1914e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek//===----------------------------------------------------------------------===//
1915e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek// DiagnosticCache.  This is a hack to cache analyzer diagnostics.  It
1916e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek// uses global state, which eventually should go elsewhere.
1917e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek//===----------------------------------------------------------------------===//
1918e0a58073b76fc016325a35152533b8468df2bf4aTed Kremeneknamespace {
1919ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass DiagCacheItem : public llvm::FoldingSetNode {
1920e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  llvm::FoldingSetNodeID ID;
1921e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenekpublic:
1922e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  DiagCacheItem(BugReport *R, PathDiagnostic *PD) {
19234522e2a9e7fa0313e8e5a388d8f0ab66feccc6afAnna Zaks    R->Profile(ID);
19244522e2a9e7fa0313e8e5a388d8f0ab66feccc6afAnna Zaks    PD->Profile(ID);
1925e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  }
1926e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1927e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  void Profile(llvm::FoldingSetNodeID &id) {
1928e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek    id = ID;
1929e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  }
1930e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1931e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  llvm::FoldingSetNodeID &getID() { return ID; }
1932e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek};
1933e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek}
1934e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1935e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenekstatic bool IsCachedDiagnostic(BugReport *R, PathDiagnostic *PD) {
1936e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  // FIXME: Eventually this diagnostic cache should reside in something
1937e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  // like AnalysisManager instead of being a static variable.  This is
1938e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  // really unsafe in the long term.
1939e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  typedef llvm::FoldingSet<DiagCacheItem> DiagnosticCache;
1940e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  static DiagnosticCache DC;
1941e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1942e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  void *InsertPos;
1943e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  DiagCacheItem *Item = new DiagCacheItem(R, PD);
1944e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1945e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  if (DC.FindNodeOrInsertPos(Item->getID(), InsertPos)) {
1946e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek    delete Item;
1947e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek    return true;
1948e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  }
1949e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1950e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  DC.InsertNode(Item, InsertPos);
1951e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek  return false;
1952e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek}
1953e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1954cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekvoid BugReporter::FlushReport(BugReportEquivClass& EQ) {
19555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<BugReport*, 10> bugReports;
195640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *exampleReport = FindReportInEquivalenceClass(EQ, bugReports);
195740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  if (!exampleReport)
195806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    return;
195906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
1960ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer* PD = getPathDiagnosticConsumer();
19611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1962cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Make sure we use the 'R' for the path that was actually used.
19631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Probably doesn't make a difference in practice.
196440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugType& BT = exampleReport->getBugType();
19651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19666f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<PathDiagnostic>
196707189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek    D(new PathDiagnostic(exampleReport->getDeclWithIssue(),
196807189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek                         exampleReport->getBugType().getName(),
1969da0e8429a3598acfdd0ecf15135d432e4dd3517cTed Kremenek                         !PD || PD->useVerboseDescription()
197040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek                         ? exampleReport->getDescription()
197140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek                         : exampleReport->getShortDescription(),
1972d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek                         BT.getCategory()));
1973d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
197440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  if (!bugReports.empty())
197540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    GeneratePathDiagnostic(*D.get(), bugReports);
1976e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
1977072192bcbb05a0fee7ec3061750b27e8d2004952Ted Kremenek  // Get the meta data.
19787f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks  const BugReport::ExtraTextList &Meta =
19797f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks                                  exampleReport->getExtraText();
19807f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks  for (BugReport::ExtraTextList::const_iterator i = Meta.begin(),
19817f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks                                                e = Meta.end(); i != e; ++i) {
19827f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks    D->addMeta(*i);
19837f2531cb41448852ec78de90fc1d3c0149c95d7dAnna Zaks  }
198475840e1501563fe7c3dcb5600b75965ba1fe1bc4Ted Kremenek
19853148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  // Emit a summary diagnostic to the regular Diagnostics engine.
1986640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis  BugReport::ranges_iterator Beg, End;
1987640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis  llvm::tie(Beg, End) = exampleReport->getRanges();
1988d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  DiagnosticsEngine &Diag = getDiagnostic();
1989c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek
199088fc18120ca14b82bef695d6440f51e4c468916cTed Kremenek  if (!IsCachedDiagnostic(exampleReport, D.get())) {
199188fc18120ca14b82bef695d6440f51e4c468916cTed Kremenek    // Search the description for '%', as that will be interpretted as a
199288fc18120ca14b82bef695d6440f51e4c468916cTed Kremenek    // format character by FormatDiagnostics.
199388fc18120ca14b82bef695d6440f51e4c468916cTed Kremenek    StringRef desc = exampleReport->getShortDescription();
199488fc18120ca14b82bef695d6440f51e4c468916cTed Kremenek
1995f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith    SmallString<512> TmpStr;
1996c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek    llvm::raw_svector_ostream Out(TmpStr);
199788fc18120ca14b82bef695d6440f51e4c468916cTed Kremenek    for (StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I) {
1998c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek      if (*I == '%')
1999c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek        Out << "%%";
2000c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek      else
2001c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek        Out << *I;
200288fc18120ca14b82bef695d6440f51e4c468916cTed Kremenek    }
2003c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek
2004c213b48206c55ca0eb1387cfa1651de504f147d1Ted Kremenek    Out.flush();
200588fc18120ca14b82bef695d6440f51e4c468916cTed Kremenek    unsigned ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning, TmpStr);
20060a14eee528a901c16f0e288fbc10a3abc1660d87Chris Lattner
2007590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    DiagnosticBuilder diagBuilder = Diag.Report(
2008590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      exampleReport->getLocation(getSourceManager()).asLocation(), ErrorDiag);
2009640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidis    for (BugReport::ranges_iterator I = Beg; I != End; ++I)
2010b6b7e7bff3101062521de6e79533a3c25e2195d9Argyrios Kyrtzidis      diagBuilder << *I;
20112f0e89ea96292d2974eb1a7dddc0e9870aa86bb7Ted Kremenek  }
20123148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek
2013ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  // Emit a full diagnostic for the path if we have a PathDiagnosticConsumer.
20143148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  if (!PD)
20153148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek    return;
20161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2017802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek  if (D->path.empty()) {
2018590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    PathDiagnosticPiece *piece = new PathDiagnosticEventPiece(
2019590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                 exampleReport->getLocation(getSourceManager()),
2020590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                 exampleReport->getDescription());
202107189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek    for ( ; Beg != End; ++Beg)
202207189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek      piece->addRange(*Beg);
20231fbfd5b9b8b82aea084773b76dd1ec6796a7000cTed Kremenek
20242042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek    D->getActivePath().push_back(piece);
20253148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  }
20261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20273148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  PD->HandlePathDiagnostic(D.take());
202861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
202957202071e477530e9348bc76671ee369b2399b92Ted Kremenek
203007189521a15d9c088216b943649cb9fe231cbb57Ted Kremenekvoid BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
203107189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek                                  StringRef name,
20325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  StringRef category,
2033590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                  StringRef str, PathDiagnosticLocation Loc,
20348c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek                                  SourceRange* RBeg, unsigned NumRanges) {
20351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2036404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // 'BT' is owned by BugReporter.
2037404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugType *BT = getBugTypeForName(name, category);
2038590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  BugReport *R = new BugReport(*BT, str, Loc);
203907189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  R->setDeclWithIssue(DeclWithIssue);
2040cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  for ( ; NumRanges > 0 ; --NumRanges, ++RBeg) R->addRange(*RBeg);
2041cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  EmitReport(R);
2042cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek}
2043404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
20445f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerBugType *BugReporter::getBugTypeForName(StringRef name,
20455f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                        StringRef category) {
2046f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<136> fullDesc;
2047404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  llvm::raw_svector_ostream(fullDesc) << name << ":" << category;
2048404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  llvm::StringMapEntry<BugType *> &
2049404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis      entry = StrBugTypes.GetOrCreateValue(fullDesc);
2050404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugType *BT = entry.getValue();
2051404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  if (!BT) {
2052404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    BT = new BugType(name, category);
2053404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    entry.setValue(BT);
2054404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  }
2055404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  return BT;
2056404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis}
2057