BugReporter.cpp 60 KB

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