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