BugReporter.cpp 61 KB

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