BugReporter.cpp revision 368f3b070e8cb657a65bfa443d60256676d269e7
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();
51852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose  else if (const CallEnter *CE = dyn_cast<CallEnter>(&P))
52852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose    return CE->getCallExpr();
53852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose  else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&P))
54852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose    return CEE->getCalleeContext()->getCallSite();
551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return 0;
5761f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
5861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
59c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic inline const ExplodedNode*
609c378f705405d37f49795d5e915989de774fe11fTed KremenekGetPredecessorNode(const ExplodedNode *N) {
61b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return N->pred_empty() ? NULL : *(N->pred_begin());
62706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek}
63706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek
64c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic inline const ExplodedNode*
659c378f705405d37f49795d5e915989de774fe11fTed KremenekGetSuccessorNode(const ExplodedNode *N) {
66b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return N->succ_empty() ? NULL : *(N->succ_begin());
67bd7efa8ca27ed9676acf00abf31d5e1cd54651ccTed Kremenek}
682673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek
699c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic const Stmt *GetPreviousStmt(const ExplodedNode *N) {
70b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  for (N = GetPredecessorNode(N); N; N = GetPredecessorNode(N))
715f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    if (const Stmt *S = GetStmt(N->getLocation()))
72b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek      return S;
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
74b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return 0;
75b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek}
76b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek
779c378f705405d37f49795d5e915989de774fe11fTed Kremenekstatic const Stmt *GetNextStmt(const ExplodedNode *N) {
78b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  for (N = GetSuccessorNode(N); N; N = GetSuccessorNode(N))
795f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek    if (const Stmt *S = GetStmt(N->getLocation())) {
80f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek      // Check if the statement is '?' or '&&'/'||'.  These are "merges",
81f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek      // not actual statement points.
82f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek      switch (S->getStmtClass()) {
83f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        case Stmt::ChooseExprClass:
8456ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        case Stmt::BinaryConditionalOperatorClass: continue;
85f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        case Stmt::ConditionalOperatorClass: continue;
86f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        case Stmt::BinaryOperatorClass: {
872de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall          BinaryOperatorKind Op = cast<BinaryOperator>(S)->getOpcode();
882de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall          if (Op == BO_LAnd || Op == BO_LOr)
89f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            continue;
90f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek          break;
91f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        }
92f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek        default:
93f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek          break;
94f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek      }
95b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek      return S;
96f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek    }
971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return 0;
99bd7efa8ca27ed9676acf00abf31d5e1cd54651ccTed Kremenek}
100bd7efa8ca27ed9676acf00abf31d5e1cd54651ccTed Kremenek
1015f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekstatic inline const Stmt*
1029c378f705405d37f49795d5e915989de774fe11fTed KremenekGetCurrentOrPreviousStmt(const ExplodedNode *N) {
1035f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (const Stmt *S = GetStmt(N->getLocation()))
104b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    return S;
1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
106b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return GetPreviousStmt(N);
107b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek}
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1095f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenekstatic inline const Stmt*
1109c378f705405d37f49795d5e915989de774fe11fTed KremenekGetCurrentOrNextStmt(const ExplodedNode *N) {
1115f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (const Stmt *S = GetStmt(N->getLocation()))
112b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    return S;
1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
114b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  return GetNextStmt(N);
1153148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek}
1163148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek
117b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek//===----------------------------------------------------------------------===//
118c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek// Diagnostic cleanup.
119c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek//===----------------------------------------------------------------------===//
120c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
121b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenekstatic PathDiagnosticEventPiece *
122b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted KremenekeventsDescribeSameCondition(PathDiagnosticEventPiece *X,
123b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek                            PathDiagnosticEventPiece *Y) {
124b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  // Prefer diagnostics that come from ConditionBRVisitor over
125b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  // those that came from TrackConstraintBRVisitor.
126b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  const void *tagPreferred = ConditionBRVisitor::getTag();
127b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  const void *tagLesser = TrackConstraintBRVisitor::getTag();
128b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
129b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  if (X->getLocation() != Y->getLocation())
130b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    return 0;
131b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
132b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  if (X->getTag() == tagPreferred && Y->getTag() == tagLesser)
133b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    return X;
134b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
135b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  if (Y->getTag() == tagPreferred && X->getTag() == tagLesser)
136b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    return Y;
137b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
138b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  return 0;
139b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek}
140b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
1413800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek/// An optimization pass over PathPieces that removes redundant diagnostics
1423800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek/// generated by both ConditionBRVisitor and TrackConstraintBRVisitor.  Both
1433800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek/// BugReporterVisitors use different methods to generate diagnostics, with
1443800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek/// one capable of emitting diagnostics in some cases but not in others.  This
1453800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek/// can lead to redundant diagnostic pieces at the same point in a path.
1463800165e56107df7430520aa98afdf7065db2dd2Ted Kremenekstatic void removeRedundantMsgs(PathPieces &path) {
147b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  unsigned N = path.size();
148b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  if (N < 2)
149b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    return;
1503800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek  // NOTE: this loop intentionally is not using an iterator.  Instead, we
1513800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek  // are streaming the path and modifying it in place.  This is done by
1523800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek  // grabbing the front, processing it, and if we decide to keep it append
1533800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek  // it to the end of the path.  The entire path is processed in this way.
154b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  for (unsigned i = 0; i < N; ++i) {
155b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    IntrusiveRefCntPtr<PathDiagnosticPiece> piece(path.front());
156b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    path.pop_front();
157b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
158b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    switch (piece->getKind()) {
159b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      case clang::ento::PathDiagnosticPiece::Call:
1603800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek        removeRedundantMsgs(cast<PathDiagnosticCallPiece>(piece)->path);
161b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek        break;
162b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      case clang::ento::PathDiagnosticPiece::Macro:
1633800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek        removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(piece)->subPieces);
164b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek        break;
165b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      case clang::ento::PathDiagnosticPiece::ControlFlow:
166b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek        break;
167b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      case clang::ento::PathDiagnosticPiece::Event: {
168b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek        if (i == N-1)
169b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek          break;
170b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
171b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek        if (PathDiagnosticEventPiece *nextEvent =
172b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek            dyn_cast<PathDiagnosticEventPiece>(path.front().getPtr())) {
173b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek          PathDiagnosticEventPiece *event =
174b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek            cast<PathDiagnosticEventPiece>(piece);
175b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek          // Check to see if we should keep one of the two pieces.  If we
176b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek          // come up with a preference, record which piece to keep, and consume
177b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek          // another piece from the path.
178b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek          if (PathDiagnosticEventPiece *pieceToKeep =
179b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek              eventsDescribeSameCondition(event, nextEvent)) {
180b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek            piece = pieceToKeep;
181b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek            path.pop_front();
182b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek            ++i;
183b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek          }
184b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek        }
185b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek        break;
186b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      }
187b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    }
188b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    path.push_back(piece);
189b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  }
190b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek}
191b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
192c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek/// Recursively scan through a path and prune out calls and macros pieces
193c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek/// that aren't needed.  Return true if afterwards the path contains
194c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek/// "interesting stuff" which means it should be pruned from the parent path.
195a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenekbool BugReporter::RemoveUneededCalls(PathPieces &pieces, BugReport *R,
196368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose                                     PathDiagnosticLocation *LastCallLocation) {
197c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  bool containsSomethingInteresting = false;
198c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  const unsigned N = pieces.size();
199c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
200c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  for (unsigned i = 0 ; i < N ; ++i) {
201c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    // Remove the front piece from the path.  If it is still something we
202c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    // want to keep once we are done, we will push it back on the end.
203c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    IntrusiveRefCntPtr<PathDiagnosticPiece> piece(pieces.front());
204c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    pieces.pop_front();
205c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
206a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek    // Throw away pieces with invalid locations.
207a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek    if (piece->getKind() != PathDiagnosticPiece::Call &&
208a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek        piece->getLocation().asLocation().isInvalid())
209a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek      continue;
210a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
211725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek    switch (piece->getKind()) {
212725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::Call: {
213725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        PathDiagnosticCallPiece *call = cast<PathDiagnosticCallPiece>(piece);
21480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // Check if the location context is interesting.
21580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        assert(LocationContextMap.count(call));
21680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        if (R->isInteresting(LocationContextMap[call])) {
21780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          containsSomethingInteresting = true;
21880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          break;
21980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        }
220368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose
221368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose        if (LastCallLocation) {
222368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose          if (!call->callEnter.asLocation().isValid())
223368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose            call->callEnter = *LastCallLocation;
224368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose          if (!call->callReturn.asLocation().isValid())
225368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose            call->callReturn = *LastCallLocation;
226368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose        }
227368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose
228725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        // Recursively clean out the subclass.  Keep this call around if
229725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        // it contains any informative diagnostics.
230368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose        if (call->callEnterWithin.asLocation().isValid())
231368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose          LastCallLocation = &call->callEnterWithin;
232368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose        else
233368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose          LastCallLocation = &call->callEnter;
234a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
235368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose        assert(LastCallLocation && "Outermost call has an invalid location");
236368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose        if (!RemoveUneededCalls(call->path, R, LastCallLocation))
237368f3b070e8cb657a65bfa443d60256676d269e7Jordan Rose          continue;
238a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
239725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        containsSomethingInteresting = true;
240725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
241725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      }
242725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::Macro: {
243725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        PathDiagnosticMacroPiece *macro = cast<PathDiagnosticMacroPiece>(piece);
24480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        if (!RemoveUneededCalls(macro->subPieces, R))
245725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek          continue;
246c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek        containsSomethingInteresting = true;
247725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
248725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      }
249725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::Event: {
250725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        PathDiagnosticEventPiece *event = cast<PathDiagnosticEventPiece>(piece);
251a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
252725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        // We never throw away an event, but we do throw it away wholesale
253725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        // as part of a path if we throw the entire path away.
25422505ef15e32db31a4f834a387cf73a913bc8f66Ted Kremenek        containsSomethingInteresting |= !event->isPrunable();
255725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
256725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      }
257725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek      case PathDiagnosticPiece::ControlFlow:
258725167443808efdc39a99f4eb132a0ae64ac5118Ted Kremenek        break;
259c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    }
260c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
261c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek    pieces.push_back(piece);
262c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  }
263c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
264c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  return containsSomethingInteresting;
265c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek}
266c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
267c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek//===----------------------------------------------------------------------===//
2683106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// PathDiagnosticBuilder and its associated routines and helper objects.
269b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek//===----------------------------------------------------------------------===//
270b479dadea93b93d3f0a335c3518b703f140b3f50Ted Kremenek
271c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xutypedef llvm::DenseMap<const ExplodedNode*,
272c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xuconst ExplodedNode*> NodeBackMap;
2737dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek
274babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremeneknamespace {
275ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass NodeMapClosure : public BugReport::NodeResolver {
2767dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeBackMap& M;
2777dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenekpublic:
2787dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeMapClosure(NodeBackMap *m) : M(*m) {}
2797dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  ~NodeMapClosure() {}
2801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2819c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *getOriginalNode(const ExplodedNode *N) {
2827dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    NodeBackMap::iterator I = M.find(N);
2837dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    return I == M.end() ? 0 : I->second;
2847dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  }
2857dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek};
2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
287ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass PathDiagnosticBuilder : public BugReporterContext {
2887dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  BugReport *R;
289ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer *PDC;
2906f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ParentMap> PM;
2917dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  NodeMapClosure NMC;
2921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic:
29359950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  const LocationContext *LC;
29459950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek
2958966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  PathDiagnosticBuilder(GRBugReporter &br,
2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                        BugReport *r, NodeBackMap *Backmap,
297ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie                        PathDiagnosticConsumer *pdc)
2988966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    : BugReporterContext(br),
29959950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek      R(r), PDC(pdc), NMC(Backmap), LC(r->getErrorNode()->getLocationContext())
30059950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  {}
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3029c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PathDiagnosticLocation ExecutionContinues(const ExplodedNode *N);
3031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3049c378f705405d37f49795d5e915989de774fe11fTed Kremenek  PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream &os,
3059c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                            const ExplodedNode *N);
3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3078e6431adab313e283a992698f6fc7afe62420999Anna Zaks  BugReport *getBugReport() { return R; }
3088e6431adab313e283a992698f6fc7afe62420999Anna Zaks
309212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care  Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); }
31059950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek
31159950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  ParentMap& getParentMap() { return LC->getParentMap(); }
3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
313c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek  const Stmt *getParent(const Stmt *S) {
314c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek    return getParentMap().getParent(S);
315c3f83ad7adaff2623986aa1c3e57833babd03d50Ted Kremenek  }
3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3178966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  virtual NodeMapClosure& getNodeResolver() { return NMC; }
3187297134f128423fce2e88f92421ed135bded7d4eDouglas Gregor
319d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S);
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
321ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie  PathDiagnosticConsumer::PathGenerationScheme getGenerationScheme() const {
322ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    return PDC ? PDC->getGenerationScheme() : PathDiagnosticConsumer::Extensive;
3237dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek  }
3247dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek
325babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek  bool supportsLogicalOpControlFlow() const {
326babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek    return PDC ? PDC->supportsLogicalOpControlFlow() : true;
3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
328babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek};
329babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek} // end anonymous namespace
330babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek
33100605e0f011ed99225a22026344c5fc1b3212cd7Ted KremenekPathDiagnosticLocation
3329c378f705405d37f49795d5e915989de774fe11fTed KremenekPathDiagnosticBuilder::ExecutionContinues(const ExplodedNode *N) {
3335f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (const Stmt *S = GetNextStmt(N))
33459950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek    return PathDiagnosticLocation(S, getSourceManager(), LC);
33500605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek
3360cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks  return PathDiagnosticLocation::createDeclEnd(N->getLocationContext(),
3370cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                                               getSourceManager());
338082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek}
3391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34000605e0f011ed99225a22026344c5fc1b3212cd7Ted KremenekPathDiagnosticLocation
3419c378f705405d37f49795d5e915989de774fe11fTed KremenekPathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream &os,
3429c378f705405d37f49795d5e915989de774fe11fTed Kremenek                                          const ExplodedNode *N) {
343babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek
344143ca222583a4a355fdc89af852deef287499300Ted Kremenek  // Slow, but probably doesn't matter.
345b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek  if (os.str().empty())
346b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    os << ' ';
3471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34800605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek  const PathDiagnosticLocation &Loc = ExecutionContinues(N);
3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
35000605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek  if (Loc.asStmt())
351b697b100f2354ac84b7a0785cab9481e8bfdcf23Ted Kremenek    os << "Execution continues on line "
352642116259e8df6286063a17361c20e95b5017a0aChandler Carruth       << getSourceManager().getExpansionLineNumber(Loc.asLocation())
3538966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek       << '.';
3544f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek  else {
3554f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    os << "Execution jumps to the end of the ";
3564f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    const Decl *D = N->getLocationContext()->getDecl();
3574f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    if (isa<ObjCMethodDecl>(D))
3584f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "method";
3594f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    else if (isa<FunctionDecl>(D))
3604f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "function";
3614f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    else {
3624f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      assert(isa<BlockDecl>(D));
3634f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek      os << "anonymous block";
3644f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    }
3654f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek    os << '.';
3664f1db537722e8d46146cd95f5962a6dcf6e44e54Ted Kremenek  }
3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
368082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek  return Loc;
369143ca222583a4a355fdc89af852deef287499300Ted Kremenek}
370143ca222583a4a355fdc89af852deef287499300Ted Kremenek
371ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenekstatic bool IsNested(const Stmt *S, ParentMap &PM) {
372ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  if (isa<Expr>(S) && PM.isConsumedExpr(cast<Expr>(S)))
373ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    return true;
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
375ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  const Stmt *Parent = PM.getParentIgnoreParens(S);
3761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
377ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  if (Parent)
378ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    switch (Parent->getStmtClass()) {
379ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::ForStmtClass:
380ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::DoStmtClass:
381ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      case Stmt::WhileStmtClass:
382ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        return true;
383ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek      default:
384ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek        break;
385ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek    }
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return false;
388ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek}
389ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek
390d8c938b0f6b7a7156181be575239e4c6e15a2adbTed KremenekPathDiagnosticLocation
391d8c938b0f6b7a7156181be575239e4c6e15a2adbTed KremenekPathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
3929c378f705405d37f49795d5e915989de774fe11fTed Kremenek  assert(S && "Null Stmt *passed to getEnclosingStmtLocation");
3931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ParentMap &P = getParentMap();
3948966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek  SourceManager &SMgr = getSourceManager();
395e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
396ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek  while (IsNested(S, P)) {
3978c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    const Stmt *Parent = P.getParentIgnoreParens(S);
3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
399af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    if (!Parent)
400af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      break;
4011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
402af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    switch (Parent->getStmtClass()) {
4035fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      case Stmt::BinaryOperatorClass: {
4045fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        const BinaryOperator *B = cast<BinaryOperator>(Parent);
4055fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        if (B->isLogicalOp())
406220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
4075fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek        break;
4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
409af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::CompoundStmtClass:
410af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::StmtExprClass:
411220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks        return PathDiagnosticLocation(S, SMgr, LC);
4121d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek      case Stmt::ChooseExprClass:
4131d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // Similar to '?' if we are referring to condition, just have the edge
4141d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // point to the entire choose expression.
4151d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        if (cast<ChooseExpr>(Parent)->getCond() == S)
416220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
4171d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        else
418220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
41956ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall      case Stmt::BinaryConditionalOperatorClass:
4201d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek      case Stmt::ConditionalOperatorClass:
4211d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // For '?', if we are referring to condition, just have the edge point
4221d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        // to the entire '?' expression.
42356ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        if (cast<AbstractConditionalOperator>(Parent)->getCond() == S)
424220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
4251d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek        else
426220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
427af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::DoStmtClass:
428220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
429af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::ForStmtClass:
430af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<ForStmt>(Parent)->getBody() == S)
431220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        break;
433af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::IfStmtClass:
434af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<IfStmt>(Parent)->getCond() != S)
435220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
4368bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek        break;
437af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::ObjCForCollectionStmtClass:
438af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<ObjCForCollectionStmt>(Parent)->getBody() == S)
439220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
440af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
441af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      case Stmt::WhileStmtClass:
442af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        if (cast<WhileStmt>(Parent)->getCond() != S)
443220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(S, SMgr, LC);
444af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
445af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek      default:
446af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek        break;
447af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek    }
448af3e3d54e990b385e5a653d2994d7d41427a13b8Ted Kremenek
449d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek    S = Parent;
450d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  }
4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
452d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek  assert(S && "Cannot have null Stmt for PathDiagnosticLocation");
453e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
454e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  // Special case: DeclStmts can appear in for statement declarations, in which
455e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  //  case the ForStmt is the context.
456e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  if (isa<DeclStmt>(S)) {
457e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    if (const Stmt *Parent = P.getParent(S)) {
458e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek      switch (Parent->getStmtClass()) {
459e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        case Stmt::ForStmtClass:
460e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        case Stmt::ObjCForCollectionStmtClass:
461220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks          return PathDiagnosticLocation(Parent, SMgr, LC);
462e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek        default:
463e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek          break;
4641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      }
4651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
466e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  }
467e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  else if (isa<BinaryOperator>(S)) {
468e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // Special case: the binary operator represents the initialization
469e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // code in a for statement (this can happen when the variable being
470e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    // initialized is an old variable.
471e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    if (const ForStmt *FS =
472e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek          dyn_cast_or_null<ForStmt>(P.getParentIgnoreParens(S))) {
473e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek      if (FS->getInit() == S)
474220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks        return PathDiagnosticLocation(FS, SMgr, LC);
475e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek    }
476e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek  }
477e88a170da9219ef6a62d2182560c4de2ebffbd59Ted Kremenek
478220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks  return PathDiagnosticLocation(S, SMgr, LC);
479d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek}
480d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
481cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
482d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose// "Visitors only" path diagnostic generation algorithm.
483d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose//===----------------------------------------------------------------------===//
484d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rosestatic bool GenerateVisitorsOnlyPathDiagnostic(PathDiagnostic &PD,
485d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose                                               PathDiagnosticBuilder &PDB,
486d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose                                               const ExplodedNode *N,
487d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose                                      ArrayRef<BugReporterVisitor *> visitors) {
488d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  // All path generation skips the very first node (the error node).
489d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  // This is because there is special handling for the end-of-path note.
490d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  N = N->getFirstPred();
491d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  if (!N)
492d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose    return true;
493d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose
494d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  BugReport *R = PDB.getBugReport();
495d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  while (const ExplodedNode *Pred = N->getFirstPred()) {
496d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose    for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
497d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose                                                  E = visitors.end();
498d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose         I != E; ++I) {
499d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      // Visit all the node pairs, but throw the path pieces away.
500d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      PathDiagnosticPiece *Piece = (*I)->VisitNode(N, Pred, PDB, *R);
501d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      delete Piece;
502d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose    }
503d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose
504d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose    N = Pred;
505d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  }
506d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose
507d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  return R->isValid();
508d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose}
509d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose
510d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose//===----------------------------------------------------------------------===//
5113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// "Minimal" path diagnostic generation algorithm.
512cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek//===----------------------------------------------------------------------===//
51356a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zakstypedef std::pair<PathDiagnosticCallPiece*, const ExplodedNode*> StackDiagPair;
51456a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zakstypedef SmallVector<StackDiagPair, 6> StackDiagVector;
51556a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks
516368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaksstatic void updateStackPiecesWithMessage(PathDiagnosticPiece *P,
51756a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks                                         StackDiagVector &CallStack) {
518368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks  // If the piece contains a special message, add it to all the call
519368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks  // pieces on the active stack.
520368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks  if (PathDiagnosticEventPiece *ep =
521368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        dyn_cast<PathDiagnosticEventPiece>(P)) {
522368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
52356a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks    if (ep->hasCallStackHint())
52456a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks      for (StackDiagVector::iterator I = CallStack.begin(),
52556a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks                                     E = CallStack.end(); I != E; ++I) {
52656a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks        PathDiagnosticCallPiece *CP = I->first;
52756a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks        const ExplodedNode *N = I->second;
5288fe4525680ce72e90cee3e58b5654e3ae955447fNAKAMURA Takumi        std::string stackMsg = ep->getCallStackMessage(N);
52956a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks
530368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        // The last message on the path to final bug is the most important
531368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        // one. Since we traverse the path backwards, do not add the message
532368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        // if one has been previously added.
53356a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks        if  (!CP->hasCallStackMessage())
53456a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks          CP->setCallStackMessage(stackMsg);
53556a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks      }
536368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks  }
537368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks}
538cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek
53977d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenekstatic void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
54014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
5418347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rosestatic bool GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
5423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                          PathDiagnosticBuilder &PDB,
5433bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                          const ExplodedNode *N,
5443bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                      ArrayRef<BugReporterVisitor *> visitors) {
5458966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek
5463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  SourceManager& SMgr = PDB.getSourceManager();
54759950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  const LocationContext *LC = PDB.LC;
5489c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *NextNode = N->pred_empty()
5493106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                        ? NULL : *(N->pred_begin());
550368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
55156a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks  StackDiagVector CallStack;
552368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
5533106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  while (NextNode) {
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    N = NextNode;
55559950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek    PDB.LC = N->getLocationContext();
5563106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    NextNode = GetPredecessorNode(N);
5571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek    ProgramPoint P = N->getLocation();
55980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
56080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    do {
56180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks      if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
56280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        PathDiagnosticCallPiece *C =
56380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PathDiagnosticCallPiece::construct(N, *CE, SMgr);
56480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        GRBugReporter& BR = PDB.getBugReporter();
56580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        BR.addCallPieceLocationContextPair(C, CE->getCalleeContext());
56680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        PD.getActivePath().push_front(C);
56780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        PD.pushActivePath(&C->path);
56880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        CallStack.push_back(StackDiagPair(C, N));
56980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        break;
5709373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks      }
571183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose
57280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks      if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
57380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // Flush all locations, and pop the active path.
57480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        bool VisitedEntireCall = PD.isWithinCall();
57580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        PD.popActivePath();
57680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
57780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // Either we just added a bunch of stuff to the top-level path, or
57880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // we have a previous CallExitEnd.  If the former, it means that the
57980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // path terminated within a function call.  We must then take the
58080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // current contents of the active path and place it within
58180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // a new PathDiagnosticCallPiece.
58280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        PathDiagnosticCallPiece *C;
58380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        if (VisitedEntireCall) {
58480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
58580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        } else {
58680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          const Decl *Caller = CE->getLocationContext()->getDecl();
58780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
58880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          GRBugReporter& BR = PDB.getBugReporter();
58980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          BR.addCallPieceLocationContextPair(C, CE->getCalleeContext());
59080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        }
59180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
59280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        C->setCallee(*CE, SMgr);
59380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        if (!CallStack.empty()) {
59480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          assert(CallStack.back().first == C);
59580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          CallStack.pop_back();
59680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        }
59780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        break;
598368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks      }
5991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks      if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
60180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        const CFGBlock *Src = BE->getSrc();
60280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        const CFGBlock *Dst = BE->getDst();
60380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        const Stmt *T = Src->getTerminator();
6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        if (!T)
60680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          break;
6071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        PathDiagnosticLocation Start =
60980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PathDiagnosticLocation::createBegin(T, SMgr,
61080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                N->getLocationContext());
6111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        switch (T->getStmtClass()) {
61361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        default:
61461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
6151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61661f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        case Stmt::GotoStmtClass:
6171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::IndirectGotoStmtClass: {
6189c378f705405d37f49795d5e915989de774fe11fTed Kremenek          const Stmt *S = GetNextStmt(N);
6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          if (!S)
62180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            break;
6221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
623297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
6241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          llvm::raw_string_ostream os(sbuf);
625d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek          const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S);
6261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62700605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          os << "Control jumps to line "
62880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              << End.asLocation().getExpansionLineNumber();
62980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
63080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              Start, End, os.str()));
63161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
63261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        }
6331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::SwitchStmtClass: {
63561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          // Figure out what case arm we took.
636297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
637297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6399c378f705405d37f49795d5e915989de774fe11fTed Kremenek          if (const Stmt *S = Dst->getLabel()) {
640220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks            PathDiagnosticLocation End(S, SMgr, LC);
6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6425a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek            switch (S->getStmtClass()) {
64380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            default:
64480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              os << "No cases match in the switch statement. "
64580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              "Control jumps to line "
64680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              << End.asLocation().getExpansionLineNumber();
64780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              break;
64880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            case Stmt::DefaultStmtClass:
64980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              os << "Control jumps to the 'default' case at line "
65080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              << End.asLocation().getExpansionLineNumber();
65180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              break;
65280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
65380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            case Stmt::CaseStmtClass: {
65480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              os << "Control jumps to 'case ";
65580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              const CaseStmt *Case = cast<CaseStmt>(S);
65680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              const Expr *LHS = Case->getLHS()->IgnoreParenCasts();
65780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
65880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              // Determine if it is an enum.
65980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              bool GetRawInt = true;
66080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
66180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS)) {
66280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                // FIXME: Maybe this should be an assertion.  Are there cases
66380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                // were it is not an EnumConstantDecl?
66480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                const EnumConstantDecl *D =
66503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu                    dyn_cast<EnumConstantDecl>(DR->getDecl());
6661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
66780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                if (D) {
66880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  GetRawInt = false;
66980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  os << *D;
6705a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek                }
67180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              }
6729ec64d6e2fe575b297e1eaa5051efc2983373e25Eli Friedman
67380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              if (GetRawInt)
67480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                os << LHS->EvaluateKnownConstInt(PDB.getASTContext());
6759ec64d6e2fe575b297e1eaa5051efc2983373e25Eli Friedman
67680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              os << ":'  at line "
67780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  << End.asLocation().getExpansionLineNumber();
67880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              break;
67961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek            }
68080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            }
68180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
68280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                Start, End, os.str()));
68361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          }
684567839273dfc395a459cbe77d5f8d128b9ae85bfTed Kremenek          else {
685c3517ebb48a51e146badc08bc3684520c41da6c8Ted Kremenek            os << "'Default' branch taken. ";
6861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
68780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
68880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                Start, End, os.str()));
689567839273dfc395a459cbe77d5f8d128b9ae85bfTed Kremenek          }
6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69161f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek          break;
69261f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek        }
6931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6942673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        case Stmt::BreakStmtClass:
6952673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        case Stmt::ContinueStmtClass: {
696297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
697297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
69800605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
69980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
70080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              Start, End, os.str()));
7012673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek          break;
7022673c9ff76ebdb72b7f846e2ff1e0f4256372e19Ted Kremenek        }
7031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
70480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // Determine control-flow for ternary '?'.
70556ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall        case Stmt::BinaryConditionalOperatorClass:
706706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek        case Stmt::ConditionalOperatorClass: {
707297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          std::string sbuf;
708297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek          llvm::raw_string_ostream os(sbuf);
7091d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek          os << "'?' condition is ";
7101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
711706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          if (*(Src->succ_begin()+1) == Dst)
712082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek            os << "false";
713706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          else
714082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek            os << "true";
7151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
71600605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
7171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7181d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek          if (const Stmt *S = End.asStmt())
7191d9a23ac34fee297e28361653a72c519cb04a854Ted Kremenek            End = PDB.getEnclosingStmtLocation(S);
7201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
72280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              Start, End, os.str()));
723babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          break;
724babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek        }
7251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        // Determine control-flow for short-circuited '&&' and '||'.
727babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek        case Stmt::BinaryOperatorClass: {
728babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          if (!PDB.supportsLogicalOpControlFlow())
729babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek            break;
7301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
73103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu          const BinaryOperator *B = cast<BinaryOperator>(T);
732babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          std::string sbuf;
733babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          llvm::raw_string_ostream os(sbuf);
734babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          os << "Left side of '";
7351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7362de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall          if (B->getOpcode() == BO_LAnd) {
737f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            os << "&&" << "' is ";
7381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
739f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            if (*(Src->succ_begin()+1) == Dst) {
740f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "false";
741220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
7420cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation Start =
74380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  PathDiagnosticLocation::createOperatorLoc(B, SMgr);
74480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
74580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  Start, End, os.str()));
7461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
747f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            else {
748f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "true";
749220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
750f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
75180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
75280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  Start, End, os.str()));
7531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump            }
754babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          }
755babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          else {
7562de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall            assert(B->getOpcode() == BO_LOr);
757f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            os << "||" << "' is ";
7581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
759f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            if (*(Src->succ_begin()+1) == Dst) {
760f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "false";
761220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
762f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              PathDiagnosticLocation End = PDB.ExecutionContinues(N);
76380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
76480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  Start, End, os.str()));
765f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            }
766f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            else {
767f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek              os << "true";
768220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks              PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
7690cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation Start =
77080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  PathDiagnosticLocation::createOperatorLoc(B, SMgr);
77180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks              PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
77280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                  Start, End, os.str()));
773f5ab8e6eb4b1c14cb3a0f69aad526192794c95ceTed Kremenek            }
774babdd7b56d02e2b6924a2c93b061d6a48bb5f0caTed Kremenek          }
7751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
776706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          break;
777706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek        }
7781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::DoStmtClass:  {
780706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek          if (*(Src->succ_begin()) == Dst) {
781297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek            std::string sbuf;
782297308eda369de400e6ea7057dffeadd9f92e385Ted Kremenek            llvm::raw_string_ostream os(sbuf);
7831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
784c3517ebb48a51e146badc08bc3684520c41da6c8Ted Kremenek            os << "Loop condition is true. ";
785d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
7861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
787d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            if (const Stmt *S = End.asStmt())
788d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek              End = PDB.getEnclosingStmtLocation(S);
7891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
79080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
79180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                Start, End, os.str()));
792082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek          }
793082cb8d7bd9bdb3fe58e8e1a2897c79c4ebcc3a7Ted Kremenek          else {
79400605e0f011ed99225a22026344c5fc1b3212cd7Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
7951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
796d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek            if (const Stmt *S = End.asStmt())
797d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek              End = PDB.getEnclosingStmtLocation(S);
7981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
79980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
80080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                Start, End, "Loop condition is false.  Exiting loop"));
8013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
8021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8033106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
8043106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
8051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        case Stmt::WhileStmtClass:
8071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        case Stmt::ForStmtClass: {
8083106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (*(Src->succ_begin()+1) == Dst) {
8093106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            std::string sbuf;
8103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            llvm::raw_string_ostream os(sbuf);
8111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8123106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            os << "Loop condition is false. ";
8133106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
8143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            if (const Stmt *S = End.asStmt())
8153106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek              End = PDB.getEnclosingStmtLocation(S);
8161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
81780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
81880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                Start, End, os.str()));
8193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
8203106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          else {
8213106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            PathDiagnosticLocation End = PDB.ExecutionContinues(N);
8223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            if (const Stmt *S = End.asStmt())
8233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek              End = PDB.getEnclosingStmtLocation(S);
8241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
82580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
82680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                Start, End, "Loop condition is true.  Entering loop body"));
8273106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          }
8281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8293106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
8303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
8311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8323106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        case Stmt::IfStmtClass: {
8333106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          PathDiagnosticLocation End = PDB.ExecutionContinues(N);
8341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8353106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (const Stmt *S = End.asStmt())
8363106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek            End = PDB.getEnclosingStmtLocation(S);
8371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8383106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          if (*(Src->succ_begin()+1) == Dst)
83980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
84080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                Start, End, "Taking false branch"));
8411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          else
84280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks            PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(
84380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                Start, End, "Taking true branch"));
8441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8453106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          break;
8463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        }
84780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        }
8483106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
84980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    } while(0);
8501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
851dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    if (NextNode) {
8528e6431adab313e283a992698f6fc7afe62420999Anna Zaks      // Add diagnostic pieces from custom visitors.
8538e6431adab313e283a992698f6fc7afe62420999Anna Zaks      BugReport *R = PDB.getBugReport();
8543bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
8553bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                                    E = visitors.end();
8563bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose           I != E; ++I) {
857368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
8582042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(p);
859368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks          updateStackPiecesWithMessage(p, CallStack);
860368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        }
861dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      }
8628966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek    }
8633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
8641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8658347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose  if (!PDB.getBugReport()->isValid())
8668347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose    return false;
8678347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose
86814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // After constructing the full PathDiagnostic, do a pass over it to compact
86914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // PathDiagnosticPieces that occur within a macro.
87077d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  CompactPathDiagnostic(PD.getMutablePieces(), PDB.getSourceManager());
8718347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose  return true;
8723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
8733106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
8743106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
8755fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek// "Extensive" PathDiagnostic generation.
8765fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek//===----------------------------------------------------------------------===//
8775fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek
8785fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenekstatic bool IsControlFlowExpr(const Stmt *S) {
8795fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  const Expr *E = dyn_cast<Expr>(S);
8801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8815fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  if (!E)
8825fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    return false;
8831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  E = E->IgnoreParenCasts();
8851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
88656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall  if (isa<AbstractConditionalOperator>(E))
8875fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    return true;
8881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8895fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E))
8905fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek    if (B->isLogicalOp())
8915fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      return true;
8921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return false;
8945fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek}
8955fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek
89614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremeneknamespace {
897ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass ContextLocation : public PathDiagnosticLocation {
8988f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool IsDead;
8998f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenekpublic:
9008f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  ContextLocation(const PathDiagnosticLocation &L, bool isdead = false)
9018f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    : PathDiagnosticLocation(L), IsDead(isdead) {}
9021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  void markDead() { IsDead = true; }
9048f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool isDead() const { return IsDead; }
9058f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek};
9061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
907ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamclass EdgeBuilder {
9088f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  std::vector<ContextLocation> CLocs;
9098f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  typedef std::vector<ContextLocation>::iterator iterator;
91014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnostic &PD;
91114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticBuilder &PDB;
91214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticLocation PrevLoc;
9131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9148f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  bool IsConsumedExpr(const PathDiagnosticLocation &L);
9151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
91614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  bool containsLocation(const PathDiagnosticLocation &Container,
91714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                        const PathDiagnosticLocation &Containee);
9181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
91914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L);
9201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9219650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek  PathDiagnosticLocation cleanUpLocation(PathDiagnosticLocation L,
9229650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek                                         bool firstCharOnly = false) {
9238c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    if (const Stmt *S = L.asStmt()) {
9249650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek      const Stmt *Original = S;
9258c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek      while (1) {
9268c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek        // Adjust the location for some expressions that are best referenced
9278c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek        // by one of their subexpressions.
9289650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        switch (S->getStmtClass()) {
9299650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          default:
9309650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            break;
9319650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ParenExprClass:
932f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne          case Stmt::GenericSelectionExprClass:
933f111d935722ed488144600cea5ed03a6b5069e8fPeter Collingbourne            S = cast<Expr>(S)->IgnoreParens();
9349650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
9359650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
93656ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall          case Stmt::BinaryConditionalOperatorClass:
9379650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ConditionalOperatorClass:
93856ca35d396d8692c384c785f9aeebcf22563fe1eJohn McCall            S = cast<AbstractConditionalOperator>(S)->getCond();
9399650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
9409650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
9419650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::ChooseExprClass:
9429650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            S = cast<ChooseExpr>(S)->getCond();
9439650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
9449650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
9459650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek          case Stmt::BinaryOperatorClass:
9469650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            S = cast<BinaryOperator>(S)->getLHS();
9479650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            firstCharOnly = true;
9489650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek            continue;
9499650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        }
9501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9519650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek        break;
9528c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek      }
9531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9549650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek      if (S != Original)
95559950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek        L = PathDiagnosticLocation(S, L.getManager(), PDB.LC);
9568c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    }
9571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9589650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek    if (firstCharOnly)
9591531bb0c69d9afff6a6434e4cadf345eb628b287Anna Zaks      L  = PathDiagnosticLocation::createSingleLocation(L);
9609650cf3b08fcd66caae39bd5a1915c3eac735095Ted Kremenek
9618c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek    return L;
9628c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  }
9631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
96414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void popLocation() {
9658f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    if (!CLocs.back().isDead() && CLocs.back().asLocation().isFileID()) {
9665c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek      // For contexts, we only one the first character as the range.
96707c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek      rawAddEdge(cleanUpLocation(CLocs.back(), true));
9685c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek    }
96914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    CLocs.pop_back();
97014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
9711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
97214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekpublic:
97314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  EdgeBuilder(PathDiagnostic &pd, PathDiagnosticBuilder &pdb)
97414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    : PD(pd), PDB(pdb) {
9751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
976a301a6773db085575ac51e3c966858180390c25bTed Kremenek      // If the PathDiagnostic already has pieces, add the enclosing statement
977a301a6773db085575ac51e3c966858180390c25bTed Kremenek      // of the first piece as a context as well.
978802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek      if (!PD.path.empty()) {
979802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek        PrevLoc = (*PD.path.begin())->getLocation();
9801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
98114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        if (const Stmt *S = PrevLoc.asStmt())
982e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek          addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
98314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      }
98414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
98514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
98614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  ~EdgeBuilder() {
98714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    while (!CLocs.empty()) popLocation();
9880cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks
989a301a6773db085575ac51e3c966858180390c25bTed Kremenek    // Finally, add an initial edge from the start location of the first
990a301a6773db085575ac51e3c966858180390c25bTed Kremenek    // statement (if it doesn't already exist).
9910cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks    PathDiagnosticLocation L = PathDiagnosticLocation::createDeclBegin(
99259950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek                                                       PDB.LC,
9930cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks                                                       PDB.getSourceManager());
9940cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks    if (L.isValid())
9950cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks      rawAddEdge(L);
99614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
99714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
9985de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek  void flushLocations() {
9995de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek    while (!CLocs.empty())
10005de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      popLocation();
10015de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek    PrevLoc = PathDiagnosticLocation();
10025de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek  }
10035de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
100414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd = false);
10051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10068bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek  void rawAddEdge(PathDiagnosticLocation NewLoc);
10071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  void addContext(const Stmt *S);
1009183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose  void addContext(const PathDiagnosticLocation &L);
1010e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  void addExtendedContext(const Stmt *S);
10111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump};
101214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek} // end anonymous namespace
101314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
101414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
101514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted KremenekPathDiagnosticLocation
101614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted KremenekEdgeBuilder::getContextLocation(const PathDiagnosticLocation &L) {
101714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (const Stmt *S = L.asStmt()) {
101814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (IsControlFlowExpr(S))
101914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return L;
10201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return PDB.getEnclosingStmtLocation(S);
102214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
10231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
102414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  return L;
102514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
102614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
102714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekbool EdgeBuilder::containsLocation(const PathDiagnosticLocation &Container,
102814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                                   const PathDiagnosticLocation &Containee) {
102914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
103014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (Container == Containee)
103114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return true;
10321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
103314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (Container.asDecl())
103414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return true;
10351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
103614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (const Stmt *S = Containee.asStmt())
103714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (const Stmt *ContainerS = Container.asStmt()) {
103814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      while (S) {
103914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        if (S == ContainerS)
104014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          return true;
104114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        S = PDB.getParent(S);
104214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      }
104314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return false;
104414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
104514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
104614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // Less accurate: compare using source ranges.
104714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceRange ContainerR = Container.asRange();
104814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceRange ContaineeR = Containee.asRange();
10491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
105014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  SourceManager &SM = PDB.getSourceManager();
1051402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContainerRBeg = SM.getExpansionLoc(ContainerR.getBegin());
1052402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContainerREnd = SM.getExpansionLoc(ContainerR.getEnd());
1053402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContaineeRBeg = SM.getExpansionLoc(ContaineeR.getBegin());
1054402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  SourceLocation ContaineeREnd = SM.getExpansionLoc(ContaineeR.getEnd());
10551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1056642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContainerBegLine = SM.getExpansionLineNumber(ContainerRBeg);
1057642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContainerEndLine = SM.getExpansionLineNumber(ContainerREnd);
1058642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContaineeBegLine = SM.getExpansionLineNumber(ContaineeRBeg);
1059642116259e8df6286063a17361c20e95b5017a0aChandler Carruth  unsigned ContaineeEndLine = SM.getExpansionLineNumber(ContaineeREnd);
10601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
106114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  assert(ContainerBegLine <= ContainerEndLine);
10621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  assert(ContaineeBegLine <= ContaineeEndLine);
10631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
106414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  return (ContainerBegLine <= ContaineeBegLine &&
106514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          ContainerEndLine >= ContaineeEndLine &&
106614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          (ContainerBegLine != ContaineeBegLine ||
1067a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContainerRBeg) <=
1068a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContaineeRBeg)) &&
106914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek          (ContainerEndLine != ContaineeEndLine ||
1070a77c031cb66f75d22672070052cc6e0205289ff8Chandler Carruth           SM.getExpansionColumnNumber(ContainerREnd) >=
10716488dc31153be6f98b404c7860be6c66bb4ec917Ted Kremenek           SM.getExpansionColumnNumber(ContaineeREnd)));
107214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
107314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
107414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) {
107514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (!PrevLoc.isValid()) {
107614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    PrevLoc = NewLoc;
107714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
107814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
10791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10808c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  const PathDiagnosticLocation &NewLocClean = cleanUpLocation(NewLoc);
10818c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  const PathDiagnosticLocation &PrevLocClean = cleanUpLocation(PrevLoc);
10821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1083a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  if (PrevLocClean.asLocation().isInvalid()) {
1084a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek    PrevLoc = NewLoc;
1085a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek    return;
1086a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek  }
1087a43df9539644bf1c258e12710cd69d79b0b078cdTed Kremenek
10888c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  if (NewLocClean.asLocation() == PrevLocClean.asLocation())
108914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
10901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
109114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  // FIXME: Ignore intra-macro edges for now.
1092402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth  if (NewLocClean.asLocation().getExpansionLoc() ==
1093402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth      PrevLocClean.asLocation().getExpansionLoc())
109414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
109514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
10962042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek  PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
10978c8b0ad9601d6ccf3d7b2a3f77a896ef4fb4e6e9Ted Kremenek  PrevLoc = NewLoc;
109814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
109914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
110014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd) {
11011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1102a301a6773db085575ac51e3c966858180390c25bTed Kremenek  if (!alwaysAdd && NewLoc.asLocation().isMacroID())
1103a301a6773db085575ac51e3c966858180390c25bTed Kremenek    return;
11041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
110514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  const PathDiagnosticLocation &CLoc = getContextLocation(NewLoc);
110614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
110714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (!CLocs.empty()) {
11088f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    ContextLocation &TopContextLoc = CLocs.back();
11091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
111014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Is the top location context the same as the one for the new location?
111114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (TopContextLoc == CLoc) {
11128f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      if (alwaysAdd) {
11134c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek        if (IsConsumedExpr(TopContextLoc) &&
11144c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek            !IsControlFlowExpr(TopContextLoc.asStmt()))
11158f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek            TopContextLoc.markDead();
11168f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek
111714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        rawAddEdge(NewLoc);
11188f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      }
111914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
112014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return;
112114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
112214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
112314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (containsLocation(TopContextLoc, CLoc)) {
11248f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      if (alwaysAdd) {
112514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek        rawAddEdge(NewLoc);
11261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11274c6f8d38e2795c67048e16e737b8225eeb184262Ted Kremenek        if (IsConsumedExpr(CLoc) && !IsControlFlowExpr(CLoc.asStmt())) {
11288f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek          CLocs.push_back(ContextLocation(CLoc, true));
11298f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek          return;
11308f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek        }
11318f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek      }
11321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      CLocs.push_back(CLoc);
11341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return;
113514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
113614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
113714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Context does not contain the location.  Flush it.
113814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    popLocation();
113914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
11401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11415c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek  // If we reach here, there is no enclosing context.  Just add the edge.
11425c7168cbe8a0eabd05e0e12e469090d2cabd27c0Ted Kremenek  rawAddEdge(NewLoc);
114314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
114414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
11458f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenekbool EdgeBuilder::IsConsumedExpr(const PathDiagnosticLocation &L) {
11468f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  if (const Expr *X = dyn_cast_or_null<Expr>(L.asStmt()))
11478f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek    return PDB.getParentMap().isConsumedExpr(X) && !IsControlFlowExpr(X);
11481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11498f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek  return false;
11508f9b1b3865cd5814a8c4c768a34d56df6d6c93beTed Kremenek}
11511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1152e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenekvoid EdgeBuilder::addExtendedContext(const Stmt *S) {
1153e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  if (!S)
1154e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    return;
11551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const Stmt *Parent = PDB.getParent(S);
1157e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  while (Parent) {
1158e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    if (isa<CompoundStmt>(Parent))
1159e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      Parent = PDB.getParent(Parent);
1160e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    else
1161e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      break;
1162e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  }
1163e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek
1164e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  if (Parent) {
1165e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    switch (Parent->getStmtClass()) {
1166e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      case Stmt::DoStmtClass:
1167e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      case Stmt::ObjCAtSynchronizedStmtClass:
1168e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek        addContext(Parent);
1169e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek      default:
1170e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek        break;
1171e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek    }
1172e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  }
11731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1174e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek  addContext(S);
1175e1baed38437e08fee7ab372ba2579ce22da354c2Ted Kremenek}
11761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
117714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenekvoid EdgeBuilder::addContext(const Stmt *S) {
117814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  if (!S)
117914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    return;
118014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
118159950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek  PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.LC);
1182183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose  addContext(L);
1183183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose}
11841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1185183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rosevoid EdgeBuilder::addContext(const PathDiagnosticLocation &L) {
118614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (!CLocs.empty()) {
118714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    const PathDiagnosticLocation &TopContextLoc = CLocs.back();
118814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
118914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Is the top location context the same as the one for the new location?
119014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (TopContextLoc == L)
119114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      return;
119214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
119314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    if (containsLocation(TopContextLoc, L)) {
119414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      CLocs.push_back(L);
11951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      return;
119614856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    }
119714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
119814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    // Context does not contain the location.  Flush it.
119914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    popLocation();
120014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
120114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
120214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  CLocs.push_back(L);
120314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
120414856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
120511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// Cone-of-influence: support the reverse propagation of "interesting" symbols
120611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// and values by tracing interesting calculations backwards through evaluated
120711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// expressions along a path.  This is probably overly complicated, but the idea
120811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// is that if an expression computed an "interesting" value, the child
120911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// expressions are are also likely to be "interesting" as well (which then
121011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// propagates to the values they in turn compute).  This reverse propagation
121111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// is needed to track interesting correlations across function call boundaries,
121211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// where formal arguments bind to actual arguments, etc.  This is also needed
121311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// because the constraint solver sometimes simplifies certain symbolic values
121411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// into constants when appropriate, and this complicates reasoning about
121511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek// interesting values.
121611abcecc8c919673237cf37384290a1ef1943976Ted Kremenektypedef llvm::DenseSet<const Expr *> InterestingExprs;
121711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek
121811abcecc8c919673237cf37384290a1ef1943976Ted Kremenekstatic void reversePropagateIntererstingSymbols(BugReport &R,
121911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                                InterestingExprs &IE,
122011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                                const ProgramState *State,
122111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                                const Expr *Ex,
122211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                                const LocationContext *LCtx) {
122311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  SVal V = State->getSVal(Ex, LCtx);
122411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  if (!(R.isInteresting(V) || IE.count(Ex)))
122511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    return;
122611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek
122711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  switch (Ex->getStmtClass()) {
122811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    default:
122911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      if (!isa<CastExpr>(Ex))
123011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        break;
123111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      // Fall through.
123211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    case Stmt::BinaryOperatorClass:
123311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    case Stmt::UnaryOperatorClass: {
123411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      for (Stmt::const_child_iterator CI = Ex->child_begin(),
123511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek            CE = Ex->child_end();
123611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek            CI != CE; ++CI) {
123711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        if (const Expr *child = dyn_cast_or_null<Expr>(*CI)) {
123811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          IE.insert(child);
123911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          SVal ChildV = State->getSVal(child, LCtx);
124011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          R.markInteresting(ChildV);
124111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        }
124211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        break;
124311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      }
124411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    }
124511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  }
124611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek
124711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  R.markInteresting(V);
124811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek}
124911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek
125011abcecc8c919673237cf37384290a1ef1943976Ted Kremenekstatic void reversePropagateInterestingSymbols(BugReport &R,
125111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                               InterestingExprs &IE,
125211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                               const ProgramState *State,
125311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                               const LocationContext *CalleeCtx,
125411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                               const LocationContext *CallerCtx)
125511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek{
1256852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose  // FIXME: Handle non-CallExpr-based CallEvents.
125711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  const StackFrameContext *Callee = CalleeCtx->getCurrentStackFrame();
125811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  const Stmt *CallSite = Callee->getCallSite();
1259852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose  if (const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite)) {
126011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeCtx->getDecl())) {
126111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      FunctionDecl::param_const_iterator PI = FD->param_begin(),
126211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                         PE = FD->param_end();
126311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
126411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      for (; AI != AE && PI != PE; ++AI, ++PI) {
126511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        if (const Expr *ArgE = *AI) {
126611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          if (const ParmVarDecl *PD = *PI) {
126711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek            Loc LV = State->getLValue(PD, CalleeCtx);
126811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek            if (R.isInteresting(LV) || R.isInteresting(State->getRawSVal(LV)))
126911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek              IE.insert(ArgE);
127011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          }
127111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        }
127211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      }
127311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    }
127411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  }
127511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek}
127611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek
12778347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rosestatic bool GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
127814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek                                            PathDiagnosticBuilder &PDB,
12793bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                            const ExplodedNode *N,
12803bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                      ArrayRef<BugReporterVisitor *> visitors) {
128114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  EdgeBuilder EB(PD, PDB);
12820cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks  const SourceManager& SM = PDB.getSourceManager();
128356a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks  StackDiagVector CallStack;
128411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  InterestingExprs IE;
128514856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
12869c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
128714856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  while (NextNode) {
128814856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    N = NextNode;
128914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    NextNode = GetPredecessorNode(N);
129014856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek    ProgramPoint P = N->getLocation();
129114856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
1292dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    do {
129311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
129411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        if (const Expr *Ex = PS->getStmtAs<Expr>())
129511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
129611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                              N->getState().getPtr(), Ex,
129711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                              N->getLocationContext());
129811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      }
129911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek
13000b3ade86a1c60cf0c7b56aa238aff458eb7f5974Anna Zaks      if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
1301183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        const Stmt *S = CE->getCalleeContext()->getCallSite();
1302183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
1303852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose            reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
1304852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose                                                N->getState().getPtr(), Ex,
1305852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose                                                N->getLocationContext());
1306852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose        }
1307183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose
1308183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        PathDiagnosticCallPiece *C =
1309183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose          PathDiagnosticCallPiece::construct(N, *CE, SM);
131080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        GRBugReporter& BR = PDB.getBugReporter();
131180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks        BR.addCallPieceLocationContextPair(C, CE->getCalleeContext());
1312183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose
1313183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        EB.addEdge(C->callReturn, true);
1314183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        EB.flushLocations();
1315183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose
1316183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        PD.getActivePath().push_front(C);
1317183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        PD.pushActivePath(&C->path);
1318183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        CallStack.push_back(StackDiagPair(C, N));
13195de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek        break;
13205de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek      }
13214ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek
13222042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // Pop the call hierarchy if we are done walking the contents
13232042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      // of a function call.
13242042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
1325097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        // Add an edge to the start of the function.
1326097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        const Decl *D = CE->getCalleeContext()->getDecl();
1327097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        PathDiagnosticLocation pos =
1328097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek          PathDiagnosticLocation::createBegin(D, SM);
1329097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        EB.addEdge(pos);
1330097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek
1331097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek        // Flush all locations, and pop the active path.
1332183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        bool VisitedEntireCall = PD.isWithinCall();
13334ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek        EB.flushLocations();
13342042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.popActivePath();
13354ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek        PDB.LC = N->getLocationContext();
1336097ebb3d8ce55d1f78a3f1e7a0978dbde5ee2898Ted Kremenek
1337183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        // Either we just added a bunch of stuff to the top-level path, or
1338183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        // we have a previous CallExitEnd.  If the former, it means that the
13392042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // path terminated within a function call.  We must then take the
13402042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // current contents of the active path and place it within
13412042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        // a new PathDiagnosticCallPiece.
1342183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        PathDiagnosticCallPiece *C;
1343183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        if (VisitedEntireCall) {
1344183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose          C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
1345183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        } else {
1346183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose          const Decl *Caller = CE->getLocationContext()->getDecl();
13479373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks          C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
134880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          GRBugReporter& BR = PDB.getBugReporter();
134980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks          BR.addCallPieceLocationContextPair(C, CE->getCalleeContext());
13509373937945e1e075dfa08169eaccc1ad0b31f699Anna Zaks        }
1351852aa0d2c5d2d1faf2d77b5aa3c0848068a342c5Jordan Rose
1352183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        C->setCallee(*CE, SM);
1353183ba8e19d49ab1ae25d3cdd0a19591369c5ab9fJordan Rose        EB.addContext(C->getLocation());
1354368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
1355368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        if (!CallStack.empty()) {
135656a938ff85a444eb3d30d2634d92ce5b1f6fae56Anna Zaks          assert(CallStack.back().first == C);
1357368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks          CallStack.pop_back();
1358368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        }
13592042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        break;
13602042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek      }
13614ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek
13624ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      // Note that is important that we update the LocationContext
13634ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      // after looking at CallExits.  CallExit basically adds an
13644ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      // edge in the *caller*, so we don't want to update the LocationContext
13654ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      // too soon.
13664ba86bc53bb280ba46a08459eda7d283d513b61fTed Kremenek      PDB.LC = N->getLocationContext();
13675de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
1368dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      // Block edges.
136911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
137011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        // Does this represent entering a call?  If so, look at propagating
137111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        // interesting symbols across call boundaries.
137211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        if (NextNode) {
137311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          const LocationContext *CallerCtx = NextNode->getLocationContext();
137411abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          const LocationContext *CalleeCtx = PDB.LC;
137511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          if (CallerCtx != CalleeCtx) {
137611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek            reversePropagateInterestingSymbols(*PDB.getBugReport(), IE,
137711abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                               N->getState().getPtr(),
137811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek                                               CalleeCtx, CallerCtx);
137911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek          }
138011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        }
138111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek
1382dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        // Are we jumping to the head of a loop?  Add a special diagnostic.
1383f57a2aa02c0578c5bd834fec0d44c16ad9908620Ted Kremenek        if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) {
138459950d3aa54ca5066b1fb08a8c79ebfe10e0919bTed Kremenek          PathDiagnosticLocation L(Loop, SM, PDB.LC);
1385ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          const CompoundStmt *CS = NULL;
13861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1387f57a2aa02c0578c5bd834fec0d44c16ad9908620Ted Kremenek          if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
1388f57a2aa02c0578c5bd834fec0d44c16ad9908620Ted Kremenek            CS = dyn_cast<CompoundStmt>(FS->getBody());
1389f57a2aa02c0578c5bd834fec0d44c16ad9908620Ted Kremenek          else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
1390f57a2aa02c0578c5bd834fec0d44c16ad9908620Ted Kremenek            CS = dyn_cast<CompoundStmt>(WS->getBody());
13911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1392dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          PathDiagnosticEventPiece *p =
1393dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek            new PathDiagnosticEventPiece(L,
139407c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek                                        "Looping back to the head of the loop");
13952dd17abf11ae64339fa6bfaa57d76e13a5fbe5b8Ted Kremenek          p->setPrunable(true);
13961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1397dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          EB.addEdge(p->getLocation(), true);
13982042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek          PD.getActivePath().push_front(p);
13991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1400ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          if (CS) {
14010cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks            PathDiagnosticLocation BL =
14020cd59482abd8aec9ed1eaad11f5fe9c1e42639f6Anna Zaks              PathDiagnosticLocation::createEndBrace(CS, SM);
140307c015cbcee31f72e2d320ba2c713c046bed42faTed Kremenek            EB.addEdge(BL);
1404dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek          }
14058bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek        }
1406f57a2aa02c0578c5bd834fec0d44c16ad9908620Ted Kremenek
1407f57a2aa02c0578c5bd834fec0d44c16ad9908620Ted Kremenek        if (const Stmt *Term = BE->getSrc()->getTerminator())
1408ddb7babf448822e0f8da07fdf9446cf515d04ad5Ted Kremenek          EB.addContext(Term);
14091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1410dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        break;
14118bd4d037d837e7922c3661d6158229da58a03887Ted Kremenek      }
141214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
14131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
14141a7bcc41efb73d80fd45eb71494b073f388d333cJordan Rose        CFGElement First = BE->getFirstElement();
14151a7bcc41efb73d80fd45eb71494b073f388d333cJordan Rose        if (const CFGStmt *S = First.getAs<CFGStmt>()) {
14163c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          const Stmt *stmt = S->getStmt();
14173c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek          if (IsControlFlowExpr(stmt)) {
1418b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu            // Add the proper context for '&&', '||', and '?'.
14193c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            EB.addContext(stmt);
1420b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu          }
1421b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu          else
14223c0349e87cdbd7316d06d2411d86ee1086e717a5Ted Kremenek            EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt());
1423dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        }
1424b36cd3e1757fb4fcd9509f35558c847b04bef35fZhongxing Xu
1425dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek        break;
1426dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek      }
14275de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
14285de4fdb8de700f95b0b863a9e5a4a508de17a034Ted Kremenek
1429dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    } while (0);
14301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1431dd986cc9989f665370cef0917ba8ba3b4871e3e6Ted Kremenek    if (!NextNode)
143214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek      continue;
14331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14348e6431adab313e283a992698f6fc7afe62420999Anna Zaks    // Add pieces from custom visitors.
14358e6431adab313e283a992698f6fc7afe62420999Anna Zaks    BugReport *R = PDB.getBugReport();
14363bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
14373bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                                  E = visitors.end();
14383bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose         I != E; ++I) {
14398e6431adab313e283a992698f6fc7afe62420999Anna Zaks      if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
14408966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        const PathDiagnosticLocation &Loc = p->getLocation();
14418966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        EB.addEdge(Loc, true);
14422042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek        PD.getActivePath().push_front(p);
1443368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks        updateStackPiecesWithMessage(p, CallStack);
1444368a0d565f078666ca5bfb7fe08d04648688e4bcAnna Zaks
14458966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek        if (const Stmt *S = Loc.asStmt())
14461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump          EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
14478966bc1c8ce271c09936c0eaf6c841aef4a0af1bTed Kremenek      }
14481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
144914856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek  }
14508347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose
14518347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose  return PDB.getBugReport()->isValid();
145214856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek}
145314856d7b7a2be05ae9a0fd5b2073631994c2ba43Ted Kremenek
14545fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek//===----------------------------------------------------------------------===//
14553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugType and subclasses.
14563106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
1457404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios KyrtzidisBugType::~BugType() { }
1458404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
14593106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekvoid BugType::FlushReports(BugReporter &BR) {}
14603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
146199ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid BuiltinBug::anchor() {}
146299ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
14633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
14643106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugReport and subclasses.
14653106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
1466e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
146799ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikievoid BugReport::NodeResolver::anchor() {}
146899ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie
14698e6431adab313e283a992698f6fc7afe62420999Anna Zaksvoid BugReport::addVisitor(BugReporterVisitor* visitor) {
14708e6431adab313e283a992698f6fc7afe62420999Anna Zaks  if (!visitor)
14718e6431adab313e283a992698f6fc7afe62420999Anna Zaks    return;
14728e6431adab313e283a992698f6fc7afe62420999Anna Zaks
14738e6431adab313e283a992698f6fc7afe62420999Anna Zaks  llvm::FoldingSetNodeID ID;
14748e6431adab313e283a992698f6fc7afe62420999Anna Zaks  visitor->Profile(ID);
14758e6431adab313e283a992698f6fc7afe62420999Anna Zaks  void *InsertPos;
14768e6431adab313e283a992698f6fc7afe62420999Anna Zaks
14778e6431adab313e283a992698f6fc7afe62420999Anna Zaks  if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) {
14788e6431adab313e283a992698f6fc7afe62420999Anna Zaks    delete visitor;
14798e6431adab313e283a992698f6fc7afe62420999Anna Zaks    return;
14808e6431adab313e283a992698f6fc7afe62420999Anna Zaks  }
14818e6431adab313e283a992698f6fc7afe62420999Anna Zaks
14828e6431adab313e283a992698f6fc7afe62420999Anna Zaks  CallbacksSet.InsertNode(visitor, InsertPos);
14833bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  Callbacks.push_back(visitor);
14843bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  ++ConfigurationChangeToken;
14858e6431adab313e283a992698f6fc7afe62420999Anna Zaks}
14868e6431adab313e283a992698f6fc7afe62420999Anna Zaks
14878e6431adab313e283a992698f6fc7afe62420999Anna ZaksBugReport::~BugReport() {
14888e6431adab313e283a992698f6fc7afe62420999Anna Zaks  for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I) {
1489dc757b049796949e4b11646445a6598f0bdabd7aAnna Zaks    delete *I;
14908e6431adab313e283a992698f6fc7afe62420999Anna Zaks  }
1491c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  while (!interestingSymbols.empty()) {
1492c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    popInterestingSymbolsAndRegions();
1493c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  }
14948e6431adab313e283a992698f6fc7afe62420999Anna Zaks}
1495e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
149607189521a15d9c088216b943649cb9fe231cbb57Ted Kremenekconst Decl *BugReport::getDeclWithIssue() const {
149707189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  if (DeclWithIssue)
149807189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek    return DeclWithIssue;
149907189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek
150007189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  const ExplodedNode *N = getErrorNode();
150107189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  if (!N)
150207189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek    return 0;
150307189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek
150407189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  const LocationContext *LC = N->getLocationContext();
150507189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  return LC->getCurrentStackFrame()->getDecl();
150607189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek}
150707189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek
1508e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaksvoid BugReport::Profile(llvm::FoldingSetNodeID& hash) const {
1509e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  hash.AddPointer(&BT);
1510e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  hash.AddString(Description);
1511ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks  if (UniqueingLocation.isValid()) {
1512ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks    UniqueingLocation.Profile(hash);
1513ca8e36eb637e232475ef31c3f22d5da907390917Anna Zaks  } else if (Location.isValid()) {
1514590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    Location.Profile(hash);
1515590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  } else {
1516590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    assert(ErrorNode);
1517590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    hash.AddPointer(GetCurrentOrPreviousStmt(ErrorNode));
1518590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  }
1519e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
1520e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  for (SmallVectorImpl<SourceRange>::const_iterator I =
1521e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      Ranges.begin(), E = Ranges.end(); I != E; ++I) {
1522e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    const SourceRange range = *I;
1523e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    if (!range.isValid())
1524e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      continue;
1525e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    hash.AddInteger(range.getBegin().getRawEncoding());
1526e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    hash.AddInteger(range.getEnd().getRawEncoding());
1527e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  }
1528e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks}
15293106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
153076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekvoid BugReport::markInteresting(SymbolRef sym) {
153176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (!sym)
153276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return;
15333bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
15343bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // If the symbol wasn't already in our set, note a configuration change.
1535c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  if (getInterestingSymbols().insert(sym).second)
15363bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    ++ConfigurationChangeToken;
15378ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose
15388ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose  if (const SymbolMetadata *meta = dyn_cast<SymbolMetadata>(sym))
1539c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    getInterestingRegions().insert(meta->getRegion());
154076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
154176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
154276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekvoid BugReport::markInteresting(const MemRegion *R) {
154376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (!R)
154476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return;
15453bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
15463bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // If the base region wasn't already in our set, note a configuration change.
154776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  R = R->getBaseRegion();
1548c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  if (getInterestingRegions().insert(R).second)
15493bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    ++ConfigurationChangeToken;
15508ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose
155176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
1552c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    getInterestingSymbols().insert(SR->getSymbol());
155376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
155476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
155576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenekvoid BugReport::markInteresting(SVal V) {
155676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  markInteresting(V.getAsRegion());
155776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  markInteresting(V.getAsSymbol());
155876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
155976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
156080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaksvoid BugReport::markInteresting(const LocationContext *LC) {
156180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  if (!LC)
156280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    return;
156380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  InterestingLocationContexts.insert(LC);
156480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks}
156580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
1566c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenekbool BugReport::isInteresting(SVal V) {
156776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  return isInteresting(V.getAsRegion()) || isInteresting(V.getAsSymbol());
156876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
156976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
1570c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenekbool BugReport::isInteresting(SymbolRef sym) {
157176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (!sym)
157276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return false;
15738ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose  // We don't currently consider metadata symbols to be interesting
15748ec588e2ac57311604cf80608c7d4b3fb3b022f7Jordy Rose  // even if we know their region is interesting. Is that correct behavior?
1575c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  return getInterestingSymbols().count(sym);
157676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
157776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
1578c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenekbool BugReport::isInteresting(const MemRegion *R) {
157976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (!R)
158076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return false;
158176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  R = R->getBaseRegion();
1582c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  bool b = getInterestingRegions().count(R);
158376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (b)
158476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    return true;
158576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
1586c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    return getInterestingSymbols().count(SR->getSymbol());
158776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  return false;
158876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek}
1589c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek
159080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaksbool BugReport::isInteresting(const LocationContext *LC) {
159180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  if (!LC)
159280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    return false;
159380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  return InterestingLocationContexts.count(LC);
159480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks}
159580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
1596c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenekvoid BugReport::lazyInitializeInterestingSets() {
1597c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  if (interestingSymbols.empty()) {
1598c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    interestingSymbols.push_back(new Symbols());
1599c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    interestingRegions.push_back(new Regions());
1600c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  }
1601c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek}
1602c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek
1603c4bac8e376b98d633bb00ee5f510d5e58449753cTed KremenekBugReport::Symbols &BugReport::getInterestingSymbols() {
1604c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  lazyInitializeInterestingSets();
1605c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  return *interestingSymbols.back();
1606c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek}
1607c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek
1608c4bac8e376b98d633bb00ee5f510d5e58449753cTed KremenekBugReport::Regions &BugReport::getInterestingRegions() {
1609c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  lazyInitializeInterestingSets();
1610c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  return *interestingRegions.back();
1611c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek}
1612c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek
1613c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenekvoid BugReport::pushInterestingSymbolsAndRegions() {
1614c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  interestingSymbols.push_back(new Symbols(getInterestingSymbols()));
1615c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  interestingRegions.push_back(new Regions(getInterestingRegions()));
1616c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek}
1617c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek
1618c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenekvoid BugReport::popInterestingSymbolsAndRegions() {
1619c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  delete interestingSymbols.back();
1620c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  interestingSymbols.pop_back();
1621c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  delete interestingRegions.back();
1622c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  interestingRegions.pop_back();
1623c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek}
162476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
16259c378f705405d37f49795d5e915989de774fe11fTed Kremenekconst Stmt *BugReport::getStmt() const {
1626e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks  if (!ErrorNode)
1627e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    return 0;
1628e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
1629212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care  ProgramPoint ProgP = ErrorNode->getLocation();
16305f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  const Stmt *S = NULL;
16311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16329c378f705405d37f49795d5e915989de774fe11fTed Kremenek  if (BlockEntrance *BE = dyn_cast<BlockEntrance>(&ProgP)) {
1633fafd3834754d2093e0ad7a1c005860fd527ecb7fZhongxing Xu    CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit();
163450d5bc4e3b53eb8bb4ebf198f1213348a3fa0f38Zhongxing Xu    if (BE->getBlock() == &Exit)
1635212f6d3b5fb3fa55ba1e40671cfc336430abc8ddTom Care      S = GetPreviousStmt(ErrorNode);
16363106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
16375f85e17df3f5b0a8021443f2b590daecfb2cbd17Ted Kremenek  if (!S)
16381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    S = GetStmt(ProgP);
16391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return S;
16413106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
16423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1643640ccf071076e684713cc3c3276bb51982bff607Argyrios Kyrtzidisstd::pair<BugReport::ranges_iterator, BugReport::ranges_iterator>
1644e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna ZaksBugReport::getRanges() {
1645e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    // If no custom ranges, add the range of the statement corresponding to
1646e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    // the error node.
1647e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    if (Ranges.empty()) {
1648e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      if (const Expr *E = dyn_cast_or_null<Expr>(getStmt()))
1649e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks        addRange(E->getSourceRange());
1650e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      else
1651e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks        return std::make_pair(ranges_iterator(), ranges_iterator());
1652e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    }
1653e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks
165414924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks    // User-specified absence of range info.
165514924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks    if (Ranges.size() == 1 && !Ranges.begin()->isValid())
165614924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks      return std::make_pair(ranges_iterator(), ranges_iterator());
165714924267950e75c6c1f6fcea39fa507b7168bc39Anna Zaks
1658e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks    return std::make_pair(Ranges.begin(), Ranges.end());
16593106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
16603106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1661590dd8e0959d8df5621827768987c4792b74fc06Anna ZaksPathDiagnosticLocation BugReport::getLocation(const SourceManager &SM) const {
1662b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  if (ErrorNode) {
1663590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks    assert(!Location.isValid() &&
1664b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks     "Either Location or ErrorNode should be specified but not both.");
1665b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks
16669c378f705405d37f49795d5e915989de774fe11fTed Kremenek    if (const Stmt *S = GetCurrentOrPreviousStmt(ErrorNode)) {
1667590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      const LocationContext *LC = ErrorNode->getLocationContext();
1668590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks
16693106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // For member expressions, return the location of the '.' or '->'.
16705b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      if (const MemberExpr *ME = dyn_cast<MemberExpr>(S))
1671590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        return PathDiagnosticLocation::createMemberLoc(ME, SM);
16725b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      // For binary operators, return the location of the operator.
16735b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek      if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
1674590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        return PathDiagnosticLocation::createOperatorLoc(B, SM);
16753106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1676590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      return PathDiagnosticLocation::createBegin(S, SM, LC);
16773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1678b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  } else {
1679b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks    assert(Location.isValid());
1680b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks    return Location;
1681b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks  }
1682b7530a4ca9a7ef62350682bbb374a06de6fdaa9fAnna Zaks
1683590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  return PathDiagnosticLocation();
16843106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
16853106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
16863106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
16873106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// Methods for BugReporter and subclasses.
16883106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
16893106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
16904a5f724538cbc275370c9504e8169ce92503256cBenjamin KramerBugReportEquivClass::~BugReportEquivClass() { }
1691a2f4ec0df645fc249d2945beef9653f03b175417Zhongxing XuGRBugReporter::~GRBugReporter() { }
16923106198188ac6eb2753f1764d5c28376b0b76351Ted KremenekBugReporterData::~BugReporterData() {}
16933106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
169438b02b912e1a55c912f603c4369431264d36a381Zhongxing XuExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); }
16953106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
169618c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekProgramStateManager&
16973106198188ac6eb2753f1764d5c28376b0b76351Ted KremenekGRBugReporter::getStateManager() { return Eng.getStateManager(); }
16983106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
16993b030a28cda2b953758507769c1d436bec5ec45eAnna ZaksBugReporter::~BugReporter() {
17003b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  FlushReports();
17013b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks
17023b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  // Free the bug reports we are tracking.
17033b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  typedef std::vector<BugReportEquivClass *> ContTy;
17043b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  for (ContTy::iterator I = EQClassesVector.begin(), E = EQClassesVector.end();
17053b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks       I != E; ++I) {
17063b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks    delete *I;
17073b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks  }
17083b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks}
17093106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
17103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenekvoid BugReporter::FlushReports() {
17113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  if (BugTypes.isEmpty())
17123106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    return;
17133106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
17143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // First flush the warnings for each BugType.  This may end up creating new
1715404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // warnings and new BugTypes.
1716404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // FIXME: Only NSErrorChecker needs BugType's FlushReports.
1717404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // Turn NSErrorChecker into a proper checker and remove this.
17185f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const BugType*, 16> bugTypes;
17193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  for (BugTypesTy::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
1720404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    bugTypes.push_back(*I);
17215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  for (SmallVector<const BugType*, 16>::iterator
1722404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis         I = bugTypes.begin(), E = bugTypes.end(); I != E; ++I)
17233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    const_cast<BugType*>(*I)->FlushReports(*this);
17243106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1725d015f4febe85d3e3340172d70042840c51bbd836Anna Zaks  // We need to flush reports in deterministic order to ensure the order
1726d015f4febe85d3e3340172d70042840c51bbd836Anna Zaks  // of the reports is consistent between runs.
17270eb6c37dd4e4ad8fa2363003dea270f9fd6c2969Anna Zaks  typedef std::vector<BugReportEquivClass *> ContVecTy;
17280eb6c37dd4e4ad8fa2363003dea270f9fd6c2969Anna Zaks  for (ContVecTy::iterator EI=EQClassesVector.begin(), EE=EQClassesVector.end();
17290eb6c37dd4e4ad8fa2363003dea270f9fd6c2969Anna Zaks       EI != EE; ++EI){
17300eb6c37dd4e4ad8fa2363003dea270f9fd6c2969Anna Zaks    BugReportEquivClass& EQ = **EI;
1731404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    FlushReport(EQ);
17323106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
17333106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
1734404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // BugReporter owns and deletes only BugTypes created implicitly through
1735404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // EmitBasicReport.
1736404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // FIXME: There are leaks from checkers that assume that the BugTypes they
1737404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // create will be destroyed by the BugReporter.
1738404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  for (llvm::StringMap<BugType*>::iterator
1739404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis         I = StrBugTypes.begin(), E = StrBugTypes.end(); I != E; ++I)
1740404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    delete I->second;
1741404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
17423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Remove all references to the BugType objects.
17433baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek  BugTypes = F.getEmptySet();
17443106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
17453106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
17463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
17473106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek// PathDiagnostics generation.
17483106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek//===----------------------------------------------------------------------===//
17493106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
175038b02b912e1a55c912f603c4369431264d36a381Zhongxing Xustatic std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
1751c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu                 std::pair<ExplodedNode*, unsigned> >
175238b02b912e1a55c912f603c4369431264d36a381Zhongxing XuMakeReportGraph(const ExplodedGraph* G,
17535f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                SmallVectorImpl<const ExplodedNode*> &nodes) {
17541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create the trimmed graph.  It will contain the shortest paths from the
17561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // error nodes to the root.  In the new graph we should only have one
17573106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // error node unless there are two or more error nodes with the same minimum
17583106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // path length.
175938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  ExplodedGraph* GTrim;
1760c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  InterExplodedGraphMap* NMap;
17613106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
17623106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  llvm::DenseMap<const void*, const void*> InverseMap;
176340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  llvm::tie(GTrim, NMap) = G->Trim(nodes.data(), nodes.data() + nodes.size(),
176440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek                                   &InverseMap);
17651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create owning pointers for GTrim and NMap just to ensure that they are
17673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // released when this function exists.
17686f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ExplodedGraph> AutoReleaseGTrim(GTrim);
17696f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<InterExplodedGraphMap> AutoReleaseNMap(NMap);
17701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17713106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Find the (first) error node in the trimmed graph.  We just need to consult
17723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // the node map (NMap) which maps from nodes in the original graph to nodes
17733106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // in the new graph.
1774938332c657390d1e782e0adc03b092993edae962Ted Kremenek
1775c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  std::queue<const ExplodedNode*> WS;
177638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  typedef llvm::DenseMap<const ExplodedNode*, unsigned> IndexMapTy;
1777938332c657390d1e782e0adc03b092993edae962Ted Kremenek  IndexMapTy IndexMap;
17783106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
177940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  for (unsigned nodeIndex = 0 ; nodeIndex < nodes.size(); ++nodeIndex) {
178040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    const ExplodedNode *originalNode = nodes[nodeIndex];
178140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (const ExplodedNode *N = NMap->getMappedNode(originalNode)) {
1782938332c657390d1e782e0adc03b092993edae962Ted Kremenek      WS.push(N);
178340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      IndexMap[originalNode] = nodeIndex;
17843106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
178540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  }
17861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1787938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(!WS.empty() && "No error node found in the trimmed graph.");
17883106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
17893106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Create a new (third!) graph with a single path.  This is the graph
17903106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // that will be returned to the caller.
1791c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu  ExplodedGraph *GNew = new ExplodedGraph();
17921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17933106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Sometimes the trimmed graph can contain a cycle.  Perform a reverse BFS
17943106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // to the root node, and then construct a new graph that contains only
17953106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // a single path.
17963106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  llvm::DenseMap<const void*,unsigned> Visited;
17971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
17983106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  unsigned cnt = 0;
17999c378f705405d37f49795d5e915989de774fe11fTed Kremenek  const ExplodedNode *Root = 0;
18001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18013106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  while (!WS.empty()) {
18029c378f705405d37f49795d5e915989de774fe11fTed Kremenek    const ExplodedNode *Node = WS.front();
18033106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    WS.pop();
18041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18053106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Visited.find(Node) != Visited.end())
18063106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
18071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18083106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    Visited[Node] = cnt++;
18091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Node->pred_empty()) {
18113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      Root = Node;
18123106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
18133106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
18141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1815c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    for (ExplodedNode::const_pred_iterator I=Node->pred_begin(),
18163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek         E=Node->pred_end(); I!=E; ++I)
18173106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      WS.push(*I);
18183106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
18191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1820938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(Root);
18211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Now walk from the root down the BFS path, always taking the successor
18233106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // with the lowest number.
18241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ExplodedNode *Last = 0, *First = 0;
18253106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  NodeBackMap *BM = new NodeBackMap();
1826938332c657390d1e782e0adc03b092993edae962Ted Kremenek  unsigned NodeIndex = 0;
18271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1828c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  for ( const ExplodedNode *N = Root ;;) {
18293106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Lookup the number associated with the current node.
18303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    llvm::DenseMap<const void*,unsigned>::iterator I = Visited.find(N);
1831938332c657390d1e782e0adc03b092993edae962Ted Kremenek    assert(I != Visited.end());
18321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18333106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Create the equivalent node in the new graph with the same state
18343106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // and location.
18359c378f705405d37f49795d5e915989de774fe11fTed Kremenek    ExplodedNode *NewN = GNew->getNode(N->getLocation(), N->getState());
18361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18373106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Store the mapping to the original node.
18383106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    llvm::DenseMap<const void*, const void*>::iterator IMitr=InverseMap.find(N);
18393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    assert(IMitr != InverseMap.end() && "No mapping to original node.");
1840c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    (*BM)[NewN] = (const ExplodedNode*) IMitr->second;
18411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Link up the new node with the previous node.
18433106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Last)
18445fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek      NewN->addPredecessor(Last, *GNew);
18451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    Last = NewN;
18471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18483106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Are we at the final node?
1849938332c657390d1e782e0adc03b092993edae962Ted Kremenek    IndexMapTy::iterator IMI =
1850c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu      IndexMap.find((const ExplodedNode*)(IMitr->second));
1851938332c657390d1e782e0adc03b092993edae962Ted Kremenek    if (IMI != IndexMap.end()) {
18523106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      First = NewN;
1853938332c657390d1e782e0adc03b092993edae962Ted Kremenek      NodeIndex = IMI->second;
18543106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
18553106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
18561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18573106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Find the next successor node.  We choose the node that is marked
18583106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // with the lowest DFS number.
1859c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::const_succ_iterator SI = N->succ_begin();
1860c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu    ExplodedNode::const_succ_iterator SE = N->succ_end();
18613106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    N = 0;
18621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    for (unsigned MinVal = 0; SI != SE; ++SI) {
18641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18653106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      I = Visited.find(*SI);
18661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (I == Visited.end())
18683106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        continue;
18691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18703106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (!N || I->second < MinVal) {
18713106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        N = *SI;
18723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MinVal = I->second;
18733106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
18743106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
18751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1876938332c657390d1e782e0adc03b092993edae962Ted Kremenek    assert(N);
18773106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
18781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1879938332c657390d1e782e0adc03b092993edae962Ted Kremenek  assert(First);
1880938332c657390d1e782e0adc03b092993edae962Ted Kremenek
18813106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  return std::make_pair(std::make_pair(GNew, BM),
18823106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                        std::make_pair(First, NodeIndex));
18833106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
1884d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
18853106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
18863106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek///  and collapses PathDiagosticPieces that are expanded by macros.
188777d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenekstatic void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
18882042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek  typedef std::vector<std::pair<IntrusiveRefCntPtr<PathDiagnosticMacroPiece>,
18892042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek                                SourceLocation> > MacroStackTy;
18901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1891c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  typedef std::vector<IntrusiveRefCntPtr<PathDiagnosticPiece> >
18923106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek          PiecesTy;
18931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18943106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  MacroStackTy MacroStack;
18953106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  PiecesTy Pieces;
18961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
189777d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  for (PathPieces::const_iterator I = path.begin(), E = path.end();
18982042fc1f36d471f437023e8899f0c4fadded2341Ted Kremenek       I!=E; ++I) {
189977d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
190077d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    PathDiagnosticPiece *piece = I->getPtr();
190177d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
190277d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    // Recursively compact calls.
190377d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
190477d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      CompactPathDiagnostic(call->path, SM);
190577d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    }
190677d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek
19073106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Get the location of the PathDiagnosticPiece.
190877d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    const FullSourceLoc Loc = piece->getLocation().asLocation();
19091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19103106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Determine the instantiation location, which is the location we group
19113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // related PathDiagnosticPieces.
19121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    SourceLocation InstantiationLoc = Loc.isMacroID() ?
1913402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth                                      SM.getExpansionLoc(Loc) :
19143106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                      SourceLocation();
19151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19163106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (Loc.isFileID()) {
19173106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.clear();
191877d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      Pieces.push_back(piece);
19193106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
19203106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1921706e3cf2fa7523b5497c52c11a2b6dad2a1ce2acTed Kremenek
19223106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    assert(Loc.isMacroID());
19231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19243106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Is the PathDiagnosticPiece within the same macro group?
19253106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
192677d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek      MacroStack.back().first->subPieces.push_back(piece);
19273106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      continue;
19283106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    }
1929d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
19303106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // We aren't in the same group.  Are we descending into a new macro
19313106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // or are part of an old one?
1932c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith    IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
1933d8c938b0f6b7a7156181be575239e4c6e15a2adbTed Kremenek
19343106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
1935402785357ab053dd53f4fdd858b9630a5e0f8badChandler Carruth                                          SM.getExpansionLoc(Loc) :
19363106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek                                          SourceLocation();
19371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19383106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Walk the entire macro stack.
19393106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    while (!MacroStack.empty()) {
19403106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (InstantiationLoc == MacroStack.back().second) {
19413106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MacroGroup = MacroStack.back().first;
19423106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        break;
19433106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
19441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19453106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (ParentInstantiationLoc == MacroStack.back().second) {
19463106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        MacroGroup = MacroStack.back().first;
19473106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        break;
194861f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek      }
19491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19503106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.pop_back();
19516837faa083bebad39aa342f84c2b450fb6410eafTed Kremenek    }
19521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19533106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) {
19543106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      // Create a new macro group and add it to the stack.
1955590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks      PathDiagnosticMacroPiece *NewGroup =
1956590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks        new PathDiagnosticMacroPiece(
195777d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek          PathDiagnosticLocation::createSingleLocation(piece->getLocation()));
19585a429954aedd8a830a70fcea2cb51561673e4fc3Ted Kremenek
19593106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      if (MacroGroup)
1960802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek        MacroGroup->subPieces.push_back(NewGroup);
19613106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      else {
19623106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        assert(InstantiationLoc.isFileID());
19633106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek        Pieces.push_back(NewGroup);
19643106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      }
19651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19663106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroGroup = NewGroup;
19673106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      MacroStack.push_back(std::make_pair(MacroGroup, InstantiationLoc));
19687dc8664a54f4ede40a5f4adee3f5081a59d7ee1cTed Kremenek    }
19693106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek
19703106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek    // Finally, add the PathDiagnosticPiece to the group.
197177d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    MacroGroup->subPieces.push_back(piece);
19723106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  }
19731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19743106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Now take the pieces and construct a new PathDiagnostic.
197577d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  path.clear();
19761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
197777d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek  for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I)
197877d09441e59d3bced6c3d55505eb3a67a784fe02Ted Kremenek    path.push_back(*I);
197961f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
198061f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
19818347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rosebool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
1982c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek                                           PathDiagnosticConsumer &PC,
1983c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek                                           ArrayRef<BugReport *> &bugReports) {
198440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  assert(!bugReports.empty());
19858347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose
19868347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose  bool HasValid = false;
19875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<const ExplodedNode *, 10> errorNodes;
1988c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  for (ArrayRef<BugReport*>::iterator I = bugReports.begin(),
1989c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek                                      E = bugReports.end(); I != E; ++I) {
19908347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose    if ((*I)->isValid()) {
19918347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose      HasValid = true;
199240406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      errorNodes.push_back((*I)->getErrorNode());
19938347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose    } else {
19948347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose      errorNodes.push_back(0);
19958347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose    }
199640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  }
19971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19988347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose  // If all the reports have been marked invalid, we're done.
19998347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose  if (!HasValid)
20008347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose    return false;
20018347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose
20023106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Construct a new graph that contains only a single path from the error
20031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // node to a root.
200438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu  const std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
2005c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  std::pair<ExplodedNode*, unsigned> >&
200640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    GPair = MakeReportGraph(&getGraph(), errorNodes);
20071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20083106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  // Find the BugReport with the original location.
200940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  assert(GPair.second.second < bugReports.size());
201040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *R = bugReports[GPair.second.second];
20113106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek  assert(R && "No original report found for sliced graph.");
20128347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose  assert(R->isValid() && "Report selected from trimmed graph marked invalid.");
20131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20146f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<ExplodedGraph> ReportGraph(GPair.first.first);
20156f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<NodeBackMap> BackMap(GPair.first.second);
2016c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu  const ExplodedNode *N = GPair.second.first;
20171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Start building the path diagnostic...
2019c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  PathDiagnosticBuilder PDB(*this, R, BackMap.get(), &PC);
20201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20218e6431adab313e283a992698f6fc7afe62420999Anna Zaks  // Register additional node visitors.
202250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  R->addVisitor(new NilReceiverBRVisitor());
202350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  R->addVisitor(new ConditionBRVisitor());
20241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
20253bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  BugReport::VisitorList visitors;
20263bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  unsigned originalReportConfigToken, finalReportConfigToken;
20273bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
20283bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // While generating diagnostics, it's possible the visitors will decide
20293bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // new symbols and regions are interesting, or add other visitors based on
20303bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // the information they find. If they do, we need to regenerate the path
20313bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  // based on our new report configuration.
20323bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  do {
20333bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Get a clean copy of all the visitors.
20343bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    for (BugReport::visitor_iterator I = R->visitor_begin(),
20353bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose                                     E = R->visitor_end(); I != E; ++I)
20363bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose       visitors.push_back((*I)->clone());
20373bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
20383bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Clear out the active path from any previous work.
20393a46f5fd1709f6df03bbb8b0abf84052dc0f39ffJordan Rose    PD.resetPath();
20403bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    originalReportConfigToken = R->getConfigurationChangeToken();
20413bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
20423bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Generate the very last diagnostic piece - the piece is visible before
20433bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // the trace is expanded.
2044d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose    if (PDB.getGenerationScheme() != PathDiagnosticConsumer::None) {
2045d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      PathDiagnosticPiece *LastPiece = 0;
2046d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
2047d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose           I != E; ++I) {
2048d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose        if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
2049d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose          assert (!LastPiece &&
2050d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose                  "There can only be one final piece in a diagnostic.");
2051d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose          LastPiece = Piece;
2052d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose        }
20533bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose      }
2054d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      if (!LastPiece)
2055d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose        LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
2056d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      if (LastPiece)
2057d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose        PD.setEndOfPath(LastPiece);
2058d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      else
2059d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose        return false;
206023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks    }
206123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
20623bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    switch (PDB.getGenerationScheme()) {
2063ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    case PathDiagnosticConsumer::Extensive:
20648347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose      if (!GenerateExtensivePathDiagnostic(PD, PDB, N, visitors)) {
20658347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose        assert(!R->isValid() && "Failed on valid report");
20668347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose        // Try again. We'll filter out the bad report when we trim the graph.
20678347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose        // FIXME: It would be more efficient to use the same intermediate
20688347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose        // trimmed graph, and just repeat the shortest-path search.
20698347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose        return generatePathDiagnostic(PD, PC, bugReports);
20708347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose      }
20715fb5dfb6646464db3cd6d54a6332375c8fe36b75Ted Kremenek      break;
2072ef3643fbbbf66247c5e205497fae0f46e240c143David Blaikie    case PathDiagnosticConsumer::Minimal:
20738347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose      if (!GenerateMinimalPathDiagnostic(PD, PDB, N, visitors)) {
20748347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose        assert(!R->isValid() && "Failed on valid report");
20758347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose        // Try again. We'll filter out the bad report when we trim the graph.
20768347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose        return generatePathDiagnostic(PD, PC, bugReports);
20778347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose      }
20783106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek      break;
2079c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    case PathDiagnosticConsumer::None:
2080d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      if (!GenerateVisitorsOnlyPathDiagnostic(PD, PDB, N, visitors)) {
2081d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose        assert(!R->isValid() && "Failed on valid report");
2082d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose        // Try again. We'll filter out the bad report when we trim the graph.
2083d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose        return generatePathDiagnostic(PD, PC, bugReports);
2084d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      }
2085d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      break;
20863bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    }
20873bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
20883bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Clean up the visitors we used.
20893bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    llvm::DeleteContainerPointers(visitors);
20903bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
20913bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    // Did anything change while generating this path?
20923bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose    finalReportConfigToken = R->getConfigurationChangeToken();
20933bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose  } while(finalReportConfigToken != originalReportConfigToken);
20943bc75ca0a636efdc93471c9b6bad43085a22bf3aJordy Rose
2095c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  // Finally, prune the diagnostic path of uninteresting stuff.
2096b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  if (!PD.path.empty()) {
2097b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    // Remove messages that are basically the same.
20983800165e56107df7430520aa98afdf7065db2dd2Ted Kremenek    removeRedundantMsgs(PD.getMutablePieces());
2099b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
2100b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    if (R->shouldPrunePath()) {
2101b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces(),
2102b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek                                                        R);
2103b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      assert(hasSomethingInteresting);
2104b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      (void) hasSomethingInteresting;
2105b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    }
2106ed7948b55fa4b2505f240cc5287137f451172b4cTed Kremenek  }
21078347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose
21088347d3d45e6f128bba19821f0d2f54cadd4d49bbJordan Rose  return true;
21093106198188ac6eb2753f1764d5c28376b0b76351Ted Kremenek}
21101aa44c7c9198796085b77c6bdd7c90030845a688Ted Kremenek
2111cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekvoid BugReporter::Register(BugType *BT) {
21123baf672378f105602d2b12f03f00277ae1936fe9Ted Kremenek  BugTypes = F.add(BugTypes, BT);
211376d90c8bf83d071fd1bdbffa6d9f2af87c6bb7b5Ted Kremenek}
211476d90c8bf83d071fd1bdbffa6d9f2af87c6bb7b5Ted Kremenek
2115785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rosevoid BugReporter::emitReport(BugReport* R) {
2116cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // Compute the bug report's hash to determine its equivalence class.
2117cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  llvm::FoldingSetNodeID ID;
2118cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  R->Profile(ID);
21191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Lookup the equivance class.  If there isn't one, create it.
2121cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  BugType& BT = R->getBugType();
2122cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  Register(&BT);
2123cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  void *InsertPos;
2124404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos);
21251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2126cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  if (!EQ) {
2127cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    EQ = new BugReportEquivClass(R);
2128404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    EQClasses.InsertNode(EQ, InsertPos);
21293b030a28cda2b953758507769c1d436bec5ec45eAnna Zaks    EQClassesVector.push_back(EQ);
2130cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  }
2131cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  else
2132cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek    EQ->AddReport(R);
213361f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
213461f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek
213506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
213606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek//===----------------------------------------------------------------------===//
213706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek// Emitting reports in equivalence classes.
213806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek//===----------------------------------------------------------------------===//
213906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
214006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremeneknamespace {
2141ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnamstruct FRIEC_WLItem {
214206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  const ExplodedNode *N;
214306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  ExplodedNode::const_succ_iterator I, E;
214406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
214506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  FRIEC_WLItem(const ExplodedNode *n)
214606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  : N(n), I(N->succ_begin()), E(N->succ_end()) {}
214706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek};
214806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek}
214906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
215061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenekstatic BugReport *
215161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted KremenekFindReportInEquivalenceClass(BugReportEquivClass& EQ,
21525f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                             SmallVectorImpl<BugReport*> &bugReports) {
215361f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
215406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
215506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  assert(I != E);
21564a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer  BugType& BT = I->getBugType();
215761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
215840406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // If we don't need to suppress any of the nodes because they are
215940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // post-dominated by a sink, simply add all the nodes in the equivalence class
216040406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  // to 'Nodes'.  Any of the reports will serve as a "representative" report.
216161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  if (!BT.isSuppressOnSink()) {
21624a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer    BugReport *R = I;
216361f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) {
21649c378f705405d37f49795d5e915989de774fe11fTed Kremenek      const ExplodedNode *N = I->getErrorNode();
216561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      if (N) {
21664a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer        R = I;
216740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek        bugReports.push_back(R);
216861f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      }
216961f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    }
217006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    return R;
217161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  }
217261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
217306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // For bug reports that should be suppressed when all paths are post-dominated
217406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // by a sink node, iterate through the reports in the equivalence class
217506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // until we find one that isn't post-dominated (if one exists).  We use a
217606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // DFS traversal of the ExplodedGraph to find a non-sink node.  We could write
217706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // this as a recursive function, but we don't want to risk blowing out the
217806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  // stack for very long paths.
217940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *exampleReport = 0;
218061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
218106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  for (; I != E; ++I) {
21824a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer    const ExplodedNode *errorNode = I->getErrorNode();
218306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
218440406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (!errorNode)
218506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      continue;
218640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (errorNode->isSink()) {
2187b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable(
218806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek           "BugType::isSuppressSink() should not be 'true' for sink end nodes");
218906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    }
219061f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    // No successors?  By definition this nodes isn't post-dominated by a sink.
219140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    if (errorNode->succ_empty()) {
21924a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer      bugReports.push_back(I);
219340406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek      if (!exampleReport)
21944a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer        exampleReport = I;
219561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      continue;
219661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek    }
219761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
219806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    // At this point we know that 'N' is not a sink and it has at least one
219906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    // successor.  Use a DFS worklist to find a non-sink end-of-path node.
220006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    typedef FRIEC_WLItem WLItem;
22015f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    typedef SmallVector<WLItem, 10> DFSWorkList;
220206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    llvm::DenseMap<const ExplodedNode *, unsigned> Visited;
220306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
220406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    DFSWorkList WL;
220540406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    WL.push_back(errorNode);
220640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek    Visited[errorNode] = 1;
220706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
220806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    while (!WL.empty()) {
220906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      WLItem &WI = WL.back();
221006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      assert(!WI.N->succ_empty());
221106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
221206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      for (; WI.I != WI.E; ++WI.I) {
221306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        const ExplodedNode *Succ = *WI.I;
221406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // End-of-path node?
221506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        if (Succ->succ_empty()) {
221661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          // If we found an end-of-path node that is not a sink.
221761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          if (!Succ->isSink()) {
22184a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer            bugReports.push_back(I);
221940406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek            if (!exampleReport)
22204a5f724538cbc275370c9504e8169ce92503256cBenjamin Kramer              exampleReport = I;
222161f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek            WL.clear();
222261f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek            break;
222361f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek          }
222406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          // Found a sink?  Continue on to the next successor.
222506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          continue;
222606c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        }
222706c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // Mark the successor as visited.  If it hasn't been explored,
222806c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        // enqueue it to the DFS worklist.
222906c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        unsigned &mark = Visited[Succ];
223006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        if (!mark) {
223106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          mark = 1;
223206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          WL.push_back(Succ);
223306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek          break;
223406c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        }
223506c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek      }
223661f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek
223761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      // The worklist may have been cleared at this point.  First
223861f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      // check if it is empty before checking the last item.
223961f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek      if (!WL.empty() && &WL.back() == &WI)
224006c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek        WL.pop_back();
224106c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek    }
224206c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek  }
224306c9cb4d1a29e708f51bce9f7ee5acbe1c3761c3Ted Kremenek
224461f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  // ExampleReport will be NULL if all the nodes in the equivalence class
224561f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek  // were post-dominated by sinks.
224640406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  return exampleReport;
224761f52bd3c524268e25b48a1ed3730aedd6cc8374Ted Kremenek}
2248e0a58073b76fc016325a35152533b8468df2bf4aTed Kremenek
2249cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekvoid BugReporter::FlushReport(BugReportEquivClass& EQ) {
22505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  SmallVector<BugReport*, 10> bugReports;
225140406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugReport *exampleReport = FindReportInEquivalenceClass(EQ, bugReports);
2252c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  if (exampleReport) {
2253c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    const PathDiagnosticConsumers &C = getPathDiagnosticConsumers();
2254c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    for (PathDiagnosticConsumers::const_iterator I=C.begin(),
2255c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek                                                 E=C.end(); I != E; ++I) {
2256c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek      FlushReport(exampleReport, **I, bugReports);
2257c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    }
2258c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  }
2259c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek}
2260c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek
2261c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenekvoid BugReporter::FlushReport(BugReport *exampleReport,
2262c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek                              PathDiagnosticConsumer &PD,
2263c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek                              ArrayRef<BugReport*> bugReports) {
22641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2265cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  // FIXME: Make sure we use the 'R' for the path that was actually used.
22661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  // Probably doesn't make a difference in practice.
226740406fe63df2b932d6e9fd021f77f097f9d33afbTed Kremenek  BugType& BT = exampleReport->getBugType();
22681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
22696f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  OwningPtr<PathDiagnostic>
227007189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek    D(new PathDiagnostic(exampleReport->getDeclWithIssue(),
227107189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek                         exampleReport->getBugType().getName(),
22723a46f5fd1709f6df03bbb8b0abf84052dc0f39ffJordan Rose                         exampleReport->getDescription(),
22733a46f5fd1709f6df03bbb8b0abf84052dc0f39ffJordan Rose                         exampleReport->getShortDescription(/*Fallback=*/false),
2274d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek                         BT.getCategory()));
2275d49967f8764135ae65658e354b6d38e3637c9de3Ted Kremenek
2276c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  // Generate the full path diagnostic, using the generation scheme
2277d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  // specified by the PathDiagnosticConsumer. Note that we have to generate
2278d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  // path diagnostics even for consumers which do not support paths, because
2279d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  // the BugReporterVisitors may mark this bug as a false positive.
2280d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose  if (!bugReports.empty())
2281d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose    if (!generatePathDiagnostic(*D.get(), PD, bugReports))
2282d632d6fc606f0be438c3b6fe5c43f1b3f5db98b1Jordan Rose      return;
22833148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek
2284c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  // If the path is empty, generate a single step path with the location
2285c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  // of the issue.
2286802e02463b880f53a6e645bde78cc412481ce9e0Ted Kremenek  if (D->path.empty()) {
2287c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    PathDiagnosticLocation L = exampleReport->getLocation(getSourceManager());
2288c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    PathDiagnosticPiece *piece =
2289c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek      new PathDiagnosticEventPiece(L, exampleReport->getDescription());
2290c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    BugReport::ranges_iterator Beg, End;
2291c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    llvm::tie(Beg, End) = exampleReport->getRanges();
229207189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek    for ( ; Beg != End; ++Beg)
229307189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek      piece->addRange(*Beg);
22943a46f5fd1709f6df03bbb8b0abf84052dc0f39ffJordan Rose    D->setEndOfPath(piece);
22953148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek  }
22961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2297c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  // Get the meta data.
2298c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  const BugReport::ExtraTextList &Meta = exampleReport->getExtraText();
2299c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  for (BugReport::ExtraTextList::const_iterator i = Meta.begin(),
2300c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek                                                e = Meta.end(); i != e; ++i) {
2301c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek    D->addMeta(*i);
2302c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  }
2303c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek
2304c4bac8e376b98d633bb00ee5f510d5e58449753cTed Kremenek  PD.HandlePathDiagnostic(D.take());
230561f3e058056ab519d249aa67e3d52b0ead57c63eTed Kremenek}
230657202071e477530e9348bc76671ee369b2399b92Ted Kremenek
230707189521a15d9c088216b943649cb9fe231cbb57Ted Kremenekvoid BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
230807189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek                                  StringRef name,
23095f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                  StringRef category,
2310590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks                                  StringRef str, PathDiagnosticLocation Loc,
23118c036c7f77d69f96df49219ed0bdbade200d52ebTed Kremenek                                  SourceRange* RBeg, unsigned NumRanges) {
23121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2313404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  // 'BT' is owned by BugReporter.
2314404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugType *BT = getBugTypeForName(name, category);
2315590dd8e0959d8df5621827768987c4792b74fc06Anna Zaks  BugReport *R = new BugReport(*BT, str, Loc);
231607189521a15d9c088216b943649cb9fe231cbb57Ted Kremenek  R->setDeclWithIssue(DeclWithIssue);
2317cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek  for ( ; NumRanges > 0 ; --NumRanges, ++RBeg) R->addRange(*RBeg);
2318785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose  emitReport(R);
2319cabe66811fe43835b8c5a0854552768fc53261e3Ted Kremenek}
2320404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis
23215f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerBugType *BugReporter::getBugTypeForName(StringRef name,
23225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                        StringRef category) {
2323f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<136> fullDesc;
2324404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  llvm::raw_svector_ostream(fullDesc) << name << ":" << category;
2325404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  llvm::StringMapEntry<BugType *> &
2326404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis      entry = StrBugTypes.GetOrCreateValue(fullDesc);
2327404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  BugType *BT = entry.getValue();
2328404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  if (!BT) {
2329404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    BT = new BugType(name, category);
2330404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis    entry.setValue(BT);
2331404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  }
2332404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis  return BT;
2333404fc3ad6bd844bf8ce70cbf9974ab297704a122Argyrios Kyrtzidis}
2334