1 // BugReporter.cpp - Generate PathDiagnostics for Bugs ------------*- C++ -*--//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines BugReporter, a utility class for generating
11 //  PathDiagnostics.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
16 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
17 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
18 #include "clang/AST/ASTContext.h"
19 #include "clang/Analysis/CFG.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/AST/Expr.h"
22 #include "clang/AST/ParentMap.h"
23 #include "clang/AST/StmtObjC.h"
24 #include "clang/Basic/SourceManager.h"
25 #include "clang/Analysis/ProgramPoint.h"
26 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include "llvm/ADT/DenseMap.h"
29 #include "llvm/ADT/SmallString.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/OwningPtr.h"
32 #include "llvm/ADT/IntrusiveRefCntPtr.h"
33 #include <queue>
34 
35 using namespace clang;
36 using namespace ento;
37 
38 BugReporterVisitor::~BugReporterVisitor() {}
39 
40 void BugReporterContext::anchor() {}
41 
42 //===----------------------------------------------------------------------===//
43 // Helper routines for walking the ExplodedGraph and fetching statements.
44 //===----------------------------------------------------------------------===//
45 
46 static inline const Stmt *GetStmt(const ProgramPoint &P) {
47   if (const StmtPoint* SP = dyn_cast<StmtPoint>(&P))
48     return SP->getStmt();
49   else if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
50     return BE->getSrc()->getTerminator();
51 
52   return 0;
53 }
54 
55 static inline const ExplodedNode*
56 GetPredecessorNode(const ExplodedNode *N) {
57   return N->pred_empty() ? NULL : *(N->pred_begin());
58 }
59 
60 static inline const ExplodedNode*
61 GetSuccessorNode(const ExplodedNode *N) {
62   return N->succ_empty() ? NULL : *(N->succ_begin());
63 }
64 
65 static const Stmt *GetPreviousStmt(const ExplodedNode *N) {
66   for (N = GetPredecessorNode(N); N; N = GetPredecessorNode(N))
67     if (const Stmt *S = GetStmt(N->getLocation()))
68       return S;
69 
70   return 0;
71 }
72 
73 static const Stmt *GetNextStmt(const ExplodedNode *N) {
74   for (N = GetSuccessorNode(N); N; N = GetSuccessorNode(N))
75     if (const Stmt *S = GetStmt(N->getLocation())) {
76       // Check if the statement is '?' or '&&'/'||'.  These are "merges",
77       // not actual statement points.
78       switch (S->getStmtClass()) {
79         case Stmt::ChooseExprClass:
80         case Stmt::BinaryConditionalOperatorClass: continue;
81         case Stmt::ConditionalOperatorClass: continue;
82         case Stmt::BinaryOperatorClass: {
83           BinaryOperatorKind Op = cast<BinaryOperator>(S)->getOpcode();
84           if (Op == BO_LAnd || Op == BO_LOr)
85             continue;
86           break;
87         }
88         default:
89           break;
90       }
91       return S;
92     }
93 
94   return 0;
95 }
96 
97 static inline const Stmt*
98 GetCurrentOrPreviousStmt(const ExplodedNode *N) {
99   if (const Stmt *S = GetStmt(N->getLocation()))
100     return S;
101 
102   return GetPreviousStmt(N);
103 }
104 
105 static inline const Stmt*
106 GetCurrentOrNextStmt(const ExplodedNode *N) {
107   if (const Stmt *S = GetStmt(N->getLocation()))
108     return S;
109 
110   return GetNextStmt(N);
111 }
112 
113 //===----------------------------------------------------------------------===//
114 // Diagnostic cleanup.
115 //===----------------------------------------------------------------------===//
116 
117 /// Recursively scan through a path and prune out calls and macros pieces
118 /// that aren't needed.  Return true if afterwards the path contains
119 /// "interesting stuff" which means it should be pruned from the parent path.
120 static bool RemoveUneededCalls(PathPieces &pieces) {
121   bool containsSomethingInteresting = false;
122   const unsigned N = pieces.size();
123 
124   for (unsigned i = 0 ; i < N ; ++i) {
125     // Remove the front piece from the path.  If it is still something we
126     // want to keep once we are done, we will push it back on the end.
127     IntrusiveRefCntPtr<PathDiagnosticPiece> piece(pieces.front());
128     pieces.pop_front();
129 
130     switch (piece->getKind()) {
131       case PathDiagnosticPiece::Call: {
132         PathDiagnosticCallPiece *call = cast<PathDiagnosticCallPiece>(piece);
133         // Recursively clean out the subclass.  Keep this call around if
134         // it contains any informative diagnostics.
135         if (!RemoveUneededCalls(call->path))
136           continue;
137         containsSomethingInteresting = true;
138         break;
139       }
140       case PathDiagnosticPiece::Macro: {
141         PathDiagnosticMacroPiece *macro = cast<PathDiagnosticMacroPiece>(piece);
142         if (!RemoveUneededCalls(macro->subPieces))
143           continue;
144         containsSomethingInteresting = true;
145         break;
146       }
147       case PathDiagnosticPiece::Event: {
148         PathDiagnosticEventPiece *event = cast<PathDiagnosticEventPiece>(piece);
149         // We never throw away an event, but we do throw it away wholesale
150         // as part of a path if we throw the entire path away.
151         if (event->isPrunable())
152           continue;
153         containsSomethingInteresting = true;
154         break;
155       }
156       case PathDiagnosticPiece::ControlFlow:
157         break;
158     }
159 
160     pieces.push_back(piece);
161   }
162 
163   return containsSomethingInteresting;
164 }
165 
166 //===----------------------------------------------------------------------===//
167 // PathDiagnosticBuilder and its associated routines and helper objects.
168 //===----------------------------------------------------------------------===//
169 
170 typedef llvm::DenseMap<const ExplodedNode*,
171 const ExplodedNode*> NodeBackMap;
172 
173 namespace {
174 class NodeMapClosure : public BugReport::NodeResolver {
175   NodeBackMap& M;
176 public:
177   NodeMapClosure(NodeBackMap *m) : M(*m) {}
178   ~NodeMapClosure() {}
179 
180   const ExplodedNode *getOriginalNode(const ExplodedNode *N) {
181     NodeBackMap::iterator I = M.find(N);
182     return I == M.end() ? 0 : I->second;
183   }
184 };
185 
186 class PathDiagnosticBuilder : public BugReporterContext {
187   BugReport *R;
188   PathDiagnosticConsumer *PDC;
189   OwningPtr<ParentMap> PM;
190   NodeMapClosure NMC;
191 public:
192   const LocationContext *LC;
193 
194   PathDiagnosticBuilder(GRBugReporter &br,
195                         BugReport *r, NodeBackMap *Backmap,
196                         PathDiagnosticConsumer *pdc)
197     : BugReporterContext(br),
198       R(r), PDC(pdc), NMC(Backmap), LC(r->getErrorNode()->getLocationContext())
199   {}
200 
201   PathDiagnosticLocation ExecutionContinues(const ExplodedNode *N);
202 
203   PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream &os,
204                                             const ExplodedNode *N);
205 
206   BugReport *getBugReport() { return R; }
207 
208   Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); }
209 
210   ParentMap& getParentMap() { return LC->getParentMap(); }
211 
212   const Stmt *getParent(const Stmt *S) {
213     return getParentMap().getParent(S);
214   }
215 
216   virtual NodeMapClosure& getNodeResolver() { return NMC; }
217 
218   PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S);
219 
220   PathDiagnosticConsumer::PathGenerationScheme getGenerationScheme() const {
221     return PDC ? PDC->getGenerationScheme() : PathDiagnosticConsumer::Extensive;
222   }
223 
224   bool supportsLogicalOpControlFlow() const {
225     return PDC ? PDC->supportsLogicalOpControlFlow() : true;
226   }
227 };
228 } // end anonymous namespace
229 
230 PathDiagnosticLocation
231 PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode *N) {
232   if (const Stmt *S = GetNextStmt(N))
233     return PathDiagnosticLocation(S, getSourceManager(), LC);
234 
235   return PathDiagnosticLocation::createDeclEnd(N->getLocationContext(),
236                                                getSourceManager());
237 }
238 
239 PathDiagnosticLocation
240 PathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream &os,
241                                           const ExplodedNode *N) {
242 
243   // Slow, but probably doesn't matter.
244   if (os.str().empty())
245     os << ' ';
246 
247   const PathDiagnosticLocation &Loc = ExecutionContinues(N);
248 
249   if (Loc.asStmt())
250     os << "Execution continues on line "
251        << getSourceManager().getExpansionLineNumber(Loc.asLocation())
252        << '.';
253   else {
254     os << "Execution jumps to the end of the ";
255     const Decl *D = N->getLocationContext()->getDecl();
256     if (isa<ObjCMethodDecl>(D))
257       os << "method";
258     else if (isa<FunctionDecl>(D))
259       os << "function";
260     else {
261       assert(isa<BlockDecl>(D));
262       os << "anonymous block";
263     }
264     os << '.';
265   }
266 
267   return Loc;
268 }
269 
270 static bool IsNested(const Stmt *S, ParentMap &PM) {
271   if (isa<Expr>(S) && PM.isConsumedExpr(cast<Expr>(S)))
272     return true;
273 
274   const Stmt *Parent = PM.getParentIgnoreParens(S);
275 
276   if (Parent)
277     switch (Parent->getStmtClass()) {
278       case Stmt::ForStmtClass:
279       case Stmt::DoStmtClass:
280       case Stmt::WhileStmtClass:
281         return true;
282       default:
283         break;
284     }
285 
286   return false;
287 }
288 
289 PathDiagnosticLocation
290 PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
291   assert(S && "Null Stmt *passed to getEnclosingStmtLocation");
292   ParentMap &P = getParentMap();
293   SourceManager &SMgr = getSourceManager();
294 
295   while (IsNested(S, P)) {
296     const Stmt *Parent = P.getParentIgnoreParens(S);
297 
298     if (!Parent)
299       break;
300 
301     switch (Parent->getStmtClass()) {
302       case Stmt::BinaryOperatorClass: {
303         const BinaryOperator *B = cast<BinaryOperator>(Parent);
304         if (B->isLogicalOp())
305           return PathDiagnosticLocation(S, SMgr, LC);
306         break;
307       }
308       case Stmt::CompoundStmtClass:
309       case Stmt::StmtExprClass:
310         return PathDiagnosticLocation(S, SMgr, LC);
311       case Stmt::ChooseExprClass:
312         // Similar to '?' if we are referring to condition, just have the edge
313         // point to the entire choose expression.
314         if (cast<ChooseExpr>(Parent)->getCond() == S)
315           return PathDiagnosticLocation(Parent, SMgr, LC);
316         else
317           return PathDiagnosticLocation(S, SMgr, LC);
318       case Stmt::BinaryConditionalOperatorClass:
319       case Stmt::ConditionalOperatorClass:
320         // For '?', if we are referring to condition, just have the edge point
321         // to the entire '?' expression.
322         if (cast<AbstractConditionalOperator>(Parent)->getCond() == S)
323           return PathDiagnosticLocation(Parent, SMgr, LC);
324         else
325           return PathDiagnosticLocation(S, SMgr, LC);
326       case Stmt::DoStmtClass:
327           return PathDiagnosticLocation(S, SMgr, LC);
328       case Stmt::ForStmtClass:
329         if (cast<ForStmt>(Parent)->getBody() == S)
330           return PathDiagnosticLocation(S, SMgr, LC);
331         break;
332       case Stmt::IfStmtClass:
333         if (cast<IfStmt>(Parent)->getCond() != S)
334           return PathDiagnosticLocation(S, SMgr, LC);
335         break;
336       case Stmt::ObjCForCollectionStmtClass:
337         if (cast<ObjCForCollectionStmt>(Parent)->getBody() == S)
338           return PathDiagnosticLocation(S, SMgr, LC);
339         break;
340       case Stmt::WhileStmtClass:
341         if (cast<WhileStmt>(Parent)->getCond() != S)
342           return PathDiagnosticLocation(S, SMgr, LC);
343         break;
344       default:
345         break;
346     }
347 
348     S = Parent;
349   }
350 
351   assert(S && "Cannot have null Stmt for PathDiagnosticLocation");
352 
353   // Special case: DeclStmts can appear in for statement declarations, in which
354   //  case the ForStmt is the context.
355   if (isa<DeclStmt>(S)) {
356     if (const Stmt *Parent = P.getParent(S)) {
357       switch (Parent->getStmtClass()) {
358         case Stmt::ForStmtClass:
359         case Stmt::ObjCForCollectionStmtClass:
360           return PathDiagnosticLocation(Parent, SMgr, LC);
361         default:
362           break;
363       }
364     }
365   }
366   else if (isa<BinaryOperator>(S)) {
367     // Special case: the binary operator represents the initialization
368     // code in a for statement (this can happen when the variable being
369     // initialized is an old variable.
370     if (const ForStmt *FS =
371           dyn_cast_or_null<ForStmt>(P.getParentIgnoreParens(S))) {
372       if (FS->getInit() == S)
373         return PathDiagnosticLocation(FS, SMgr, LC);
374     }
375   }
376 
377   return PathDiagnosticLocation(S, SMgr, LC);
378 }
379 
380 //===----------------------------------------------------------------------===//
381 // "Minimal" path diagnostic generation algorithm.
382 //===----------------------------------------------------------------------===//
383 
384 static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
385 
386 static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
387                                           PathDiagnosticBuilder &PDB,
388                                           const ExplodedNode *N) {
389 
390   SourceManager& SMgr = PDB.getSourceManager();
391   const LocationContext *LC = PDB.LC;
392   const ExplodedNode *NextNode = N->pred_empty()
393                                         ? NULL : *(N->pred_begin());
394   while (NextNode) {
395     N = NextNode;
396     PDB.LC = N->getLocationContext();
397     NextNode = GetPredecessorNode(N);
398 
399     ProgramPoint P = N->getLocation();
400 
401     if (const CallExit *CE = dyn_cast<CallExit>(&P)) {
402       PathDiagnosticCallPiece *C =
403         PathDiagnosticCallPiece::construct(N, *CE, SMgr);
404       PD.getActivePath().push_front(C);
405       PD.pushActivePath(&C->path);
406       continue;
407     }
408 
409     if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
410       PD.popActivePath();
411       // The current active path should never be empty.  Either we
412       // just added a bunch of stuff to the top-level path, or
413       // we have a previous CallExit.  If the front of the active
414       // path is not a PathDiagnosticCallPiece, it means that the
415       // path terminated within a function call.  We must then take the
416       // current contents of the active path and place it within
417       // a new PathDiagnosticCallPiece.
418       assert(!PD.getActivePath().empty());
419       PathDiagnosticCallPiece *C =
420         dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
421       if (!C)
422         C = PathDiagnosticCallPiece::construct(PD.getActivePath());
423       C->setCallee(*CE, SMgr);
424       continue;
425     }
426 
427     if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
428       const CFGBlock *Src = BE->getSrc();
429       const CFGBlock *Dst = BE->getDst();
430       const Stmt *T = Src->getTerminator();
431 
432       if (!T)
433         continue;
434 
435       PathDiagnosticLocation Start =
436         PathDiagnosticLocation::createBegin(T, SMgr,
437                                                 N->getLocationContext());
438 
439       switch (T->getStmtClass()) {
440         default:
441           break;
442 
443         case Stmt::GotoStmtClass:
444         case Stmt::IndirectGotoStmtClass: {
445           const Stmt *S = GetNextStmt(N);
446 
447           if (!S)
448             continue;
449 
450           std::string sbuf;
451           llvm::raw_string_ostream os(sbuf);
452           const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S);
453 
454           os << "Control jumps to line "
455           << End.asLocation().getExpansionLineNumber();
456           PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
457                                                                 os.str()));
458           break;
459         }
460 
461         case Stmt::SwitchStmtClass: {
462           // Figure out what case arm we took.
463           std::string sbuf;
464           llvm::raw_string_ostream os(sbuf);
465 
466           if (const Stmt *S = Dst->getLabel()) {
467             PathDiagnosticLocation End(S, SMgr, LC);
468 
469             switch (S->getStmtClass()) {
470               default:
471                 os << "No cases match in the switch statement. "
472                 "Control jumps to line "
473                 << End.asLocation().getExpansionLineNumber();
474                 break;
475               case Stmt::DefaultStmtClass:
476                 os << "Control jumps to the 'default' case at line "
477                 << End.asLocation().getExpansionLineNumber();
478                 break;
479 
480               case Stmt::CaseStmtClass: {
481                 os << "Control jumps to 'case ";
482                 const CaseStmt *Case = cast<CaseStmt>(S);
483                 const Expr *LHS = Case->getLHS()->IgnoreParenCasts();
484 
485                 // Determine if it is an enum.
486                 bool GetRawInt = true;
487 
488                 if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS)) {
489                   // FIXME: Maybe this should be an assertion.  Are there cases
490                   // were it is not an EnumConstantDecl?
491                   const EnumConstantDecl *D =
492                     dyn_cast<EnumConstantDecl>(DR->getDecl());
493 
494                   if (D) {
495                     GetRawInt = false;
496                     os << *D;
497                   }
498                 }
499 
500                 if (GetRawInt)
501                   os << LHS->EvaluateKnownConstInt(PDB.getASTContext());
502 
503                 os << ":'  at line "
504                 << End.asLocation().getExpansionLineNumber();
505                 break;
506               }
507             }
508             PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
509                                                              os.str()));
510           }
511           else {
512             os << "'Default' branch taken. ";
513             const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N);
514             PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
515                                                              os.str()));
516           }
517 
518           break;
519         }
520 
521         case Stmt::BreakStmtClass:
522         case Stmt::ContinueStmtClass: {
523           std::string sbuf;
524           llvm::raw_string_ostream os(sbuf);
525           PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
526           PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
527                                                            os.str()));
528           break;
529         }
530 
531           // Determine control-flow for ternary '?'.
532         case Stmt::BinaryConditionalOperatorClass:
533         case Stmt::ConditionalOperatorClass: {
534           std::string sbuf;
535           llvm::raw_string_ostream os(sbuf);
536           os << "'?' condition is ";
537 
538           if (*(Src->succ_begin()+1) == Dst)
539             os << "false";
540           else
541             os << "true";
542 
543           PathDiagnosticLocation End = PDB.ExecutionContinues(N);
544 
545           if (const Stmt *S = End.asStmt())
546             End = PDB.getEnclosingStmtLocation(S);
547 
548           PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
549                                                            os.str()));
550           break;
551         }
552 
553           // Determine control-flow for short-circuited '&&' and '||'.
554         case Stmt::BinaryOperatorClass: {
555           if (!PDB.supportsLogicalOpControlFlow())
556             break;
557 
558           const BinaryOperator *B = cast<BinaryOperator>(T);
559           std::string sbuf;
560           llvm::raw_string_ostream os(sbuf);
561           os << "Left side of '";
562 
563           if (B->getOpcode() == BO_LAnd) {
564             os << "&&" << "' is ";
565 
566             if (*(Src->succ_begin()+1) == Dst) {
567               os << "false";
568               PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
569               PathDiagnosticLocation Start =
570                 PathDiagnosticLocation::createOperatorLoc(B, SMgr);
571               PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
572                                                                os.str()));
573             }
574             else {
575               os << "true";
576               PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
577               PathDiagnosticLocation End = PDB.ExecutionContinues(N);
578               PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
579                                                                os.str()));
580             }
581           }
582           else {
583             assert(B->getOpcode() == BO_LOr);
584             os << "||" << "' is ";
585 
586             if (*(Src->succ_begin()+1) == Dst) {
587               os << "false";
588               PathDiagnosticLocation Start(B->getLHS(), SMgr, LC);
589               PathDiagnosticLocation End = PDB.ExecutionContinues(N);
590               PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
591                                                                os.str()));
592             }
593             else {
594               os << "true";
595               PathDiagnosticLocation End(B->getLHS(), SMgr, LC);
596               PathDiagnosticLocation Start =
597                 PathDiagnosticLocation::createOperatorLoc(B, SMgr);
598               PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
599                                                                os.str()));
600             }
601           }
602 
603           break;
604         }
605 
606         case Stmt::DoStmtClass:  {
607           if (*(Src->succ_begin()) == Dst) {
608             std::string sbuf;
609             llvm::raw_string_ostream os(sbuf);
610 
611             os << "Loop condition is true. ";
612             PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
613 
614             if (const Stmt *S = End.asStmt())
615               End = PDB.getEnclosingStmtLocation(S);
616 
617             PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
618                                                              os.str()));
619           }
620           else {
621             PathDiagnosticLocation End = PDB.ExecutionContinues(N);
622 
623             if (const Stmt *S = End.asStmt())
624               End = PDB.getEnclosingStmtLocation(S);
625 
626             PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
627                               "Loop condition is false.  Exiting loop"));
628           }
629 
630           break;
631         }
632 
633         case Stmt::WhileStmtClass:
634         case Stmt::ForStmtClass: {
635           if (*(Src->succ_begin()+1) == Dst) {
636             std::string sbuf;
637             llvm::raw_string_ostream os(sbuf);
638 
639             os << "Loop condition is false. ";
640             PathDiagnosticLocation End = PDB.ExecutionContinues(os, N);
641             if (const Stmt *S = End.asStmt())
642               End = PDB.getEnclosingStmtLocation(S);
643 
644             PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
645                                                              os.str()));
646           }
647           else {
648             PathDiagnosticLocation End = PDB.ExecutionContinues(N);
649             if (const Stmt *S = End.asStmt())
650               End = PDB.getEnclosingStmtLocation(S);
651 
652             PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
653                             "Loop condition is true.  Entering loop body"));
654           }
655 
656           break;
657         }
658 
659         case Stmt::IfStmtClass: {
660           PathDiagnosticLocation End = PDB.ExecutionContinues(N);
661 
662           if (const Stmt *S = End.asStmt())
663             End = PDB.getEnclosingStmtLocation(S);
664 
665           if (*(Src->succ_begin()+1) == Dst)
666             PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
667                                                         "Taking false branch"));
668           else
669             PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(Start, End,
670                                                          "Taking true branch"));
671 
672           break;
673         }
674       }
675     }
676 
677     if (NextNode) {
678       // Add diagnostic pieces from custom visitors.
679       BugReport *R = PDB.getBugReport();
680       for (BugReport::visitor_iterator I = R->visitor_begin(),
681            E = R->visitor_end(); I!=E; ++I) {
682         if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R))
683           PD.getActivePath().push_front(p);
684       }
685     }
686   }
687 
688   // After constructing the full PathDiagnostic, do a pass over it to compact
689   // PathDiagnosticPieces that occur within a macro.
690   CompactPathDiagnostic(PD.getMutablePieces(), PDB.getSourceManager());
691 }
692 
693 //===----------------------------------------------------------------------===//
694 // "Extensive" PathDiagnostic generation.
695 //===----------------------------------------------------------------------===//
696 
697 static bool IsControlFlowExpr(const Stmt *S) {
698   const Expr *E = dyn_cast<Expr>(S);
699 
700   if (!E)
701     return false;
702 
703   E = E->IgnoreParenCasts();
704 
705   if (isa<AbstractConditionalOperator>(E))
706     return true;
707 
708   if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E))
709     if (B->isLogicalOp())
710       return true;
711 
712   return false;
713 }
714 
715 namespace {
716 class ContextLocation : public PathDiagnosticLocation {
717   bool IsDead;
718 public:
719   ContextLocation(const PathDiagnosticLocation &L, bool isdead = false)
720     : PathDiagnosticLocation(L), IsDead(isdead) {}
721 
722   void markDead() { IsDead = true; }
723   bool isDead() const { return IsDead; }
724 };
725 
726 class EdgeBuilder {
727   std::vector<ContextLocation> CLocs;
728   typedef std::vector<ContextLocation>::iterator iterator;
729   PathDiagnostic &PD;
730   PathDiagnosticBuilder &PDB;
731   PathDiagnosticLocation PrevLoc;
732 
733   bool IsConsumedExpr(const PathDiagnosticLocation &L);
734 
735   bool containsLocation(const PathDiagnosticLocation &Container,
736                         const PathDiagnosticLocation &Containee);
737 
738   PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L);
739 
740   PathDiagnosticLocation cleanUpLocation(PathDiagnosticLocation L,
741                                          bool firstCharOnly = false) {
742     if (const Stmt *S = L.asStmt()) {
743       const Stmt *Original = S;
744       while (1) {
745         // Adjust the location for some expressions that are best referenced
746         // by one of their subexpressions.
747         switch (S->getStmtClass()) {
748           default:
749             break;
750           case Stmt::ParenExprClass:
751           case Stmt::GenericSelectionExprClass:
752             S = cast<Expr>(S)->IgnoreParens();
753             firstCharOnly = true;
754             continue;
755           case Stmt::BinaryConditionalOperatorClass:
756           case Stmt::ConditionalOperatorClass:
757             S = cast<AbstractConditionalOperator>(S)->getCond();
758             firstCharOnly = true;
759             continue;
760           case Stmt::ChooseExprClass:
761             S = cast<ChooseExpr>(S)->getCond();
762             firstCharOnly = true;
763             continue;
764           case Stmt::BinaryOperatorClass:
765             S = cast<BinaryOperator>(S)->getLHS();
766             firstCharOnly = true;
767             continue;
768         }
769 
770         break;
771       }
772 
773       if (S != Original)
774         L = PathDiagnosticLocation(S, L.getManager(), PDB.LC);
775     }
776 
777     if (firstCharOnly)
778       L  = PathDiagnosticLocation::createSingleLocation(L);
779 
780     return L;
781   }
782 
783   void popLocation() {
784     if (!CLocs.back().isDead() && CLocs.back().asLocation().isFileID()) {
785       // For contexts, we only one the first character as the range.
786       rawAddEdge(cleanUpLocation(CLocs.back(), true));
787     }
788     CLocs.pop_back();
789   }
790 
791 public:
792   EdgeBuilder(PathDiagnostic &pd, PathDiagnosticBuilder &pdb)
793     : PD(pd), PDB(pdb) {
794 
795       // If the PathDiagnostic already has pieces, add the enclosing statement
796       // of the first piece as a context as well.
797       if (!PD.path.empty()) {
798         PrevLoc = (*PD.path.begin())->getLocation();
799 
800         if (const Stmt *S = PrevLoc.asStmt())
801           addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
802       }
803   }
804 
805   ~EdgeBuilder() {
806     while (!CLocs.empty()) popLocation();
807 
808     // Finally, add an initial edge from the start location of the first
809     // statement (if it doesn't already exist).
810     PathDiagnosticLocation L = PathDiagnosticLocation::createDeclBegin(
811                                                        PDB.LC,
812                                                        PDB.getSourceManager());
813     if (L.isValid())
814       rawAddEdge(L);
815   }
816 
817   void flushLocations() {
818     while (!CLocs.empty())
819       popLocation();
820     PrevLoc = PathDiagnosticLocation();
821   }
822 
823   void addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd = false);
824 
825   void rawAddEdge(PathDiagnosticLocation NewLoc);
826 
827   void addContext(const Stmt *S);
828   void addExtendedContext(const Stmt *S);
829 };
830 } // end anonymous namespace
831 
832 
833 PathDiagnosticLocation
834 EdgeBuilder::getContextLocation(const PathDiagnosticLocation &L) {
835   if (const Stmt *S = L.asStmt()) {
836     if (IsControlFlowExpr(S))
837       return L;
838 
839     return PDB.getEnclosingStmtLocation(S);
840   }
841 
842   return L;
843 }
844 
845 bool EdgeBuilder::containsLocation(const PathDiagnosticLocation &Container,
846                                    const PathDiagnosticLocation &Containee) {
847 
848   if (Container == Containee)
849     return true;
850 
851   if (Container.asDecl())
852     return true;
853 
854   if (const Stmt *S = Containee.asStmt())
855     if (const Stmt *ContainerS = Container.asStmt()) {
856       while (S) {
857         if (S == ContainerS)
858           return true;
859         S = PDB.getParent(S);
860       }
861       return false;
862     }
863 
864   // Less accurate: compare using source ranges.
865   SourceRange ContainerR = Container.asRange();
866   SourceRange ContaineeR = Containee.asRange();
867 
868   SourceManager &SM = PDB.getSourceManager();
869   SourceLocation ContainerRBeg = SM.getExpansionLoc(ContainerR.getBegin());
870   SourceLocation ContainerREnd = SM.getExpansionLoc(ContainerR.getEnd());
871   SourceLocation ContaineeRBeg = SM.getExpansionLoc(ContaineeR.getBegin());
872   SourceLocation ContaineeREnd = SM.getExpansionLoc(ContaineeR.getEnd());
873 
874   unsigned ContainerBegLine = SM.getExpansionLineNumber(ContainerRBeg);
875   unsigned ContainerEndLine = SM.getExpansionLineNumber(ContainerREnd);
876   unsigned ContaineeBegLine = SM.getExpansionLineNumber(ContaineeRBeg);
877   unsigned ContaineeEndLine = SM.getExpansionLineNumber(ContaineeREnd);
878 
879   assert(ContainerBegLine <= ContainerEndLine);
880   assert(ContaineeBegLine <= ContaineeEndLine);
881 
882   return (ContainerBegLine <= ContaineeBegLine &&
883           ContainerEndLine >= ContaineeEndLine &&
884           (ContainerBegLine != ContaineeBegLine ||
885            SM.getExpansionColumnNumber(ContainerRBeg) <=
886            SM.getExpansionColumnNumber(ContaineeRBeg)) &&
887           (ContainerEndLine != ContaineeEndLine ||
888            SM.getExpansionColumnNumber(ContainerREnd) >=
889            SM.getExpansionColumnNumber(ContainerREnd)));
890 }
891 
892 void EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) {
893   if (!PrevLoc.isValid()) {
894     PrevLoc = NewLoc;
895     return;
896   }
897 
898   const PathDiagnosticLocation &NewLocClean = cleanUpLocation(NewLoc);
899   const PathDiagnosticLocation &PrevLocClean = cleanUpLocation(PrevLoc);
900 
901   if (NewLocClean.asLocation() == PrevLocClean.asLocation())
902     return;
903 
904   // FIXME: Ignore intra-macro edges for now.
905   if (NewLocClean.asLocation().getExpansionLoc() ==
906       PrevLocClean.asLocation().getExpansionLoc())
907     return;
908 
909   PD.getActivePath().push_front(new PathDiagnosticControlFlowPiece(NewLocClean, PrevLocClean));
910   PrevLoc = NewLoc;
911 }
912 
913 void EdgeBuilder::addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd) {
914 
915   if (!alwaysAdd && NewLoc.asLocation().isMacroID())
916     return;
917 
918   const PathDiagnosticLocation &CLoc = getContextLocation(NewLoc);
919 
920   while (!CLocs.empty()) {
921     ContextLocation &TopContextLoc = CLocs.back();
922 
923     // Is the top location context the same as the one for the new location?
924     if (TopContextLoc == CLoc) {
925       if (alwaysAdd) {
926         if (IsConsumedExpr(TopContextLoc) &&
927             !IsControlFlowExpr(TopContextLoc.asStmt()))
928             TopContextLoc.markDead();
929 
930         rawAddEdge(NewLoc);
931       }
932 
933       return;
934     }
935 
936     if (containsLocation(TopContextLoc, CLoc)) {
937       if (alwaysAdd) {
938         rawAddEdge(NewLoc);
939 
940         if (IsConsumedExpr(CLoc) && !IsControlFlowExpr(CLoc.asStmt())) {
941           CLocs.push_back(ContextLocation(CLoc, true));
942           return;
943         }
944       }
945 
946       CLocs.push_back(CLoc);
947       return;
948     }
949 
950     // Context does not contain the location.  Flush it.
951     popLocation();
952   }
953 
954   // If we reach here, there is no enclosing context.  Just add the edge.
955   rawAddEdge(NewLoc);
956 }
957 
958 bool EdgeBuilder::IsConsumedExpr(const PathDiagnosticLocation &L) {
959   if (const Expr *X = dyn_cast_or_null<Expr>(L.asStmt()))
960     return PDB.getParentMap().isConsumedExpr(X) && !IsControlFlowExpr(X);
961 
962   return false;
963 }
964 
965 void EdgeBuilder::addExtendedContext(const Stmt *S) {
966   if (!S)
967     return;
968 
969   const Stmt *Parent = PDB.getParent(S);
970   while (Parent) {
971     if (isa<CompoundStmt>(Parent))
972       Parent = PDB.getParent(Parent);
973     else
974       break;
975   }
976 
977   if (Parent) {
978     switch (Parent->getStmtClass()) {
979       case Stmt::DoStmtClass:
980       case Stmt::ObjCAtSynchronizedStmtClass:
981         addContext(Parent);
982       default:
983         break;
984     }
985   }
986 
987   addContext(S);
988 }
989 
990 void EdgeBuilder::addContext(const Stmt *S) {
991   if (!S)
992     return;
993 
994   PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.LC);
995 
996   while (!CLocs.empty()) {
997     const PathDiagnosticLocation &TopContextLoc = CLocs.back();
998 
999     // Is the top location context the same as the one for the new location?
1000     if (TopContextLoc == L)
1001       return;
1002 
1003     if (containsLocation(TopContextLoc, L)) {
1004       CLocs.push_back(L);
1005       return;
1006     }
1007 
1008     // Context does not contain the location.  Flush it.
1009     popLocation();
1010   }
1011 
1012   CLocs.push_back(L);
1013 }
1014 
1015 static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
1016                                             PathDiagnosticBuilder &PDB,
1017                                             const ExplodedNode *N) {
1018   EdgeBuilder EB(PD, PDB);
1019   const SourceManager& SM = PDB.getSourceManager();
1020 
1021   const ExplodedNode *NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
1022   while (NextNode) {
1023     N = NextNode;
1024     NextNode = GetPredecessorNode(N);
1025     ProgramPoint P = N->getLocation();
1026 
1027     do {
1028       if (const CallExit *CE = dyn_cast<CallExit>(&P)) {
1029         const StackFrameContext *LCtx =
1030         CE->getLocationContext()->getCurrentStackFrame();
1031         PathDiagnosticLocation Loc(LCtx->getCallSite(),
1032                                    PDB.getSourceManager(),
1033                                    LCtx);
1034         EB.addEdge(Loc, true);
1035         EB.flushLocations();
1036         PathDiagnosticCallPiece *C =
1037           PathDiagnosticCallPiece::construct(N, *CE, SM);
1038         PD.getActivePath().push_front(C);
1039         PD.pushActivePath(&C->path);
1040         break;
1041       }
1042 
1043       // Pop the call hierarchy if we are done walking the contents
1044       // of a function call.
1045       if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
1046         // Add an edge to the start of the function.
1047         const Decl *D = CE->getCalleeContext()->getDecl();
1048         PathDiagnosticLocation pos =
1049           PathDiagnosticLocation::createBegin(D, SM);
1050         EB.addEdge(pos);
1051 
1052         // Flush all locations, and pop the active path.
1053         EB.flushLocations();
1054         PD.popActivePath();
1055         assert(!PD.getActivePath().empty());
1056         PDB.LC = N->getLocationContext();
1057 
1058         // The current active path should never be empty.  Either we
1059         // just added a bunch of stuff to the top-level path, or
1060         // we have a previous CallExit.  If the front of the active
1061         // path is not a PathDiagnosticCallPiece, it means that the
1062         // path terminated within a function call.  We must then take the
1063         // current contents of the active path and place it within
1064         // a new PathDiagnosticCallPiece.
1065         PathDiagnosticCallPiece *C =
1066           dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
1067         if (!C)
1068           C = PathDiagnosticCallPiece::construct(PD.getActivePath());
1069         C->setCallee(*CE, SM);
1070         EB.addContext(CE->getCallExpr());
1071         break;
1072       }
1073 
1074       // Note that is important that we update the LocationContext
1075       // after looking at CallExits.  CallExit basically adds an
1076       // edge in the *caller*, so we don't want to update the LocationContext
1077       // too soon.
1078       PDB.LC = N->getLocationContext();
1079 
1080       // Block edges.
1081       if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P)) {
1082         const CFGBlock &Blk = *BE->getSrc();
1083         const Stmt *Term = Blk.getTerminator();
1084 
1085         // Are we jumping to the head of a loop?  Add a special diagnostic.
1086         if (const Stmt *Loop = BE->getDst()->getLoopTarget()) {
1087           PathDiagnosticLocation L(Loop, SM, PDB.LC);
1088           const CompoundStmt *CS = NULL;
1089 
1090           if (!Term) {
1091             if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
1092               CS = dyn_cast<CompoundStmt>(FS->getBody());
1093             else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop))
1094               CS = dyn_cast<CompoundStmt>(WS->getBody());
1095           }
1096 
1097           PathDiagnosticEventPiece *p =
1098             new PathDiagnosticEventPiece(L,
1099                                         "Looping back to the head of the loop");
1100           p->setPrunable(true);
1101 
1102           EB.addEdge(p->getLocation(), true);
1103           PD.getActivePath().push_front(p);
1104 
1105           if (CS) {
1106             PathDiagnosticLocation BL =
1107               PathDiagnosticLocation::createEndBrace(CS, SM);
1108             EB.addEdge(BL);
1109           }
1110         }
1111 
1112         if (Term)
1113           EB.addContext(Term);
1114 
1115         break;
1116       }
1117 
1118       if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
1119         if (const CFGStmt *S = BE->getFirstElement().getAs<CFGStmt>()) {
1120           const Stmt *stmt = S->getStmt();
1121           if (IsControlFlowExpr(stmt)) {
1122             // Add the proper context for '&&', '||', and '?'.
1123             EB.addContext(stmt);
1124           }
1125           else
1126             EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt());
1127         }
1128 
1129         break;
1130       }
1131 
1132 
1133     } while (0);
1134 
1135     if (!NextNode)
1136       continue;
1137 
1138     // Add pieces from custom visitors.
1139     BugReport *R = PDB.getBugReport();
1140     for (BugReport::visitor_iterator I = R->visitor_begin(),
1141                                      E = R->visitor_end(); I!=E; ++I) {
1142       if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
1143         const PathDiagnosticLocation &Loc = p->getLocation();
1144         EB.addEdge(Loc, true);
1145         PD.getActivePath().push_front(p);
1146         if (const Stmt *S = Loc.asStmt())
1147           EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt());
1148       }
1149     }
1150   }
1151 }
1152 
1153 //===----------------------------------------------------------------------===//
1154 // Methods for BugType and subclasses.
1155 //===----------------------------------------------------------------------===//
1156 BugType::~BugType() { }
1157 
1158 void BugType::FlushReports(BugReporter &BR) {}
1159 
1160 void BuiltinBug::anchor() {}
1161 
1162 //===----------------------------------------------------------------------===//
1163 // Methods for BugReport and subclasses.
1164 //===----------------------------------------------------------------------===//
1165 
1166 void BugReport::NodeResolver::anchor() {}
1167 
1168 void BugReport::addVisitor(BugReporterVisitor* visitor) {
1169   if (!visitor)
1170     return;
1171 
1172   llvm::FoldingSetNodeID ID;
1173   visitor->Profile(ID);
1174   void *InsertPos;
1175 
1176   if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) {
1177     delete visitor;
1178     return;
1179   }
1180 
1181   CallbacksSet.InsertNode(visitor, InsertPos);
1182   Callbacks = F.add(visitor, Callbacks);
1183 }
1184 
1185 BugReport::~BugReport() {
1186   for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I) {
1187     delete *I;
1188   }
1189 }
1190 
1191 void BugReport::Profile(llvm::FoldingSetNodeID& hash) const {
1192   hash.AddPointer(&BT);
1193   hash.AddString(Description);
1194   if (UniqueingLocation.isValid()) {
1195     UniqueingLocation.Profile(hash);
1196   } else if (Location.isValid()) {
1197     Location.Profile(hash);
1198   } else {
1199     assert(ErrorNode);
1200     hash.AddPointer(GetCurrentOrPreviousStmt(ErrorNode));
1201   }
1202 
1203   for (SmallVectorImpl<SourceRange>::const_iterator I =
1204       Ranges.begin(), E = Ranges.end(); I != E; ++I) {
1205     const SourceRange range = *I;
1206     if (!range.isValid())
1207       continue;
1208     hash.AddInteger(range.getBegin().getRawEncoding());
1209     hash.AddInteger(range.getEnd().getRawEncoding());
1210   }
1211 }
1212 
1213 void BugReport::markInteresting(SymbolRef sym) {
1214   if (!sym)
1215     return;
1216   interestingSymbols.insert(sym);
1217 }
1218 
1219 void BugReport::markInteresting(const MemRegion *R) {
1220   if (!R)
1221     return;
1222   R = R->getBaseRegion();
1223   interestingRegions.insert(R);
1224 
1225   if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
1226     interestingSymbols.insert(SR->getSymbol());
1227 }
1228 
1229 void BugReport::markInteresting(SVal V) {
1230   markInteresting(V.getAsRegion());
1231   markInteresting(V.getAsSymbol());
1232 }
1233 
1234 bool BugReport::isInteresting(SVal V) const {
1235   return isInteresting(V.getAsRegion()) || isInteresting(V.getAsSymbol());
1236 }
1237 
1238 bool BugReport::isInteresting(SymbolRef sym) const {
1239   if (!sym)
1240     return false;
1241   return interestingSymbols.count(sym);
1242 }
1243 
1244 bool BugReport::isInteresting(const MemRegion *R) const {
1245   if (!R)
1246     return false;
1247   R = R->getBaseRegion();
1248   bool b = interestingRegions.count(R);
1249   if (b)
1250     return true;
1251   if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
1252     return interestingSymbols.count(SR->getSymbol());
1253   return false;
1254 }
1255 
1256 
1257 const Stmt *BugReport::getStmt() const {
1258   if (!ErrorNode)
1259     return 0;
1260 
1261   ProgramPoint ProgP = ErrorNode->getLocation();
1262   const Stmt *S = NULL;
1263 
1264   if (BlockEntrance *BE = dyn_cast<BlockEntrance>(&ProgP)) {
1265     CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit();
1266     if (BE->getBlock() == &Exit)
1267       S = GetPreviousStmt(ErrorNode);
1268   }
1269   if (!S)
1270     S = GetStmt(ProgP);
1271 
1272   return S;
1273 }
1274 
1275 std::pair<BugReport::ranges_iterator, BugReport::ranges_iterator>
1276 BugReport::getRanges() {
1277     // If no custom ranges, add the range of the statement corresponding to
1278     // the error node.
1279     if (Ranges.empty()) {
1280       if (const Expr *E = dyn_cast_or_null<Expr>(getStmt()))
1281         addRange(E->getSourceRange());
1282       else
1283         return std::make_pair(ranges_iterator(), ranges_iterator());
1284     }
1285 
1286     // User-specified absence of range info.
1287     if (Ranges.size() == 1 && !Ranges.begin()->isValid())
1288       return std::make_pair(ranges_iterator(), ranges_iterator());
1289 
1290     return std::make_pair(Ranges.begin(), Ranges.end());
1291 }
1292 
1293 PathDiagnosticLocation BugReport::getLocation(const SourceManager &SM) const {
1294   if (ErrorNode) {
1295     assert(!Location.isValid() &&
1296      "Either Location or ErrorNode should be specified but not both.");
1297 
1298     if (const Stmt *S = GetCurrentOrPreviousStmt(ErrorNode)) {
1299       const LocationContext *LC = ErrorNode->getLocationContext();
1300 
1301       // For member expressions, return the location of the '.' or '->'.
1302       if (const MemberExpr *ME = dyn_cast<MemberExpr>(S))
1303         return PathDiagnosticLocation::createMemberLoc(ME, SM);
1304       // For binary operators, return the location of the operator.
1305       if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
1306         return PathDiagnosticLocation::createOperatorLoc(B, SM);
1307 
1308       return PathDiagnosticLocation::createBegin(S, SM, LC);
1309     }
1310   } else {
1311     assert(Location.isValid());
1312     return Location;
1313   }
1314 
1315   return PathDiagnosticLocation();
1316 }
1317 
1318 //===----------------------------------------------------------------------===//
1319 // Methods for BugReporter and subclasses.
1320 //===----------------------------------------------------------------------===//
1321 
1322 BugReportEquivClass::~BugReportEquivClass() {
1323   for (iterator I=begin(), E=end(); I!=E; ++I) delete *I;
1324 }
1325 
1326 GRBugReporter::~GRBugReporter() { }
1327 BugReporterData::~BugReporterData() {}
1328 
1329 ExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); }
1330 
1331 ProgramStateManager&
1332 GRBugReporter::getStateManager() { return Eng.getStateManager(); }
1333 
1334 BugReporter::~BugReporter() {
1335   FlushReports();
1336 
1337   // Free the bug reports we are tracking.
1338   typedef std::vector<BugReportEquivClass *> ContTy;
1339   for (ContTy::iterator I = EQClassesVector.begin(), E = EQClassesVector.end();
1340        I != E; ++I) {
1341     delete *I;
1342   }
1343 }
1344 
1345 void BugReporter::FlushReports() {
1346   if (BugTypes.isEmpty())
1347     return;
1348 
1349   // First flush the warnings for each BugType.  This may end up creating new
1350   // warnings and new BugTypes.
1351   // FIXME: Only NSErrorChecker needs BugType's FlushReports.
1352   // Turn NSErrorChecker into a proper checker and remove this.
1353   SmallVector<const BugType*, 16> bugTypes;
1354   for (BugTypesTy::iterator I=BugTypes.begin(), E=BugTypes.end(); I!=E; ++I)
1355     bugTypes.push_back(*I);
1356   for (SmallVector<const BugType*, 16>::iterator
1357          I = bugTypes.begin(), E = bugTypes.end(); I != E; ++I)
1358     const_cast<BugType*>(*I)->FlushReports(*this);
1359 
1360   typedef llvm::FoldingSet<BugReportEquivClass> SetTy;
1361   for (SetTy::iterator EI=EQClasses.begin(), EE=EQClasses.end(); EI!=EE;++EI){
1362     BugReportEquivClass& EQ = *EI;
1363     FlushReport(EQ);
1364   }
1365 
1366   // BugReporter owns and deletes only BugTypes created implicitly through
1367   // EmitBasicReport.
1368   // FIXME: There are leaks from checkers that assume that the BugTypes they
1369   // create will be destroyed by the BugReporter.
1370   for (llvm::StringMap<BugType*>::iterator
1371          I = StrBugTypes.begin(), E = StrBugTypes.end(); I != E; ++I)
1372     delete I->second;
1373 
1374   // Remove all references to the BugType objects.
1375   BugTypes = F.getEmptySet();
1376 }
1377 
1378 //===----------------------------------------------------------------------===//
1379 // PathDiagnostics generation.
1380 //===----------------------------------------------------------------------===//
1381 
1382 static std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
1383                  std::pair<ExplodedNode*, unsigned> >
1384 MakeReportGraph(const ExplodedGraph* G,
1385                 SmallVectorImpl<const ExplodedNode*> &nodes) {
1386 
1387   // Create the trimmed graph.  It will contain the shortest paths from the
1388   // error nodes to the root.  In the new graph we should only have one
1389   // error node unless there are two or more error nodes with the same minimum
1390   // path length.
1391   ExplodedGraph* GTrim;
1392   InterExplodedGraphMap* NMap;
1393 
1394   llvm::DenseMap<const void*, const void*> InverseMap;
1395   llvm::tie(GTrim, NMap) = G->Trim(nodes.data(), nodes.data() + nodes.size(),
1396                                    &InverseMap);
1397 
1398   // Create owning pointers for GTrim and NMap just to ensure that they are
1399   // released when this function exists.
1400   OwningPtr<ExplodedGraph> AutoReleaseGTrim(GTrim);
1401   OwningPtr<InterExplodedGraphMap> AutoReleaseNMap(NMap);
1402 
1403   // Find the (first) error node in the trimmed graph.  We just need to consult
1404   // the node map (NMap) which maps from nodes in the original graph to nodes
1405   // in the new graph.
1406 
1407   std::queue<const ExplodedNode*> WS;
1408   typedef llvm::DenseMap<const ExplodedNode*, unsigned> IndexMapTy;
1409   IndexMapTy IndexMap;
1410 
1411   for (unsigned nodeIndex = 0 ; nodeIndex < nodes.size(); ++nodeIndex) {
1412     const ExplodedNode *originalNode = nodes[nodeIndex];
1413     if (const ExplodedNode *N = NMap->getMappedNode(originalNode)) {
1414       WS.push(N);
1415       IndexMap[originalNode] = nodeIndex;
1416     }
1417   }
1418 
1419   assert(!WS.empty() && "No error node found in the trimmed graph.");
1420 
1421   // Create a new (third!) graph with a single path.  This is the graph
1422   // that will be returned to the caller.
1423   ExplodedGraph *GNew = new ExplodedGraph();
1424 
1425   // Sometimes the trimmed graph can contain a cycle.  Perform a reverse BFS
1426   // to the root node, and then construct a new graph that contains only
1427   // a single path.
1428   llvm::DenseMap<const void*,unsigned> Visited;
1429 
1430   unsigned cnt = 0;
1431   const ExplodedNode *Root = 0;
1432 
1433   while (!WS.empty()) {
1434     const ExplodedNode *Node = WS.front();
1435     WS.pop();
1436 
1437     if (Visited.find(Node) != Visited.end())
1438       continue;
1439 
1440     Visited[Node] = cnt++;
1441 
1442     if (Node->pred_empty()) {
1443       Root = Node;
1444       break;
1445     }
1446 
1447     for (ExplodedNode::const_pred_iterator I=Node->pred_begin(),
1448          E=Node->pred_end(); I!=E; ++I)
1449       WS.push(*I);
1450   }
1451 
1452   assert(Root);
1453 
1454   // Now walk from the root down the BFS path, always taking the successor
1455   // with the lowest number.
1456   ExplodedNode *Last = 0, *First = 0;
1457   NodeBackMap *BM = new NodeBackMap();
1458   unsigned NodeIndex = 0;
1459 
1460   for ( const ExplodedNode *N = Root ;;) {
1461     // Lookup the number associated with the current node.
1462     llvm::DenseMap<const void*,unsigned>::iterator I = Visited.find(N);
1463     assert(I != Visited.end());
1464 
1465     // Create the equivalent node in the new graph with the same state
1466     // and location.
1467     ExplodedNode *NewN = GNew->getNode(N->getLocation(), N->getState());
1468 
1469     // Store the mapping to the original node.
1470     llvm::DenseMap<const void*, const void*>::iterator IMitr=InverseMap.find(N);
1471     assert(IMitr != InverseMap.end() && "No mapping to original node.");
1472     (*BM)[NewN] = (const ExplodedNode*) IMitr->second;
1473 
1474     // Link up the new node with the previous node.
1475     if (Last)
1476       NewN->addPredecessor(Last, *GNew);
1477 
1478     Last = NewN;
1479 
1480     // Are we at the final node?
1481     IndexMapTy::iterator IMI =
1482       IndexMap.find((const ExplodedNode*)(IMitr->second));
1483     if (IMI != IndexMap.end()) {
1484       First = NewN;
1485       NodeIndex = IMI->second;
1486       break;
1487     }
1488 
1489     // Find the next successor node.  We choose the node that is marked
1490     // with the lowest DFS number.
1491     ExplodedNode::const_succ_iterator SI = N->succ_begin();
1492     ExplodedNode::const_succ_iterator SE = N->succ_end();
1493     N = 0;
1494 
1495     for (unsigned MinVal = 0; SI != SE; ++SI) {
1496 
1497       I = Visited.find(*SI);
1498 
1499       if (I == Visited.end())
1500         continue;
1501 
1502       if (!N || I->second < MinVal) {
1503         N = *SI;
1504         MinVal = I->second;
1505       }
1506     }
1507 
1508     assert(N);
1509   }
1510 
1511   assert(First);
1512 
1513   return std::make_pair(std::make_pair(GNew, BM),
1514                         std::make_pair(First, NodeIndex));
1515 }
1516 
1517 /// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
1518 ///  and collapses PathDiagosticPieces that are expanded by macros.
1519 static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) {
1520   typedef std::vector<std::pair<IntrusiveRefCntPtr<PathDiagnosticMacroPiece>,
1521                                 SourceLocation> > MacroStackTy;
1522 
1523   typedef std::vector<IntrusiveRefCntPtr<PathDiagnosticPiece> >
1524           PiecesTy;
1525 
1526   MacroStackTy MacroStack;
1527   PiecesTy Pieces;
1528 
1529   for (PathPieces::const_iterator I = path.begin(), E = path.end();
1530        I!=E; ++I) {
1531 
1532     PathDiagnosticPiece *piece = I->getPtr();
1533 
1534     // Recursively compact calls.
1535     if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
1536       CompactPathDiagnostic(call->path, SM);
1537     }
1538 
1539     // Get the location of the PathDiagnosticPiece.
1540     const FullSourceLoc Loc = piece->getLocation().asLocation();
1541 
1542     // Determine the instantiation location, which is the location we group
1543     // related PathDiagnosticPieces.
1544     SourceLocation InstantiationLoc = Loc.isMacroID() ?
1545                                       SM.getExpansionLoc(Loc) :
1546                                       SourceLocation();
1547 
1548     if (Loc.isFileID()) {
1549       MacroStack.clear();
1550       Pieces.push_back(piece);
1551       continue;
1552     }
1553 
1554     assert(Loc.isMacroID());
1555 
1556     // Is the PathDiagnosticPiece within the same macro group?
1557     if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) {
1558       MacroStack.back().first->subPieces.push_back(piece);
1559       continue;
1560     }
1561 
1562     // We aren't in the same group.  Are we descending into a new macro
1563     // or are part of an old one?
1564     IntrusiveRefCntPtr<PathDiagnosticMacroPiece> MacroGroup;
1565 
1566     SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ?
1567                                           SM.getExpansionLoc(Loc) :
1568                                           SourceLocation();
1569 
1570     // Walk the entire macro stack.
1571     while (!MacroStack.empty()) {
1572       if (InstantiationLoc == MacroStack.back().second) {
1573         MacroGroup = MacroStack.back().first;
1574         break;
1575       }
1576 
1577       if (ParentInstantiationLoc == MacroStack.back().second) {
1578         MacroGroup = MacroStack.back().first;
1579         break;
1580       }
1581 
1582       MacroStack.pop_back();
1583     }
1584 
1585     if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) {
1586       // Create a new macro group and add it to the stack.
1587       PathDiagnosticMacroPiece *NewGroup =
1588         new PathDiagnosticMacroPiece(
1589           PathDiagnosticLocation::createSingleLocation(piece->getLocation()));
1590 
1591       if (MacroGroup)
1592         MacroGroup->subPieces.push_back(NewGroup);
1593       else {
1594         assert(InstantiationLoc.isFileID());
1595         Pieces.push_back(NewGroup);
1596       }
1597 
1598       MacroGroup = NewGroup;
1599       MacroStack.push_back(std::make_pair(MacroGroup, InstantiationLoc));
1600     }
1601 
1602     // Finally, add the PathDiagnosticPiece to the group.
1603     MacroGroup->subPieces.push_back(piece);
1604   }
1605 
1606   // Now take the pieces and construct a new PathDiagnostic.
1607   path.clear();
1608 
1609   for (PiecesTy::iterator I=Pieces.begin(), E=Pieces.end(); I!=E; ++I)
1610     path.push_back(*I);
1611 }
1612 
1613 void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
1614                         SmallVectorImpl<BugReport *> &bugReports) {
1615 
1616   assert(!bugReports.empty());
1617   SmallVector<const ExplodedNode *, 10> errorNodes;
1618   for (SmallVectorImpl<BugReport*>::iterator I = bugReports.begin(),
1619     E = bugReports.end(); I != E; ++I) {
1620       errorNodes.push_back((*I)->getErrorNode());
1621   }
1622 
1623   // Construct a new graph that contains only a single path from the error
1624   // node to a root.
1625   const std::pair<std::pair<ExplodedGraph*, NodeBackMap*>,
1626   std::pair<ExplodedNode*, unsigned> >&
1627     GPair = MakeReportGraph(&getGraph(), errorNodes);
1628 
1629   // Find the BugReport with the original location.
1630   assert(GPair.second.second < bugReports.size());
1631   BugReport *R = bugReports[GPair.second.second];
1632   assert(R && "No original report found for sliced graph.");
1633 
1634   OwningPtr<ExplodedGraph> ReportGraph(GPair.first.first);
1635   OwningPtr<NodeBackMap> BackMap(GPair.first.second);
1636   const ExplodedNode *N = GPair.second.first;
1637 
1638   // Start building the path diagnostic...
1639   PathDiagnosticBuilder PDB(*this, R, BackMap.get(),
1640                             getPathDiagnosticConsumer());
1641 
1642   // Register additional node visitors.
1643   R->addVisitor(new NilReceiverBRVisitor());
1644   R->addVisitor(new ConditionBRVisitor());
1645 
1646   // Generate the very last diagnostic piece - the piece is visible before
1647   // the trace is expanded.
1648   PathDiagnosticPiece *LastPiece = 0;
1649   for (BugReport::visitor_iterator I = R->visitor_begin(),
1650                                    E = R->visitor_end(); I!=E; ++I) {
1651     if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
1652       assert (!LastPiece &&
1653               "There can only be one final piece in a diagnostic.");
1654       LastPiece = Piece;
1655     }
1656   }
1657   if (!LastPiece)
1658     LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
1659   if (LastPiece)
1660     PD.getActivePath().push_back(LastPiece);
1661   else
1662     return;
1663 
1664   switch (PDB.getGenerationScheme()) {
1665     case PathDiagnosticConsumer::Extensive:
1666       GenerateExtensivePathDiagnostic(PD, PDB, N);
1667       break;
1668     case PathDiagnosticConsumer::Minimal:
1669       GenerateMinimalPathDiagnostic(PD, PDB, N);
1670       break;
1671   }
1672 
1673   // Finally, prune the diagnostic path of uninteresting stuff.
1674   bool hasSomethingInteresting = RemoveUneededCalls(PD.getMutablePieces());
1675   assert(hasSomethingInteresting);
1676   (void) hasSomethingInteresting;
1677 }
1678 
1679 void BugReporter::Register(BugType *BT) {
1680   BugTypes = F.add(BugTypes, BT);
1681 }
1682 
1683 void BugReporter::EmitReport(BugReport* R) {
1684   // Compute the bug report's hash to determine its equivalence class.
1685   llvm::FoldingSetNodeID ID;
1686   R->Profile(ID);
1687 
1688   // Lookup the equivance class.  If there isn't one, create it.
1689   BugType& BT = R->getBugType();
1690   Register(&BT);
1691   void *InsertPos;
1692   BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos);
1693 
1694   if (!EQ) {
1695     EQ = new BugReportEquivClass(R);
1696     EQClasses.InsertNode(EQ, InsertPos);
1697     EQClassesVector.push_back(EQ);
1698   }
1699   else
1700     EQ->AddReport(R);
1701 }
1702 
1703 
1704 //===----------------------------------------------------------------------===//
1705 // Emitting reports in equivalence classes.
1706 //===----------------------------------------------------------------------===//
1707 
1708 namespace {
1709 struct FRIEC_WLItem {
1710   const ExplodedNode *N;
1711   ExplodedNode::const_succ_iterator I, E;
1712 
1713   FRIEC_WLItem(const ExplodedNode *n)
1714   : N(n), I(N->succ_begin()), E(N->succ_end()) {}
1715 };
1716 }
1717 
1718 static BugReport *
1719 FindReportInEquivalenceClass(BugReportEquivClass& EQ,
1720                              SmallVectorImpl<BugReport*> &bugReports) {
1721 
1722   BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
1723   assert(I != E);
1724   BugReport *R = *I;
1725   BugType& BT = R->getBugType();
1726 
1727   // If we don't need to suppress any of the nodes because they are
1728   // post-dominated by a sink, simply add all the nodes in the equivalence class
1729   // to 'Nodes'.  Any of the reports will serve as a "representative" report.
1730   if (!BT.isSuppressOnSink()) {
1731     for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) {
1732       const ExplodedNode *N = I->getErrorNode();
1733       if (N) {
1734         R = *I;
1735         bugReports.push_back(R);
1736       }
1737     }
1738     return R;
1739   }
1740 
1741   // For bug reports that should be suppressed when all paths are post-dominated
1742   // by a sink node, iterate through the reports in the equivalence class
1743   // until we find one that isn't post-dominated (if one exists).  We use a
1744   // DFS traversal of the ExplodedGraph to find a non-sink node.  We could write
1745   // this as a recursive function, but we don't want to risk blowing out the
1746   // stack for very long paths.
1747   BugReport *exampleReport = 0;
1748 
1749   for (; I != E; ++I) {
1750     R = *I;
1751     const ExplodedNode *errorNode = R->getErrorNode();
1752 
1753     if (!errorNode)
1754       continue;
1755     if (errorNode->isSink()) {
1756       llvm_unreachable(
1757            "BugType::isSuppressSink() should not be 'true' for sink end nodes");
1758     }
1759     // No successors?  By definition this nodes isn't post-dominated by a sink.
1760     if (errorNode->succ_empty()) {
1761       bugReports.push_back(R);
1762       if (!exampleReport)
1763         exampleReport = R;
1764       continue;
1765     }
1766 
1767     // At this point we know that 'N' is not a sink and it has at least one
1768     // successor.  Use a DFS worklist to find a non-sink end-of-path node.
1769     typedef FRIEC_WLItem WLItem;
1770     typedef SmallVector<WLItem, 10> DFSWorkList;
1771     llvm::DenseMap<const ExplodedNode *, unsigned> Visited;
1772 
1773     DFSWorkList WL;
1774     WL.push_back(errorNode);
1775     Visited[errorNode] = 1;
1776 
1777     while (!WL.empty()) {
1778       WLItem &WI = WL.back();
1779       assert(!WI.N->succ_empty());
1780 
1781       for (; WI.I != WI.E; ++WI.I) {
1782         const ExplodedNode *Succ = *WI.I;
1783         // End-of-path node?
1784         if (Succ->succ_empty()) {
1785           // If we found an end-of-path node that is not a sink.
1786           if (!Succ->isSink()) {
1787             bugReports.push_back(R);
1788             if (!exampleReport)
1789               exampleReport = R;
1790             WL.clear();
1791             break;
1792           }
1793           // Found a sink?  Continue on to the next successor.
1794           continue;
1795         }
1796         // Mark the successor as visited.  If it hasn't been explored,
1797         // enqueue it to the DFS worklist.
1798         unsigned &mark = Visited[Succ];
1799         if (!mark) {
1800           mark = 1;
1801           WL.push_back(Succ);
1802           break;
1803         }
1804       }
1805 
1806       // The worklist may have been cleared at this point.  First
1807       // check if it is empty before checking the last item.
1808       if (!WL.empty() && &WL.back() == &WI)
1809         WL.pop_back();
1810     }
1811   }
1812 
1813   // ExampleReport will be NULL if all the nodes in the equivalence class
1814   // were post-dominated by sinks.
1815   return exampleReport;
1816 }
1817 
1818 //===----------------------------------------------------------------------===//
1819 // DiagnosticCache.  This is a hack to cache analyzer diagnostics.  It
1820 // uses global state, which eventually should go elsewhere.
1821 //===----------------------------------------------------------------------===//
1822 namespace {
1823 class DiagCacheItem : public llvm::FoldingSetNode {
1824   llvm::FoldingSetNodeID ID;
1825 public:
1826   DiagCacheItem(BugReport *R, PathDiagnostic *PD) {
1827     R->Profile(ID);
1828     PD->Profile(ID);
1829   }
1830 
1831   void Profile(llvm::FoldingSetNodeID &id) {
1832     id = ID;
1833   }
1834 
1835   llvm::FoldingSetNodeID &getID() { return ID; }
1836 };
1837 }
1838 
1839 static bool IsCachedDiagnostic(BugReport *R, PathDiagnostic *PD) {
1840   // FIXME: Eventually this diagnostic cache should reside in something
1841   // like AnalysisManager instead of being a static variable.  This is
1842   // really unsafe in the long term.
1843   typedef llvm::FoldingSet<DiagCacheItem> DiagnosticCache;
1844   static DiagnosticCache DC;
1845 
1846   void *InsertPos;
1847   DiagCacheItem *Item = new DiagCacheItem(R, PD);
1848 
1849   if (DC.FindNodeOrInsertPos(Item->getID(), InsertPos)) {
1850     delete Item;
1851     return true;
1852   }
1853 
1854   DC.InsertNode(Item, InsertPos);
1855   return false;
1856 }
1857 
1858 void BugReporter::FlushReport(BugReportEquivClass& EQ) {
1859   SmallVector<BugReport*, 10> bugReports;
1860   BugReport *exampleReport = FindReportInEquivalenceClass(EQ, bugReports);
1861   if (!exampleReport)
1862     return;
1863 
1864   PathDiagnosticConsumer* PD = getPathDiagnosticConsumer();
1865 
1866   // FIXME: Make sure we use the 'R' for the path that was actually used.
1867   // Probably doesn't make a difference in practice.
1868   BugType& BT = exampleReport->getBugType();
1869 
1870   OwningPtr<PathDiagnostic>
1871     D(new PathDiagnostic(exampleReport->getBugType().getName(),
1872                          !PD || PD->useVerboseDescription()
1873                          ? exampleReport->getDescription()
1874                          : exampleReport->getShortDescription(),
1875                          BT.getCategory()));
1876 
1877   if (!bugReports.empty())
1878     GeneratePathDiagnostic(*D.get(), bugReports);
1879 
1880   if (IsCachedDiagnostic(exampleReport, D.get()))
1881     return;
1882 
1883   // Get the meta data.
1884   const BugReport::ExtraTextList &Meta =
1885                                   exampleReport->getExtraText();
1886   for (BugReport::ExtraTextList::const_iterator i = Meta.begin(),
1887                                                 e = Meta.end(); i != e; ++i) {
1888     D->addMeta(*i);
1889   }
1890 
1891   // Emit a summary diagnostic to the regular Diagnostics engine.
1892   BugReport::ranges_iterator Beg, End;
1893   llvm::tie(Beg, End) = exampleReport->getRanges();
1894   DiagnosticsEngine &Diag = getDiagnostic();
1895 
1896   // Search the description for '%', as that will be interpretted as a
1897   // format character by FormatDiagnostics.
1898   StringRef desc = exampleReport->getShortDescription();
1899   unsigned ErrorDiag;
1900   {
1901     SmallString<512> TmpStr;
1902     llvm::raw_svector_ostream Out(TmpStr);
1903     for (StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I)
1904       if (*I == '%')
1905         Out << "%%";
1906       else
1907         Out << *I;
1908 
1909     Out.flush();
1910     ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning, TmpStr);
1911   }
1912 
1913   {
1914     DiagnosticBuilder diagBuilder = Diag.Report(
1915       exampleReport->getLocation(getSourceManager()).asLocation(), ErrorDiag);
1916     for (BugReport::ranges_iterator I = Beg; I != End; ++I)
1917       diagBuilder << *I;
1918   }
1919 
1920   // Emit a full diagnostic for the path if we have a PathDiagnosticConsumer.
1921   if (!PD)
1922     return;
1923 
1924   if (D->path.empty()) {
1925     PathDiagnosticPiece *piece = new PathDiagnosticEventPiece(
1926                                  exampleReport->getLocation(getSourceManager()),
1927                                  exampleReport->getDescription());
1928 
1929     for ( ; Beg != End; ++Beg) piece->addRange(*Beg);
1930     D->getActivePath().push_back(piece);
1931   }
1932 
1933   PD->HandlePathDiagnostic(D.take());
1934 }
1935 
1936 void BugReporter::EmitBasicReport(StringRef name, StringRef str,
1937                                   PathDiagnosticLocation Loc,
1938                                   SourceRange* RBeg, unsigned NumRanges) {
1939   EmitBasicReport(name, "", str, Loc, RBeg, NumRanges);
1940 }
1941 
1942 void BugReporter::EmitBasicReport(StringRef name,
1943                                   StringRef category,
1944                                   StringRef str, PathDiagnosticLocation Loc,
1945                                   SourceRange* RBeg, unsigned NumRanges) {
1946 
1947   // 'BT' is owned by BugReporter.
1948   BugType *BT = getBugTypeForName(name, category);
1949   BugReport *R = new BugReport(*BT, str, Loc);
1950   for ( ; NumRanges > 0 ; --NumRanges, ++RBeg) R->addRange(*RBeg);
1951   EmitReport(R);
1952 }
1953 
1954 BugType *BugReporter::getBugTypeForName(StringRef name,
1955                                         StringRef category) {
1956   SmallString<136> fullDesc;
1957   llvm::raw_svector_ostream(fullDesc) << name << ":" << category;
1958   llvm::StringMapEntry<BugType *> &
1959       entry = StrBugTypes.GetOrCreateValue(fullDesc);
1960   BugType *BT = entry.getValue();
1961   if (!BT) {
1962     BT = new BugType(name, category);
1963     entry.setValue(BT);
1964   }
1965   return BT;
1966 }
1967