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