1 // BugReporter.cpp - Generate PathDiagnostics for Bugs ------------*- C++ -*--// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines BugReporter, a utility class for generating 11 // PathDiagnostics. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/DeclObjC.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/AST/ExprCXX.h" 20 #include "clang/AST/ParentMap.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtObjC.h" 23 #include "clang/Analysis/CFG.h" 24 #include "clang/Analysis/CFGStmtMap.h" 25 #include "clang/Analysis/ProgramPoint.h" 26 #include "clang/Basic/SourceManager.h" 27 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 28 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" 29 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 30 #include "llvm/ADT/DenseMap.h" 31 #include "llvm/ADT/IntrusiveRefCntPtr.h" 32 #include "llvm/ADT/STLExtras.h" 33 #include "llvm/ADT/SmallString.h" 34 #include "llvm/ADT/Statistic.h" 35 #include "llvm/Support/raw_ostream.h" 36 #include <memory> 37 #include <queue> 38 39 using namespace clang; 40 using namespace ento; 41 42 #define DEBUG_TYPE "BugReporter" 43 44 STATISTIC(MaxBugClassSize, 45 "The maximum number of bug reports in the same equivalence class"); 46 STATISTIC(MaxValidBugClassSize, 47 "The maximum number of bug reports in the same equivalence class " 48 "where at least one report is valid (not suppressed)"); 49 50 BugReporterVisitor::~BugReporterVisitor() {} 51 52 void BugReporterContext::anchor() {} 53 54 //===----------------------------------------------------------------------===// 55 // Helper routines for walking the ExplodedGraph and fetching statements. 56 //===----------------------------------------------------------------------===// 57 58 static const Stmt *GetPreviousStmt(const ExplodedNode *N) { 59 for (N = N->getFirstPred(); N; N = N->getFirstPred()) 60 if (const Stmt *S = PathDiagnosticLocation::getStmt(N)) 61 return S; 62 63 return nullptr; 64 } 65 66 static inline const Stmt* 67 GetCurrentOrPreviousStmt(const ExplodedNode *N) { 68 if (const Stmt *S = PathDiagnosticLocation::getStmt(N)) 69 return S; 70 71 return GetPreviousStmt(N); 72 } 73 74 //===----------------------------------------------------------------------===// 75 // Diagnostic cleanup. 76 //===----------------------------------------------------------------------===// 77 78 static PathDiagnosticEventPiece * 79 eventsDescribeSameCondition(PathDiagnosticEventPiece *X, 80 PathDiagnosticEventPiece *Y) { 81 // Prefer diagnostics that come from ConditionBRVisitor over 82 // those that came from TrackConstraintBRVisitor, 83 // unless the one from ConditionBRVisitor is 84 // its generic fallback diagnostic. 85 const void *tagPreferred = ConditionBRVisitor::getTag(); 86 const void *tagLesser = TrackConstraintBRVisitor::getTag(); 87 88 if (X->getLocation() != Y->getLocation()) 89 return nullptr; 90 91 if (X->getTag() == tagPreferred && Y->getTag() == tagLesser) 92 return ConditionBRVisitor::isPieceMessageGeneric(X) ? Y : X; 93 94 if (Y->getTag() == tagPreferred && X->getTag() == tagLesser) 95 return ConditionBRVisitor::isPieceMessageGeneric(Y) ? X : Y; 96 97 return nullptr; 98 } 99 100 /// An optimization pass over PathPieces that removes redundant diagnostics 101 /// generated by both ConditionBRVisitor and TrackConstraintBRVisitor. Both 102 /// BugReporterVisitors use different methods to generate diagnostics, with 103 /// one capable of emitting diagnostics in some cases but not in others. This 104 /// can lead to redundant diagnostic pieces at the same point in a path. 105 static void removeRedundantMsgs(PathPieces &path) { 106 unsigned N = path.size(); 107 if (N < 2) 108 return; 109 // NOTE: this loop intentionally is not using an iterator. Instead, we 110 // are streaming the path and modifying it in place. This is done by 111 // grabbing the front, processing it, and if we decide to keep it append 112 // it to the end of the path. The entire path is processed in this way. 113 for (unsigned i = 0; i < N; ++i) { 114 auto piece = std::move(path.front()); 115 path.pop_front(); 116 117 switch (piece->getKind()) { 118 case PathDiagnosticPiece::Call: 119 removeRedundantMsgs(cast<PathDiagnosticCallPiece>(*piece).path); 120 break; 121 case PathDiagnosticPiece::Macro: 122 removeRedundantMsgs(cast<PathDiagnosticMacroPiece>(*piece).subPieces); 123 break; 124 case PathDiagnosticPiece::ControlFlow: 125 break; 126 case PathDiagnosticPiece::Event: { 127 if (i == N-1) 128 break; 129 130 if (PathDiagnosticEventPiece *nextEvent = 131 dyn_cast<PathDiagnosticEventPiece>(path.front().get())) { 132 PathDiagnosticEventPiece *event = 133 cast<PathDiagnosticEventPiece>(piece.get()); 134 // Check to see if we should keep one of the two pieces. If we 135 // come up with a preference, record which piece to keep, and consume 136 // another piece from the path. 137 if (auto *pieceToKeep = 138 eventsDescribeSameCondition(event, nextEvent)) { 139 piece = std::move(pieceToKeep == event ? piece : path.front()); 140 path.pop_front(); 141 ++i; 142 } 143 } 144 break; 145 } 146 case PathDiagnosticPiece::Note: 147 break; 148 } 149 path.push_back(std::move(piece)); 150 } 151 } 152 153 /// A map from PathDiagnosticPiece to the LocationContext of the inlined 154 /// function call it represents. 155 typedef llvm::DenseMap<const PathPieces *, const LocationContext *> 156 LocationContextMap; 157 158 /// Recursively scan through a path and prune out calls and macros pieces 159 /// that aren't needed. Return true if afterwards the path contains 160 /// "interesting stuff" which means it shouldn't be pruned from the parent path. 161 static bool removeUnneededCalls(PathPieces &pieces, BugReport *R, 162 LocationContextMap &LCM) { 163 bool containsSomethingInteresting = false; 164 const unsigned N = pieces.size(); 165 166 for (unsigned i = 0 ; i < N ; ++i) { 167 // Remove the front piece from the path. If it is still something we 168 // want to keep once we are done, we will push it back on the end. 169 auto piece = std::move(pieces.front()); 170 pieces.pop_front(); 171 172 switch (piece->getKind()) { 173 case PathDiagnosticPiece::Call: { 174 auto &call = cast<PathDiagnosticCallPiece>(*piece); 175 // Check if the location context is interesting. 176 assert(LCM.count(&call.path)); 177 if (R->isInteresting(LCM[&call.path])) { 178 containsSomethingInteresting = true; 179 break; 180 } 181 182 if (!removeUnneededCalls(call.path, R, LCM)) 183 continue; 184 185 containsSomethingInteresting = true; 186 break; 187 } 188 case PathDiagnosticPiece::Macro: { 189 auto ¯o = cast<PathDiagnosticMacroPiece>(*piece); 190 if (!removeUnneededCalls(macro.subPieces, R, LCM)) 191 continue; 192 containsSomethingInteresting = true; 193 break; 194 } 195 case PathDiagnosticPiece::Event: { 196 auto &event = cast<PathDiagnosticEventPiece>(*piece); 197 198 // We never throw away an event, but we do throw it away wholesale 199 // as part of a path if we throw the entire path away. 200 containsSomethingInteresting |= !event.isPrunable(); 201 break; 202 } 203 case PathDiagnosticPiece::ControlFlow: 204 break; 205 206 case PathDiagnosticPiece::Note: 207 break; 208 } 209 210 pieces.push_back(std::move(piece)); 211 } 212 213 return containsSomethingInteresting; 214 } 215 216 /// Returns true if the given decl has been implicitly given a body, either by 217 /// the analyzer or by the compiler proper. 218 static bool hasImplicitBody(const Decl *D) { 219 assert(D); 220 return D->isImplicit() || !D->hasBody(); 221 } 222 223 /// Recursively scan through a path and make sure that all call pieces have 224 /// valid locations. 225 static void 226 adjustCallLocations(PathPieces &Pieces, 227 PathDiagnosticLocation *LastCallLocation = nullptr) { 228 for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E; ++I) { 229 PathDiagnosticCallPiece *Call = dyn_cast<PathDiagnosticCallPiece>(I->get()); 230 231 if (!Call) { 232 assert((*I)->getLocation().asLocation().isValid()); 233 continue; 234 } 235 236 if (LastCallLocation) { 237 bool CallerIsImplicit = hasImplicitBody(Call->getCaller()); 238 if (CallerIsImplicit || !Call->callEnter.asLocation().isValid()) 239 Call->callEnter = *LastCallLocation; 240 if (CallerIsImplicit || !Call->callReturn.asLocation().isValid()) 241 Call->callReturn = *LastCallLocation; 242 } 243 244 // Recursively clean out the subclass. Keep this call around if 245 // it contains any informative diagnostics. 246 PathDiagnosticLocation *ThisCallLocation; 247 if (Call->callEnterWithin.asLocation().isValid() && 248 !hasImplicitBody(Call->getCallee())) 249 ThisCallLocation = &Call->callEnterWithin; 250 else 251 ThisCallLocation = &Call->callEnter; 252 253 assert(ThisCallLocation && "Outermost call has an invalid location"); 254 adjustCallLocations(Call->path, ThisCallLocation); 255 } 256 } 257 258 /// Remove edges in and out of C++ default initializer expressions. These are 259 /// for fields that have in-class initializers, as opposed to being initialized 260 /// explicitly in a constructor or braced list. 261 static void removeEdgesToDefaultInitializers(PathPieces &Pieces) { 262 for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) { 263 if (auto *C = dyn_cast<PathDiagnosticCallPiece>(I->get())) 264 removeEdgesToDefaultInitializers(C->path); 265 266 if (auto *M = dyn_cast<PathDiagnosticMacroPiece>(I->get())) 267 removeEdgesToDefaultInitializers(M->subPieces); 268 269 if (auto *CF = dyn_cast<PathDiagnosticControlFlowPiece>(I->get())) { 270 const Stmt *Start = CF->getStartLocation().asStmt(); 271 const Stmt *End = CF->getEndLocation().asStmt(); 272 if (Start && isa<CXXDefaultInitExpr>(Start)) { 273 I = Pieces.erase(I); 274 continue; 275 } else if (End && isa<CXXDefaultInitExpr>(End)) { 276 PathPieces::iterator Next = std::next(I); 277 if (Next != E) { 278 if (auto *NextCF = 279 dyn_cast<PathDiagnosticControlFlowPiece>(Next->get())) { 280 NextCF->setStartLocation(CF->getStartLocation()); 281 } 282 } 283 I = Pieces.erase(I); 284 continue; 285 } 286 } 287 288 I++; 289 } 290 } 291 292 /// Remove all pieces with invalid locations as these cannot be serialized. 293 /// We might have pieces with invalid locations as a result of inlining Body 294 /// Farm generated functions. 295 static void removePiecesWithInvalidLocations(PathPieces &Pieces) { 296 for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) { 297 if (auto *C = dyn_cast<PathDiagnosticCallPiece>(I->get())) 298 removePiecesWithInvalidLocations(C->path); 299 300 if (auto *M = dyn_cast<PathDiagnosticMacroPiece>(I->get())) 301 removePiecesWithInvalidLocations(M->subPieces); 302 303 if (!(*I)->getLocation().isValid() || 304 !(*I)->getLocation().asLocation().isValid()) { 305 I = Pieces.erase(I); 306 continue; 307 } 308 I++; 309 } 310 } 311 312 //===----------------------------------------------------------------------===// 313 // PathDiagnosticBuilder and its associated routines and helper objects. 314 //===----------------------------------------------------------------------===// 315 316 namespace { 317 class NodeMapClosure : public BugReport::NodeResolver { 318 InterExplodedGraphMap &M; 319 public: 320 NodeMapClosure(InterExplodedGraphMap &m) : M(m) {} 321 322 const ExplodedNode *getOriginalNode(const ExplodedNode *N) override { 323 return M.lookup(N); 324 } 325 }; 326 327 class PathDiagnosticBuilder : public BugReporterContext { 328 BugReport *R; 329 PathDiagnosticConsumer *PDC; 330 NodeMapClosure NMC; 331 public: 332 const LocationContext *LC; 333 334 PathDiagnosticBuilder(GRBugReporter &br, 335 BugReport *r, InterExplodedGraphMap &Backmap, 336 PathDiagnosticConsumer *pdc) 337 : BugReporterContext(br), 338 R(r), PDC(pdc), NMC(Backmap), LC(r->getErrorNode()->getLocationContext()) 339 {} 340 341 PathDiagnosticLocation ExecutionContinues(const ExplodedNode *N); 342 343 PathDiagnosticLocation ExecutionContinues(llvm::raw_string_ostream &os, 344 const ExplodedNode *N); 345 346 BugReport *getBugReport() { return R; } 347 348 Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); } 349 350 ParentMap& getParentMap() { return LC->getParentMap(); } 351 352 const Stmt *getParent(const Stmt *S) { 353 return getParentMap().getParent(S); 354 } 355 356 NodeMapClosure& getNodeResolver() override { return NMC; } 357 358 PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S); 359 360 PathDiagnosticConsumer::PathGenerationScheme getGenerationScheme() const { 361 return PDC ? PDC->getGenerationScheme() : PathDiagnosticConsumer::Extensive; 362 } 363 364 bool supportsLogicalOpControlFlow() const { 365 return PDC ? PDC->supportsLogicalOpControlFlow() : true; 366 } 367 }; 368 } // end anonymous namespace 369 370 PathDiagnosticLocation 371 PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode *N) { 372 if (const Stmt *S = PathDiagnosticLocation::getNextStmt(N)) 373 return PathDiagnosticLocation(S, getSourceManager(), LC); 374 375 return PathDiagnosticLocation::createDeclEnd(N->getLocationContext(), 376 getSourceManager()); 377 } 378 379 PathDiagnosticLocation 380 PathDiagnosticBuilder::ExecutionContinues(llvm::raw_string_ostream &os, 381 const ExplodedNode *N) { 382 383 // Slow, but probably doesn't matter. 384 if (os.str().empty()) 385 os << ' '; 386 387 const PathDiagnosticLocation &Loc = ExecutionContinues(N); 388 389 if (Loc.asStmt()) 390 os << "Execution continues on line " 391 << getSourceManager().getExpansionLineNumber(Loc.asLocation()) 392 << '.'; 393 else { 394 os << "Execution jumps to the end of the "; 395 const Decl *D = N->getLocationContext()->getDecl(); 396 if (isa<ObjCMethodDecl>(D)) 397 os << "method"; 398 else if (isa<FunctionDecl>(D)) 399 os << "function"; 400 else { 401 assert(isa<BlockDecl>(D)); 402 os << "anonymous block"; 403 } 404 os << '.'; 405 } 406 407 return Loc; 408 } 409 410 static const Stmt *getEnclosingParent(const Stmt *S, const ParentMap &PM) { 411 if (isa<Expr>(S) && PM.isConsumedExpr(cast<Expr>(S))) 412 return PM.getParentIgnoreParens(S); 413 414 const Stmt *Parent = PM.getParentIgnoreParens(S); 415 if (!Parent) 416 return nullptr; 417 418 switch (Parent->getStmtClass()) { 419 case Stmt::ForStmtClass: 420 case Stmt::DoStmtClass: 421 case Stmt::WhileStmtClass: 422 case Stmt::ObjCForCollectionStmtClass: 423 case Stmt::CXXForRangeStmtClass: 424 return Parent; 425 default: 426 break; 427 } 428 429 return nullptr; 430 } 431 432 static PathDiagnosticLocation 433 getEnclosingStmtLocation(const Stmt *S, SourceManager &SMgr, const ParentMap &P, 434 const LocationContext *LC, bool allowNestedContexts) { 435 if (!S) 436 return PathDiagnosticLocation(); 437 438 while (const Stmt *Parent = getEnclosingParent(S, P)) { 439 switch (Parent->getStmtClass()) { 440 case Stmt::BinaryOperatorClass: { 441 const BinaryOperator *B = cast<BinaryOperator>(Parent); 442 if (B->isLogicalOp()) 443 return PathDiagnosticLocation(allowNestedContexts ? B : S, SMgr, LC); 444 break; 445 } 446 case Stmt::CompoundStmtClass: 447 case Stmt::StmtExprClass: 448 return PathDiagnosticLocation(S, SMgr, LC); 449 case Stmt::ChooseExprClass: 450 // Similar to '?' if we are referring to condition, just have the edge 451 // point to the entire choose expression. 452 if (allowNestedContexts || cast<ChooseExpr>(Parent)->getCond() == S) 453 return PathDiagnosticLocation(Parent, SMgr, LC); 454 else 455 return PathDiagnosticLocation(S, SMgr, LC); 456 case Stmt::BinaryConditionalOperatorClass: 457 case Stmt::ConditionalOperatorClass: 458 // For '?', if we are referring to condition, just have the edge point 459 // to the entire '?' expression. 460 if (allowNestedContexts || 461 cast<AbstractConditionalOperator>(Parent)->getCond() == S) 462 return PathDiagnosticLocation(Parent, SMgr, LC); 463 else 464 return PathDiagnosticLocation(S, SMgr, LC); 465 case Stmt::CXXForRangeStmtClass: 466 if (cast<CXXForRangeStmt>(Parent)->getBody() == S) 467 return PathDiagnosticLocation(S, SMgr, LC); 468 break; 469 case Stmt::DoStmtClass: 470 return PathDiagnosticLocation(S, SMgr, LC); 471 case Stmt::ForStmtClass: 472 if (cast<ForStmt>(Parent)->getBody() == S) 473 return PathDiagnosticLocation(S, SMgr, LC); 474 break; 475 case Stmt::IfStmtClass: 476 if (cast<IfStmt>(Parent)->getCond() != S) 477 return PathDiagnosticLocation(S, SMgr, LC); 478 break; 479 case Stmt::ObjCForCollectionStmtClass: 480 if (cast<ObjCForCollectionStmt>(Parent)->getBody() == S) 481 return PathDiagnosticLocation(S, SMgr, LC); 482 break; 483 case Stmt::WhileStmtClass: 484 if (cast<WhileStmt>(Parent)->getCond() != S) 485 return PathDiagnosticLocation(S, SMgr, LC); 486 break; 487 default: 488 break; 489 } 490 491 S = Parent; 492 } 493 494 assert(S && "Cannot have null Stmt for PathDiagnosticLocation"); 495 496 return PathDiagnosticLocation(S, SMgr, LC); 497 } 498 499 PathDiagnosticLocation 500 PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) { 501 assert(S && "Null Stmt passed to getEnclosingStmtLocation"); 502 return ::getEnclosingStmtLocation(S, getSourceManager(), getParentMap(), LC, 503 /*allowNestedContexts=*/false); 504 } 505 506 //===----------------------------------------------------------------------===// 507 // "Visitors only" path diagnostic generation algorithm. 508 //===----------------------------------------------------------------------===// 509 static bool GenerateVisitorsOnlyPathDiagnostic( 510 PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N, 511 ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) { 512 // All path generation skips the very first node (the error node). 513 // This is because there is special handling for the end-of-path note. 514 N = N->getFirstPred(); 515 if (!N) 516 return true; 517 518 BugReport *R = PDB.getBugReport(); 519 while (const ExplodedNode *Pred = N->getFirstPred()) { 520 for (auto &V : visitors) 521 // Visit all the node pairs, but throw the path pieces away. 522 V->VisitNode(N, Pred, PDB, *R); 523 524 N = Pred; 525 } 526 527 return R->isValid(); 528 } 529 530 //===----------------------------------------------------------------------===// 531 // "Minimal" path diagnostic generation algorithm. 532 //===----------------------------------------------------------------------===// 533 typedef std::pair<PathDiagnosticCallPiece*, const ExplodedNode*> StackDiagPair; 534 typedef SmallVector<StackDiagPair, 6> StackDiagVector; 535 536 static void updateStackPiecesWithMessage(PathDiagnosticPiece &P, 537 StackDiagVector &CallStack) { 538 // If the piece contains a special message, add it to all the call 539 // pieces on the active stack. 540 if (PathDiagnosticEventPiece *ep = dyn_cast<PathDiagnosticEventPiece>(&P)) { 541 542 if (ep->hasCallStackHint()) 543 for (StackDiagVector::iterator I = CallStack.begin(), 544 E = CallStack.end(); I != E; ++I) { 545 PathDiagnosticCallPiece *CP = I->first; 546 const ExplodedNode *N = I->second; 547 std::string stackMsg = ep->getCallStackMessage(N); 548 549 // The last message on the path to final bug is the most important 550 // one. Since we traverse the path backwards, do not add the message 551 // if one has been previously added. 552 if (!CP->hasCallStackMessage()) 553 CP->setCallStackMessage(stackMsg); 554 } 555 } 556 } 557 558 static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM); 559 560 static bool GenerateMinimalPathDiagnostic( 561 PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N, 562 LocationContextMap &LCM, 563 ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) { 564 565 SourceManager& SMgr = PDB.getSourceManager(); 566 const LocationContext *LC = PDB.LC; 567 const ExplodedNode *NextNode = N->pred_empty() 568 ? nullptr : *(N->pred_begin()); 569 570 StackDiagVector CallStack; 571 572 while (NextNode) { 573 N = NextNode; 574 PDB.LC = N->getLocationContext(); 575 NextNode = N->getFirstPred(); 576 577 ProgramPoint P = N->getLocation(); 578 579 do { 580 if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) { 581 auto C = PathDiagnosticCallPiece::construct(N, *CE, SMgr); 582 // Record the mapping from call piece to LocationContext. 583 LCM[&C->path] = CE->getCalleeContext(); 584 auto *P = C.get(); 585 PD.getActivePath().push_front(std::move(C)); 586 PD.pushActivePath(&P->path); 587 CallStack.push_back(StackDiagPair(P, N)); 588 break; 589 } 590 591 if (Optional<CallEnter> CE = P.getAs<CallEnter>()) { 592 // Flush all locations, and pop the active path. 593 bool VisitedEntireCall = PD.isWithinCall(); 594 PD.popActivePath(); 595 596 // Either we just added a bunch of stuff to the top-level path, or 597 // we have a previous CallExitEnd. If the former, it means that the 598 // path terminated within a function call. We must then take the 599 // current contents of the active path and place it within 600 // a new PathDiagnosticCallPiece. 601 PathDiagnosticCallPiece *C; 602 if (VisitedEntireCall) { 603 C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front().get()); 604 } else { 605 const Decl *Caller = CE->getLocationContext()->getDecl(); 606 C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller); 607 // Record the mapping from call piece to LocationContext. 608 LCM[&C->path] = CE->getCalleeContext(); 609 } 610 611 C->setCallee(*CE, SMgr); 612 if (!CallStack.empty()) { 613 assert(CallStack.back().first == C); 614 CallStack.pop_back(); 615 } 616 break; 617 } 618 619 if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) { 620 const CFGBlock *Src = BE->getSrc(); 621 const CFGBlock *Dst = BE->getDst(); 622 const Stmt *T = Src->getTerminator(); 623 624 if (!T) 625 break; 626 627 PathDiagnosticLocation Start = 628 PathDiagnosticLocation::createBegin(T, SMgr, 629 N->getLocationContext()); 630 631 switch (T->getStmtClass()) { 632 default: 633 break; 634 635 case Stmt::GotoStmtClass: 636 case Stmt::IndirectGotoStmtClass: { 637 const Stmt *S = PathDiagnosticLocation::getNextStmt(N); 638 639 if (!S) 640 break; 641 642 std::string sbuf; 643 llvm::raw_string_ostream os(sbuf); 644 const PathDiagnosticLocation &End = PDB.getEnclosingStmtLocation(S); 645 646 os << "Control jumps to line " 647 << End.asLocation().getExpansionLineNumber(); 648 PD.getActivePath().push_front( 649 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 650 os.str())); 651 break; 652 } 653 654 case Stmt::SwitchStmtClass: { 655 // Figure out what case arm we took. 656 std::string sbuf; 657 llvm::raw_string_ostream os(sbuf); 658 659 if (const Stmt *S = Dst->getLabel()) { 660 PathDiagnosticLocation End(S, SMgr, LC); 661 662 switch (S->getStmtClass()) { 663 default: 664 os << "No cases match in the switch statement. " 665 "Control jumps to line " 666 << End.asLocation().getExpansionLineNumber(); 667 break; 668 case Stmt::DefaultStmtClass: 669 os << "Control jumps to the 'default' case at line " 670 << End.asLocation().getExpansionLineNumber(); 671 break; 672 673 case Stmt::CaseStmtClass: { 674 os << "Control jumps to 'case "; 675 const CaseStmt *Case = cast<CaseStmt>(S); 676 const Expr *LHS = Case->getLHS()->IgnoreParenCasts(); 677 678 // Determine if it is an enum. 679 bool GetRawInt = true; 680 681 if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS)) { 682 // FIXME: Maybe this should be an assertion. Are there cases 683 // were it is not an EnumConstantDecl? 684 const EnumConstantDecl *D = 685 dyn_cast<EnumConstantDecl>(DR->getDecl()); 686 687 if (D) { 688 GetRawInt = false; 689 os << *D; 690 } 691 } 692 693 if (GetRawInt) 694 os << LHS->EvaluateKnownConstInt(PDB.getASTContext()); 695 696 os << ":' at line " 697 << End.asLocation().getExpansionLineNumber(); 698 break; 699 } 700 } 701 PD.getActivePath().push_front( 702 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 703 os.str())); 704 } 705 else { 706 os << "'Default' branch taken. "; 707 const PathDiagnosticLocation &End = PDB.ExecutionContinues(os, N); 708 PD.getActivePath().push_front( 709 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 710 os.str())); 711 } 712 713 break; 714 } 715 716 case Stmt::BreakStmtClass: 717 case Stmt::ContinueStmtClass: { 718 std::string sbuf; 719 llvm::raw_string_ostream os(sbuf); 720 PathDiagnosticLocation End = PDB.ExecutionContinues(os, N); 721 PD.getActivePath().push_front( 722 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 723 os.str())); 724 break; 725 } 726 727 // Determine control-flow for ternary '?'. 728 case Stmt::BinaryConditionalOperatorClass: 729 case Stmt::ConditionalOperatorClass: { 730 std::string sbuf; 731 llvm::raw_string_ostream os(sbuf); 732 os << "'?' condition is "; 733 734 if (*(Src->succ_begin()+1) == Dst) 735 os << "false"; 736 else 737 os << "true"; 738 739 PathDiagnosticLocation End = PDB.ExecutionContinues(N); 740 741 if (const Stmt *S = End.asStmt()) 742 End = PDB.getEnclosingStmtLocation(S); 743 744 PD.getActivePath().push_front( 745 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 746 os.str())); 747 break; 748 } 749 750 // Determine control-flow for short-circuited '&&' and '||'. 751 case Stmt::BinaryOperatorClass: { 752 if (!PDB.supportsLogicalOpControlFlow()) 753 break; 754 755 const BinaryOperator *B = cast<BinaryOperator>(T); 756 std::string sbuf; 757 llvm::raw_string_ostream os(sbuf); 758 os << "Left side of '"; 759 760 if (B->getOpcode() == BO_LAnd) { 761 os << "&&" << "' is "; 762 763 if (*(Src->succ_begin()+1) == Dst) { 764 os << "false"; 765 PathDiagnosticLocation End(B->getLHS(), SMgr, LC); 766 PathDiagnosticLocation Start = 767 PathDiagnosticLocation::createOperatorLoc(B, SMgr); 768 PD.getActivePath().push_front( 769 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 770 os.str())); 771 } 772 else { 773 os << "true"; 774 PathDiagnosticLocation Start(B->getLHS(), SMgr, LC); 775 PathDiagnosticLocation End = PDB.ExecutionContinues(N); 776 PD.getActivePath().push_front( 777 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 778 os.str())); 779 } 780 } 781 else { 782 assert(B->getOpcode() == BO_LOr); 783 os << "||" << "' is "; 784 785 if (*(Src->succ_begin()+1) == Dst) { 786 os << "false"; 787 PathDiagnosticLocation Start(B->getLHS(), SMgr, LC); 788 PathDiagnosticLocation End = PDB.ExecutionContinues(N); 789 PD.getActivePath().push_front( 790 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 791 os.str())); 792 } 793 else { 794 os << "true"; 795 PathDiagnosticLocation End(B->getLHS(), SMgr, LC); 796 PathDiagnosticLocation Start = 797 PathDiagnosticLocation::createOperatorLoc(B, SMgr); 798 PD.getActivePath().push_front( 799 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 800 os.str())); 801 } 802 } 803 804 break; 805 } 806 807 case Stmt::DoStmtClass: { 808 if (*(Src->succ_begin()) == Dst) { 809 std::string sbuf; 810 llvm::raw_string_ostream os(sbuf); 811 812 os << "Loop condition is true. "; 813 PathDiagnosticLocation End = PDB.ExecutionContinues(os, N); 814 815 if (const Stmt *S = End.asStmt()) 816 End = PDB.getEnclosingStmtLocation(S); 817 818 PD.getActivePath().push_front( 819 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 820 os.str())); 821 } 822 else { 823 PathDiagnosticLocation End = PDB.ExecutionContinues(N); 824 825 if (const Stmt *S = End.asStmt()) 826 End = PDB.getEnclosingStmtLocation(S); 827 828 PD.getActivePath().push_front( 829 std::make_shared<PathDiagnosticControlFlowPiece>( 830 Start, End, "Loop condition is false. Exiting loop")); 831 } 832 833 break; 834 } 835 836 case Stmt::WhileStmtClass: 837 case Stmt::ForStmtClass: { 838 if (*(Src->succ_begin()+1) == Dst) { 839 std::string sbuf; 840 llvm::raw_string_ostream os(sbuf); 841 842 os << "Loop condition is false. "; 843 PathDiagnosticLocation End = PDB.ExecutionContinues(os, N); 844 if (const Stmt *S = End.asStmt()) 845 End = PDB.getEnclosingStmtLocation(S); 846 847 PD.getActivePath().push_front( 848 std::make_shared<PathDiagnosticControlFlowPiece>(Start, End, 849 os.str())); 850 } 851 else { 852 PathDiagnosticLocation End = PDB.ExecutionContinues(N); 853 if (const Stmt *S = End.asStmt()) 854 End = PDB.getEnclosingStmtLocation(S); 855 856 PD.getActivePath().push_front( 857 std::make_shared<PathDiagnosticControlFlowPiece>( 858 Start, End, "Loop condition is true. Entering loop body")); 859 } 860 861 break; 862 } 863 864 case Stmt::IfStmtClass: { 865 PathDiagnosticLocation End = PDB.ExecutionContinues(N); 866 867 if (const Stmt *S = End.asStmt()) 868 End = PDB.getEnclosingStmtLocation(S); 869 870 if (*(Src->succ_begin()+1) == Dst) 871 PD.getActivePath().push_front( 872 std::make_shared<PathDiagnosticControlFlowPiece>( 873 Start, End, "Taking false branch")); 874 else 875 PD.getActivePath().push_front( 876 std::make_shared<PathDiagnosticControlFlowPiece>( 877 Start, End, "Taking true branch")); 878 879 break; 880 } 881 } 882 } 883 } while(0); 884 885 if (NextNode) { 886 // Add diagnostic pieces from custom visitors. 887 BugReport *R = PDB.getBugReport(); 888 llvm::FoldingSet<PathDiagnosticPiece> DeduplicationSet; 889 for (auto &V : visitors) { 890 if (auto p = V->VisitNode(N, NextNode, PDB, *R)) { 891 if (DeduplicationSet.GetOrInsertNode(p.get()) != p.get()) 892 continue; 893 894 updateStackPiecesWithMessage(*p, CallStack); 895 PD.getActivePath().push_front(std::move(p)); 896 } 897 } 898 } 899 } 900 901 if (!PDB.getBugReport()->isValid()) 902 return false; 903 904 // After constructing the full PathDiagnostic, do a pass over it to compact 905 // PathDiagnosticPieces that occur within a macro. 906 CompactPathDiagnostic(PD.getMutablePieces(), PDB.getSourceManager()); 907 return true; 908 } 909 910 //===----------------------------------------------------------------------===// 911 // "Extensive" PathDiagnostic generation. 912 //===----------------------------------------------------------------------===// 913 914 static bool IsControlFlowExpr(const Stmt *S) { 915 const Expr *E = dyn_cast<Expr>(S); 916 917 if (!E) 918 return false; 919 920 E = E->IgnoreParenCasts(); 921 922 if (isa<AbstractConditionalOperator>(E)) 923 return true; 924 925 if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E)) 926 if (B->isLogicalOp()) 927 return true; 928 929 return false; 930 } 931 932 namespace { 933 class ContextLocation : public PathDiagnosticLocation { 934 bool IsDead; 935 public: 936 ContextLocation(const PathDiagnosticLocation &L, bool isdead = false) 937 : PathDiagnosticLocation(L), IsDead(isdead) {} 938 939 void markDead() { IsDead = true; } 940 bool isDead() const { return IsDead; } 941 }; 942 943 static PathDiagnosticLocation cleanUpLocation(PathDiagnosticLocation L, 944 const LocationContext *LC, 945 bool firstCharOnly = false) { 946 if (const Stmt *S = L.asStmt()) { 947 const Stmt *Original = S; 948 while (1) { 949 // Adjust the location for some expressions that are best referenced 950 // by one of their subexpressions. 951 switch (S->getStmtClass()) { 952 default: 953 break; 954 case Stmt::ParenExprClass: 955 case Stmt::GenericSelectionExprClass: 956 S = cast<Expr>(S)->IgnoreParens(); 957 firstCharOnly = true; 958 continue; 959 case Stmt::BinaryConditionalOperatorClass: 960 case Stmt::ConditionalOperatorClass: 961 S = cast<AbstractConditionalOperator>(S)->getCond(); 962 firstCharOnly = true; 963 continue; 964 case Stmt::ChooseExprClass: 965 S = cast<ChooseExpr>(S)->getCond(); 966 firstCharOnly = true; 967 continue; 968 case Stmt::BinaryOperatorClass: 969 S = cast<BinaryOperator>(S)->getLHS(); 970 firstCharOnly = true; 971 continue; 972 } 973 974 break; 975 } 976 977 if (S != Original) 978 L = PathDiagnosticLocation(S, L.getManager(), LC); 979 } 980 981 if (firstCharOnly) 982 L = PathDiagnosticLocation::createSingleLocation(L); 983 984 return L; 985 } 986 987 class EdgeBuilder { 988 std::vector<ContextLocation> CLocs; 989 typedef std::vector<ContextLocation>::iterator iterator; 990 PathDiagnostic &PD; 991 PathDiagnosticBuilder &PDB; 992 PathDiagnosticLocation PrevLoc; 993 994 bool IsConsumedExpr(const PathDiagnosticLocation &L); 995 996 bool containsLocation(const PathDiagnosticLocation &Container, 997 const PathDiagnosticLocation &Containee); 998 999 PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L); 1000 1001 1002 1003 void popLocation() { 1004 if (!CLocs.back().isDead() && CLocs.back().asLocation().isFileID()) { 1005 // For contexts, we only one the first character as the range. 1006 rawAddEdge(cleanUpLocation(CLocs.back(), PDB.LC, true)); 1007 } 1008 CLocs.pop_back(); 1009 } 1010 1011 public: 1012 EdgeBuilder(PathDiagnostic &pd, PathDiagnosticBuilder &pdb) 1013 : PD(pd), PDB(pdb) { 1014 1015 // If the PathDiagnostic already has pieces, add the enclosing statement 1016 // of the first piece as a context as well. 1017 if (!PD.path.empty()) { 1018 PrevLoc = (*PD.path.begin())->getLocation(); 1019 1020 if (const Stmt *S = PrevLoc.asStmt()) 1021 addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt()); 1022 } 1023 } 1024 1025 ~EdgeBuilder() { 1026 while (!CLocs.empty()) popLocation(); 1027 1028 // Finally, add an initial edge from the start location of the first 1029 // statement (if it doesn't already exist). 1030 PathDiagnosticLocation L = PathDiagnosticLocation::createDeclBegin( 1031 PDB.LC, 1032 PDB.getSourceManager()); 1033 if (L.isValid()) 1034 rawAddEdge(L); 1035 } 1036 1037 void flushLocations() { 1038 while (!CLocs.empty()) 1039 popLocation(); 1040 PrevLoc = PathDiagnosticLocation(); 1041 } 1042 1043 void addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd = false, 1044 bool IsPostJump = false); 1045 1046 void rawAddEdge(PathDiagnosticLocation NewLoc); 1047 1048 void addContext(const Stmt *S); 1049 void addContext(const PathDiagnosticLocation &L); 1050 void addExtendedContext(const Stmt *S); 1051 }; 1052 } // end anonymous namespace 1053 1054 1055 PathDiagnosticLocation 1056 EdgeBuilder::getContextLocation(const PathDiagnosticLocation &L) { 1057 if (const Stmt *S = L.asStmt()) { 1058 if (IsControlFlowExpr(S)) 1059 return L; 1060 1061 return PDB.getEnclosingStmtLocation(S); 1062 } 1063 1064 return L; 1065 } 1066 1067 bool EdgeBuilder::containsLocation(const PathDiagnosticLocation &Container, 1068 const PathDiagnosticLocation &Containee) { 1069 1070 if (Container == Containee) 1071 return true; 1072 1073 if (Container.asDecl()) 1074 return true; 1075 1076 if (const Stmt *S = Containee.asStmt()) 1077 if (const Stmt *ContainerS = Container.asStmt()) { 1078 while (S) { 1079 if (S == ContainerS) 1080 return true; 1081 S = PDB.getParent(S); 1082 } 1083 return false; 1084 } 1085 1086 // Less accurate: compare using source ranges. 1087 SourceRange ContainerR = Container.asRange(); 1088 SourceRange ContaineeR = Containee.asRange(); 1089 1090 SourceManager &SM = PDB.getSourceManager(); 1091 SourceLocation ContainerRBeg = SM.getExpansionLoc(ContainerR.getBegin()); 1092 SourceLocation ContainerREnd = SM.getExpansionLoc(ContainerR.getEnd()); 1093 SourceLocation ContaineeRBeg = SM.getExpansionLoc(ContaineeR.getBegin()); 1094 SourceLocation ContaineeREnd = SM.getExpansionLoc(ContaineeR.getEnd()); 1095 1096 unsigned ContainerBegLine = SM.getExpansionLineNumber(ContainerRBeg); 1097 unsigned ContainerEndLine = SM.getExpansionLineNumber(ContainerREnd); 1098 unsigned ContaineeBegLine = SM.getExpansionLineNumber(ContaineeRBeg); 1099 unsigned ContaineeEndLine = SM.getExpansionLineNumber(ContaineeREnd); 1100 1101 assert(ContainerBegLine <= ContainerEndLine); 1102 assert(ContaineeBegLine <= ContaineeEndLine); 1103 1104 return (ContainerBegLine <= ContaineeBegLine && 1105 ContainerEndLine >= ContaineeEndLine && 1106 (ContainerBegLine != ContaineeBegLine || 1107 SM.getExpansionColumnNumber(ContainerRBeg) <= 1108 SM.getExpansionColumnNumber(ContaineeRBeg)) && 1109 (ContainerEndLine != ContaineeEndLine || 1110 SM.getExpansionColumnNumber(ContainerREnd) >= 1111 SM.getExpansionColumnNumber(ContaineeREnd))); 1112 } 1113 1114 void EdgeBuilder::rawAddEdge(PathDiagnosticLocation NewLoc) { 1115 if (!PrevLoc.isValid()) { 1116 PrevLoc = NewLoc; 1117 return; 1118 } 1119 1120 const PathDiagnosticLocation &NewLocClean = cleanUpLocation(NewLoc, PDB.LC); 1121 const PathDiagnosticLocation &PrevLocClean = cleanUpLocation(PrevLoc, PDB.LC); 1122 1123 if (PrevLocClean.asLocation().isInvalid()) { 1124 PrevLoc = NewLoc; 1125 return; 1126 } 1127 1128 if (NewLocClean.asLocation() == PrevLocClean.asLocation()) 1129 return; 1130 1131 // FIXME: Ignore intra-macro edges for now. 1132 if (NewLocClean.asLocation().getExpansionLoc() == 1133 PrevLocClean.asLocation().getExpansionLoc()) 1134 return; 1135 1136 PD.getActivePath().push_front( 1137 std::make_shared<PathDiagnosticControlFlowPiece>(NewLocClean, 1138 PrevLocClean)); 1139 PrevLoc = NewLoc; 1140 } 1141 1142 void EdgeBuilder::addEdge(PathDiagnosticLocation NewLoc, bool alwaysAdd, 1143 bool IsPostJump) { 1144 1145 if (!alwaysAdd && NewLoc.asLocation().isMacroID()) 1146 return; 1147 1148 const PathDiagnosticLocation &CLoc = getContextLocation(NewLoc); 1149 1150 while (!CLocs.empty()) { 1151 ContextLocation &TopContextLoc = CLocs.back(); 1152 1153 // Is the top location context the same as the one for the new location? 1154 if (TopContextLoc == CLoc) { 1155 if (alwaysAdd) { 1156 if (IsConsumedExpr(TopContextLoc)) 1157 TopContextLoc.markDead(); 1158 1159 rawAddEdge(NewLoc); 1160 } 1161 1162 if (IsPostJump) 1163 TopContextLoc.markDead(); 1164 return; 1165 } 1166 1167 if (containsLocation(TopContextLoc, CLoc)) { 1168 if (alwaysAdd) { 1169 rawAddEdge(NewLoc); 1170 1171 if (IsConsumedExpr(CLoc)) { 1172 CLocs.push_back(ContextLocation(CLoc, /*IsDead=*/true)); 1173 return; 1174 } 1175 } 1176 1177 CLocs.push_back(ContextLocation(CLoc, /*IsDead=*/IsPostJump)); 1178 return; 1179 } 1180 1181 // Context does not contain the location. Flush it. 1182 popLocation(); 1183 } 1184 1185 // If we reach here, there is no enclosing context. Just add the edge. 1186 rawAddEdge(NewLoc); 1187 } 1188 1189 bool EdgeBuilder::IsConsumedExpr(const PathDiagnosticLocation &L) { 1190 if (const Expr *X = dyn_cast_or_null<Expr>(L.asStmt())) 1191 return PDB.getParentMap().isConsumedExpr(X) && !IsControlFlowExpr(X); 1192 1193 return false; 1194 } 1195 1196 void EdgeBuilder::addExtendedContext(const Stmt *S) { 1197 if (!S) 1198 return; 1199 1200 const Stmt *Parent = PDB.getParent(S); 1201 while (Parent) { 1202 if (isa<CompoundStmt>(Parent)) 1203 Parent = PDB.getParent(Parent); 1204 else 1205 break; 1206 } 1207 1208 if (Parent) { 1209 switch (Parent->getStmtClass()) { 1210 case Stmt::DoStmtClass: 1211 case Stmt::ObjCAtSynchronizedStmtClass: 1212 addContext(Parent); 1213 default: 1214 break; 1215 } 1216 } 1217 1218 addContext(S); 1219 } 1220 1221 void EdgeBuilder::addContext(const Stmt *S) { 1222 if (!S) 1223 return; 1224 1225 PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.LC); 1226 addContext(L); 1227 } 1228 1229 void EdgeBuilder::addContext(const PathDiagnosticLocation &L) { 1230 while (!CLocs.empty()) { 1231 const PathDiagnosticLocation &TopContextLoc = CLocs.back(); 1232 1233 // Is the top location context the same as the one for the new location? 1234 if (TopContextLoc == L) 1235 return; 1236 1237 if (containsLocation(TopContextLoc, L)) { 1238 CLocs.push_back(L); 1239 return; 1240 } 1241 1242 // Context does not contain the location. Flush it. 1243 popLocation(); 1244 } 1245 1246 CLocs.push_back(L); 1247 } 1248 1249 // Cone-of-influence: support the reverse propagation of "interesting" symbols 1250 // and values by tracing interesting calculations backwards through evaluated 1251 // expressions along a path. This is probably overly complicated, but the idea 1252 // is that if an expression computed an "interesting" value, the child 1253 // expressions are are also likely to be "interesting" as well (which then 1254 // propagates to the values they in turn compute). This reverse propagation 1255 // is needed to track interesting correlations across function call boundaries, 1256 // where formal arguments bind to actual arguments, etc. This is also needed 1257 // because the constraint solver sometimes simplifies certain symbolic values 1258 // into constants when appropriate, and this complicates reasoning about 1259 // interesting values. 1260 typedef llvm::DenseSet<const Expr *> InterestingExprs; 1261 1262 static void reversePropagateIntererstingSymbols(BugReport &R, 1263 InterestingExprs &IE, 1264 const ProgramState *State, 1265 const Expr *Ex, 1266 const LocationContext *LCtx) { 1267 SVal V = State->getSVal(Ex, LCtx); 1268 if (!(R.isInteresting(V) || IE.count(Ex))) 1269 return; 1270 1271 switch (Ex->getStmtClass()) { 1272 default: 1273 if (!isa<CastExpr>(Ex)) 1274 break; 1275 // Fall through. 1276 case Stmt::BinaryOperatorClass: 1277 case Stmt::UnaryOperatorClass: { 1278 for (const Stmt *SubStmt : Ex->children()) { 1279 if (const Expr *child = dyn_cast_or_null<Expr>(SubStmt)) { 1280 IE.insert(child); 1281 SVal ChildV = State->getSVal(child, LCtx); 1282 R.markInteresting(ChildV); 1283 } 1284 } 1285 break; 1286 } 1287 } 1288 1289 R.markInteresting(V); 1290 } 1291 1292 static void reversePropagateInterestingSymbols(BugReport &R, 1293 InterestingExprs &IE, 1294 const ProgramState *State, 1295 const LocationContext *CalleeCtx, 1296 const LocationContext *CallerCtx) 1297 { 1298 // FIXME: Handle non-CallExpr-based CallEvents. 1299 const StackFrameContext *Callee = CalleeCtx->getCurrentStackFrame(); 1300 const Stmt *CallSite = Callee->getCallSite(); 1301 if (const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite)) { 1302 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeCtx->getDecl())) { 1303 FunctionDecl::param_const_iterator PI = FD->param_begin(), 1304 PE = FD->param_end(); 1305 CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end(); 1306 for (; AI != AE && PI != PE; ++AI, ++PI) { 1307 if (const Expr *ArgE = *AI) { 1308 if (const ParmVarDecl *PD = *PI) { 1309 Loc LV = State->getLValue(PD, CalleeCtx); 1310 if (R.isInteresting(LV) || R.isInteresting(State->getRawSVal(LV))) 1311 IE.insert(ArgE); 1312 } 1313 } 1314 } 1315 } 1316 } 1317 } 1318 1319 //===----------------------------------------------------------------------===// 1320 // Functions for determining if a loop was executed 0 times. 1321 //===----------------------------------------------------------------------===// 1322 1323 static bool isLoop(const Stmt *Term) { 1324 switch (Term->getStmtClass()) { 1325 case Stmt::ForStmtClass: 1326 case Stmt::WhileStmtClass: 1327 case Stmt::ObjCForCollectionStmtClass: 1328 case Stmt::CXXForRangeStmtClass: 1329 return true; 1330 default: 1331 // Note that we intentionally do not include do..while here. 1332 return false; 1333 } 1334 } 1335 1336 static bool isJumpToFalseBranch(const BlockEdge *BE) { 1337 const CFGBlock *Src = BE->getSrc(); 1338 assert(Src->succ_size() == 2); 1339 return (*(Src->succ_begin()+1) == BE->getDst()); 1340 } 1341 1342 /// Return true if the terminator is a loop and the destination is the 1343 /// false branch. 1344 static bool isLoopJumpPastBody(const Stmt *Term, const BlockEdge *BE) { 1345 if (!isLoop(Term)) 1346 return false; 1347 1348 // Did we take the false branch? 1349 return isJumpToFalseBranch(BE); 1350 } 1351 1352 static bool isContainedByStmt(ParentMap &PM, const Stmt *S, const Stmt *SubS) { 1353 while (SubS) { 1354 if (SubS == S) 1355 return true; 1356 SubS = PM.getParent(SubS); 1357 } 1358 return false; 1359 } 1360 1361 static const Stmt *getStmtBeforeCond(ParentMap &PM, const Stmt *Term, 1362 const ExplodedNode *N) { 1363 while (N) { 1364 Optional<StmtPoint> SP = N->getLocation().getAs<StmtPoint>(); 1365 if (SP) { 1366 const Stmt *S = SP->getStmt(); 1367 if (!isContainedByStmt(PM, Term, S)) 1368 return S; 1369 } 1370 N = N->getFirstPred(); 1371 } 1372 return nullptr; 1373 } 1374 1375 static bool isInLoopBody(ParentMap &PM, const Stmt *S, const Stmt *Term) { 1376 const Stmt *LoopBody = nullptr; 1377 switch (Term->getStmtClass()) { 1378 case Stmt::CXXForRangeStmtClass: { 1379 const CXXForRangeStmt *FR = cast<CXXForRangeStmt>(Term); 1380 if (isContainedByStmt(PM, FR->getInc(), S)) 1381 return true; 1382 if (isContainedByStmt(PM, FR->getLoopVarStmt(), S)) 1383 return true; 1384 LoopBody = FR->getBody(); 1385 break; 1386 } 1387 case Stmt::ForStmtClass: { 1388 const ForStmt *FS = cast<ForStmt>(Term); 1389 if (isContainedByStmt(PM, FS->getInc(), S)) 1390 return true; 1391 LoopBody = FS->getBody(); 1392 break; 1393 } 1394 case Stmt::ObjCForCollectionStmtClass: { 1395 const ObjCForCollectionStmt *FC = cast<ObjCForCollectionStmt>(Term); 1396 LoopBody = FC->getBody(); 1397 break; 1398 } 1399 case Stmt::WhileStmtClass: 1400 LoopBody = cast<WhileStmt>(Term)->getBody(); 1401 break; 1402 default: 1403 return false; 1404 } 1405 return isContainedByStmt(PM, LoopBody, S); 1406 } 1407 1408 //===----------------------------------------------------------------------===// 1409 // Top-level logic for generating extensive path diagnostics. 1410 //===----------------------------------------------------------------------===// 1411 1412 static bool GenerateExtensivePathDiagnostic( 1413 PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N, 1414 LocationContextMap &LCM, 1415 ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) { 1416 EdgeBuilder EB(PD, PDB); 1417 const SourceManager& SM = PDB.getSourceManager(); 1418 StackDiagVector CallStack; 1419 InterestingExprs IE; 1420 1421 const ExplodedNode *NextNode = N->pred_empty() ? nullptr : *(N->pred_begin()); 1422 while (NextNode) { 1423 N = NextNode; 1424 NextNode = N->getFirstPred(); 1425 ProgramPoint P = N->getLocation(); 1426 1427 do { 1428 if (Optional<PostStmt> PS = P.getAs<PostStmt>()) { 1429 if (const Expr *Ex = PS->getStmtAs<Expr>()) 1430 reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE, 1431 N->getState().get(), Ex, 1432 N->getLocationContext()); 1433 } 1434 1435 if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) { 1436 const Stmt *S = CE->getCalleeContext()->getCallSite(); 1437 if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) { 1438 reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE, 1439 N->getState().get(), Ex, 1440 N->getLocationContext()); 1441 } 1442 1443 auto C = PathDiagnosticCallPiece::construct(N, *CE, SM); 1444 LCM[&C->path] = CE->getCalleeContext(); 1445 1446 EB.addEdge(C->callReturn, /*AlwaysAdd=*/true, /*IsPostJump=*/true); 1447 EB.flushLocations(); 1448 1449 auto *P = C.get(); 1450 PD.getActivePath().push_front(std::move(C)); 1451 PD.pushActivePath(&P->path); 1452 CallStack.push_back(StackDiagPair(P, N)); 1453 break; 1454 } 1455 1456 // Pop the call hierarchy if we are done walking the contents 1457 // of a function call. 1458 if (Optional<CallEnter> CE = P.getAs<CallEnter>()) { 1459 // Add an edge to the start of the function. 1460 const Decl *D = CE->getCalleeContext()->getDecl(); 1461 PathDiagnosticLocation pos = 1462 PathDiagnosticLocation::createBegin(D, SM); 1463 EB.addEdge(pos); 1464 1465 // Flush all locations, and pop the active path. 1466 bool VisitedEntireCall = PD.isWithinCall(); 1467 EB.flushLocations(); 1468 PD.popActivePath(); 1469 PDB.LC = N->getLocationContext(); 1470 1471 // Either we just added a bunch of stuff to the top-level path, or 1472 // we have a previous CallExitEnd. If the former, it means that the 1473 // path terminated within a function call. We must then take the 1474 // current contents of the active path and place it within 1475 // a new PathDiagnosticCallPiece. 1476 PathDiagnosticCallPiece *C; 1477 if (VisitedEntireCall) { 1478 C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front().get()); 1479 } else { 1480 const Decl *Caller = CE->getLocationContext()->getDecl(); 1481 C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller); 1482 LCM[&C->path] = CE->getCalleeContext(); 1483 } 1484 1485 C->setCallee(*CE, SM); 1486 EB.addContext(C->getLocation()); 1487 1488 if (!CallStack.empty()) { 1489 assert(CallStack.back().first == C); 1490 CallStack.pop_back(); 1491 } 1492 break; 1493 } 1494 1495 // Note that is important that we update the LocationContext 1496 // after looking at CallExits. CallExit basically adds an 1497 // edge in the *caller*, so we don't want to update the LocationContext 1498 // too soon. 1499 PDB.LC = N->getLocationContext(); 1500 1501 // Block edges. 1502 if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) { 1503 // Does this represent entering a call? If so, look at propagating 1504 // interesting symbols across call boundaries. 1505 if (NextNode) { 1506 const LocationContext *CallerCtx = NextNode->getLocationContext(); 1507 const LocationContext *CalleeCtx = PDB.LC; 1508 if (CallerCtx != CalleeCtx) { 1509 reversePropagateInterestingSymbols(*PDB.getBugReport(), IE, 1510 N->getState().get(), 1511 CalleeCtx, CallerCtx); 1512 } 1513 } 1514 1515 // Are we jumping to the head of a loop? Add a special diagnostic. 1516 if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) { 1517 PathDiagnosticLocation L(Loop, SM, PDB.LC); 1518 const CompoundStmt *CS = nullptr; 1519 1520 if (const ForStmt *FS = dyn_cast<ForStmt>(Loop)) 1521 CS = dyn_cast<CompoundStmt>(FS->getBody()); 1522 else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop)) 1523 CS = dyn_cast<CompoundStmt>(WS->getBody()); 1524 1525 auto p = std::make_shared<PathDiagnosticEventPiece>( 1526 L, "Looping back to the head of the loop"); 1527 p->setPrunable(true); 1528 1529 EB.addEdge(p->getLocation(), true); 1530 PD.getActivePath().push_front(std::move(p)); 1531 1532 if (CS) { 1533 PathDiagnosticLocation BL = 1534 PathDiagnosticLocation::createEndBrace(CS, SM); 1535 EB.addEdge(BL); 1536 } 1537 } 1538 1539 const CFGBlock *BSrc = BE->getSrc(); 1540 ParentMap &PM = PDB.getParentMap(); 1541 1542 if (const Stmt *Term = BSrc->getTerminator()) { 1543 // Are we jumping past the loop body without ever executing the 1544 // loop (because the condition was false)? 1545 if (isLoopJumpPastBody(Term, &*BE) && 1546 !isInLoopBody(PM, 1547 getStmtBeforeCond(PM, 1548 BSrc->getTerminatorCondition(), 1549 N), 1550 Term)) { 1551 PathDiagnosticLocation L(Term, SM, PDB.LC); 1552 auto PE = std::make_shared<PathDiagnosticEventPiece>( 1553 L, "Loop body executed 0 times"); 1554 PE->setPrunable(true); 1555 1556 EB.addEdge(PE->getLocation(), true); 1557 PD.getActivePath().push_front(std::move(PE)); 1558 } 1559 1560 // In any case, add the terminator as the current statement 1561 // context for control edges. 1562 EB.addContext(Term); 1563 } 1564 1565 break; 1566 } 1567 1568 if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>()) { 1569 Optional<CFGElement> First = BE->getFirstElement(); 1570 if (Optional<CFGStmt> S = First ? First->getAs<CFGStmt>() : None) { 1571 const Stmt *stmt = S->getStmt(); 1572 if (IsControlFlowExpr(stmt)) { 1573 // Add the proper context for '&&', '||', and '?'. 1574 EB.addContext(stmt); 1575 } 1576 else 1577 EB.addExtendedContext(PDB.getEnclosingStmtLocation(stmt).asStmt()); 1578 } 1579 1580 break; 1581 } 1582 1583 1584 } while (0); 1585 1586 if (!NextNode) 1587 continue; 1588 1589 // Add pieces from custom visitors. 1590 BugReport *R = PDB.getBugReport(); 1591 llvm::FoldingSet<PathDiagnosticPiece> DeduplicationSet; 1592 for (auto &V : visitors) { 1593 if (auto p = V->VisitNode(N, NextNode, PDB, *R)) { 1594 if (DeduplicationSet.GetOrInsertNode(p.get()) != p.get()) 1595 continue; 1596 1597 const PathDiagnosticLocation &Loc = p->getLocation(); 1598 EB.addEdge(Loc, true); 1599 updateStackPiecesWithMessage(*p, CallStack); 1600 PD.getActivePath().push_front(std::move(p)); 1601 1602 if (const Stmt *S = Loc.asStmt()) 1603 EB.addExtendedContext(PDB.getEnclosingStmtLocation(S).asStmt()); 1604 } 1605 } 1606 } 1607 1608 return PDB.getBugReport()->isValid(); 1609 } 1610 1611 /// \brief Adds a sanitized control-flow diagnostic edge to a path. 1612 static void addEdgeToPath(PathPieces &path, 1613 PathDiagnosticLocation &PrevLoc, 1614 PathDiagnosticLocation NewLoc, 1615 const LocationContext *LC) { 1616 if (!NewLoc.isValid()) 1617 return; 1618 1619 SourceLocation NewLocL = NewLoc.asLocation(); 1620 if (NewLocL.isInvalid()) 1621 return; 1622 1623 if (!PrevLoc.isValid() || !PrevLoc.asLocation().isValid()) { 1624 PrevLoc = NewLoc; 1625 return; 1626 } 1627 1628 // Ignore self-edges, which occur when there are multiple nodes at the same 1629 // statement. 1630 if (NewLoc.asStmt() && NewLoc.asStmt() == PrevLoc.asStmt()) 1631 return; 1632 1633 path.push_front( 1634 std::make_shared<PathDiagnosticControlFlowPiece>(NewLoc, PrevLoc)); 1635 PrevLoc = NewLoc; 1636 } 1637 1638 /// A customized wrapper for CFGBlock::getTerminatorCondition() 1639 /// which returns the element for ObjCForCollectionStmts. 1640 static const Stmt *getTerminatorCondition(const CFGBlock *B) { 1641 const Stmt *S = B->getTerminatorCondition(); 1642 if (const ObjCForCollectionStmt *FS = 1643 dyn_cast_or_null<ObjCForCollectionStmt>(S)) 1644 return FS->getElement(); 1645 return S; 1646 } 1647 1648 static const char StrEnteringLoop[] = "Entering loop body"; 1649 static const char StrLoopBodyZero[] = "Loop body executed 0 times"; 1650 static const char StrLoopRangeEmpty[] = 1651 "Loop body skipped when range is empty"; 1652 static const char StrLoopCollectionEmpty[] = 1653 "Loop body skipped when collection is empty"; 1654 1655 static bool GenerateAlternateExtensivePathDiagnostic( 1656 PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N, 1657 LocationContextMap &LCM, 1658 ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) { 1659 1660 BugReport *report = PDB.getBugReport(); 1661 const SourceManager& SM = PDB.getSourceManager(); 1662 StackDiagVector CallStack; 1663 InterestingExprs IE; 1664 1665 PathDiagnosticLocation PrevLoc = PD.getLocation(); 1666 1667 const ExplodedNode *NextNode = N->getFirstPred(); 1668 while (NextNode) { 1669 N = NextNode; 1670 NextNode = N->getFirstPred(); 1671 ProgramPoint P = N->getLocation(); 1672 1673 do { 1674 // Have we encountered an entrance to a call? It may be 1675 // the case that we have not encountered a matching 1676 // call exit before this point. This means that the path 1677 // terminated within the call itself. 1678 if (Optional<CallEnter> CE = P.getAs<CallEnter>()) { 1679 // Add an edge to the start of the function. 1680 const StackFrameContext *CalleeLC = CE->getCalleeContext(); 1681 const Decl *D = CalleeLC->getDecl(); 1682 // Add the edge only when the callee has body. We jump to the beginning 1683 // of the *declaration*, however we expect it to be followed by the 1684 // body. This isn't the case for autosynthesized property accessors in 1685 // Objective-C. No need for a similar extra check for CallExit points 1686 // because the exit edge comes from a statement (i.e. return), 1687 // not from declaration. 1688 if (D->hasBody()) 1689 addEdgeToPath(PD.getActivePath(), PrevLoc, 1690 PathDiagnosticLocation::createBegin(D, SM), CalleeLC); 1691 1692 // Did we visit an entire call? 1693 bool VisitedEntireCall = PD.isWithinCall(); 1694 PD.popActivePath(); 1695 1696 PathDiagnosticCallPiece *C; 1697 if (VisitedEntireCall) { 1698 PathDiagnosticPiece *P = PD.getActivePath().front().get(); 1699 C = cast<PathDiagnosticCallPiece>(P); 1700 } else { 1701 const Decl *Caller = CE->getLocationContext()->getDecl(); 1702 C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller); 1703 1704 // Since we just transferred the path over to the call piece, 1705 // reset the mapping from active to location context. 1706 assert(PD.getActivePath().size() == 1 && 1707 PD.getActivePath().front().get() == C); 1708 LCM[&PD.getActivePath()] = nullptr; 1709 1710 // Record the location context mapping for the path within 1711 // the call. 1712 assert(LCM[&C->path] == nullptr || 1713 LCM[&C->path] == CE->getCalleeContext()); 1714 LCM[&C->path] = CE->getCalleeContext(); 1715 1716 // If this is the first item in the active path, record 1717 // the new mapping from active path to location context. 1718 const LocationContext *&NewLC = LCM[&PD.getActivePath()]; 1719 if (!NewLC) 1720 NewLC = N->getLocationContext(); 1721 1722 PDB.LC = NewLC; 1723 } 1724 C->setCallee(*CE, SM); 1725 1726 // Update the previous location in the active path. 1727 PrevLoc = C->getLocation(); 1728 1729 if (!CallStack.empty()) { 1730 assert(CallStack.back().first == C); 1731 CallStack.pop_back(); 1732 } 1733 break; 1734 } 1735 1736 // Query the location context here and the previous location 1737 // as processing CallEnter may change the active path. 1738 PDB.LC = N->getLocationContext(); 1739 1740 // Record the mapping from the active path to the location 1741 // context. 1742 assert(!LCM[&PD.getActivePath()] || 1743 LCM[&PD.getActivePath()] == PDB.LC); 1744 LCM[&PD.getActivePath()] = PDB.LC; 1745 1746 // Have we encountered an exit from a function call? 1747 if (Optional<CallExitEnd> CE = P.getAs<CallExitEnd>()) { 1748 const Stmt *S = CE->getCalleeContext()->getCallSite(); 1749 // Propagate the interesting symbols accordingly. 1750 if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) { 1751 reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE, 1752 N->getState().get(), Ex, 1753 N->getLocationContext()); 1754 } 1755 1756 // We are descending into a call (backwards). Construct 1757 // a new call piece to contain the path pieces for that call. 1758 auto C = PathDiagnosticCallPiece::construct(N, *CE, SM); 1759 1760 // Record the location context for this call piece. 1761 LCM[&C->path] = CE->getCalleeContext(); 1762 1763 // Add the edge to the return site. 1764 addEdgeToPath(PD.getActivePath(), PrevLoc, C->callReturn, PDB.LC); 1765 auto *P = C.get(); 1766 PD.getActivePath().push_front(std::move(C)); 1767 PrevLoc.invalidate(); 1768 1769 // Make the contents of the call the active path for now. 1770 PD.pushActivePath(&P->path); 1771 CallStack.push_back(StackDiagPair(P, N)); 1772 break; 1773 } 1774 1775 if (Optional<PostStmt> PS = P.getAs<PostStmt>()) { 1776 // For expressions, make sure we propagate the 1777 // interesting symbols correctly. 1778 if (const Expr *Ex = PS->getStmtAs<Expr>()) 1779 reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE, 1780 N->getState().get(), Ex, 1781 N->getLocationContext()); 1782 1783 // Add an edge. If this is an ObjCForCollectionStmt do 1784 // not add an edge here as it appears in the CFG both 1785 // as a terminator and as a terminator condition. 1786 if (!isa<ObjCForCollectionStmt>(PS->getStmt())) { 1787 PathDiagnosticLocation L = 1788 PathDiagnosticLocation(PS->getStmt(), SM, PDB.LC); 1789 addEdgeToPath(PD.getActivePath(), PrevLoc, L, PDB.LC); 1790 } 1791 break; 1792 } 1793 1794 // Block edges. 1795 if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) { 1796 // Does this represent entering a call? If so, look at propagating 1797 // interesting symbols across call boundaries. 1798 if (NextNode) { 1799 const LocationContext *CallerCtx = NextNode->getLocationContext(); 1800 const LocationContext *CalleeCtx = PDB.LC; 1801 if (CallerCtx != CalleeCtx) { 1802 reversePropagateInterestingSymbols(*PDB.getBugReport(), IE, 1803 N->getState().get(), 1804 CalleeCtx, CallerCtx); 1805 } 1806 } 1807 1808 // Are we jumping to the head of a loop? Add a special diagnostic. 1809 if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) { 1810 PathDiagnosticLocation L(Loop, SM, PDB.LC); 1811 const Stmt *Body = nullptr; 1812 1813 if (const ForStmt *FS = dyn_cast<ForStmt>(Loop)) 1814 Body = FS->getBody(); 1815 else if (const WhileStmt *WS = dyn_cast<WhileStmt>(Loop)) 1816 Body = WS->getBody(); 1817 else if (const ObjCForCollectionStmt *OFS = 1818 dyn_cast<ObjCForCollectionStmt>(Loop)) { 1819 Body = OFS->getBody(); 1820 } else if (const CXXForRangeStmt *FRS = 1821 dyn_cast<CXXForRangeStmt>(Loop)) { 1822 Body = FRS->getBody(); 1823 } 1824 // do-while statements are explicitly excluded here 1825 1826 auto p = std::make_shared<PathDiagnosticEventPiece>( 1827 L, "Looping back to the head " 1828 "of the loop"); 1829 p->setPrunable(true); 1830 1831 addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC); 1832 PD.getActivePath().push_front(std::move(p)); 1833 1834 if (const CompoundStmt *CS = dyn_cast_or_null<CompoundStmt>(Body)) { 1835 addEdgeToPath(PD.getActivePath(), PrevLoc, 1836 PathDiagnosticLocation::createEndBrace(CS, SM), 1837 PDB.LC); 1838 } 1839 } 1840 1841 const CFGBlock *BSrc = BE->getSrc(); 1842 ParentMap &PM = PDB.getParentMap(); 1843 1844 if (const Stmt *Term = BSrc->getTerminator()) { 1845 // Are we jumping past the loop body without ever executing the 1846 // loop (because the condition was false)? 1847 if (isLoop(Term)) { 1848 const Stmt *TermCond = getTerminatorCondition(BSrc); 1849 bool IsInLoopBody = 1850 isInLoopBody(PM, getStmtBeforeCond(PM, TermCond, N), Term); 1851 1852 const char *str = nullptr; 1853 1854 if (isJumpToFalseBranch(&*BE)) { 1855 if (!IsInLoopBody) { 1856 if (isa<ObjCForCollectionStmt>(Term)) { 1857 str = StrLoopCollectionEmpty; 1858 } else if (isa<CXXForRangeStmt>(Term)) { 1859 str = StrLoopRangeEmpty; 1860 } else { 1861 str = StrLoopBodyZero; 1862 } 1863 } 1864 } else { 1865 str = StrEnteringLoop; 1866 } 1867 1868 if (str) { 1869 PathDiagnosticLocation L(TermCond ? TermCond : Term, SM, PDB.LC); 1870 auto PE = std::make_shared<PathDiagnosticEventPiece>(L, str); 1871 PE->setPrunable(true); 1872 addEdgeToPath(PD.getActivePath(), PrevLoc, 1873 PE->getLocation(), PDB.LC); 1874 PD.getActivePath().push_front(std::move(PE)); 1875 } 1876 } else if (isa<BreakStmt>(Term) || isa<ContinueStmt>(Term) || 1877 isa<GotoStmt>(Term)) { 1878 PathDiagnosticLocation L(Term, SM, PDB.LC); 1879 addEdgeToPath(PD.getActivePath(), PrevLoc, L, PDB.LC); 1880 } 1881 } 1882 break; 1883 } 1884 } while (0); 1885 1886 if (!NextNode) 1887 continue; 1888 1889 // Add pieces from custom visitors. 1890 llvm::FoldingSet<PathDiagnosticPiece> DeduplicationSet; 1891 for (auto &V : visitors) { 1892 if (auto p = V->VisitNode(N, NextNode, PDB, *report)) { 1893 if (DeduplicationSet.GetOrInsertNode(p.get()) != p.get()) 1894 continue; 1895 1896 addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC); 1897 updateStackPiecesWithMessage(*p, CallStack); 1898 PD.getActivePath().push_front(std::move(p)); 1899 } 1900 } 1901 } 1902 1903 // Add an edge to the start of the function. 1904 // We'll prune it out later, but it helps make diagnostics more uniform. 1905 const StackFrameContext *CalleeLC = PDB.LC->getCurrentStackFrame(); 1906 const Decl *D = CalleeLC->getDecl(); 1907 addEdgeToPath(PD.getActivePath(), PrevLoc, 1908 PathDiagnosticLocation::createBegin(D, SM), 1909 CalleeLC); 1910 1911 return report->isValid(); 1912 } 1913 1914 static const Stmt *getLocStmt(PathDiagnosticLocation L) { 1915 if (!L.isValid()) 1916 return nullptr; 1917 return L.asStmt(); 1918 } 1919 1920 static const Stmt *getStmtParent(const Stmt *S, const ParentMap &PM) { 1921 if (!S) 1922 return nullptr; 1923 1924 while (true) { 1925 S = PM.getParentIgnoreParens(S); 1926 1927 if (!S) 1928 break; 1929 1930 if (isa<ExprWithCleanups>(S) || 1931 isa<CXXBindTemporaryExpr>(S) || 1932 isa<SubstNonTypeTemplateParmExpr>(S)) 1933 continue; 1934 1935 break; 1936 } 1937 1938 return S; 1939 } 1940 1941 static bool isConditionForTerminator(const Stmt *S, const Stmt *Cond) { 1942 switch (S->getStmtClass()) { 1943 case Stmt::BinaryOperatorClass: { 1944 const BinaryOperator *BO = cast<BinaryOperator>(S); 1945 if (!BO->isLogicalOp()) 1946 return false; 1947 return BO->getLHS() == Cond || BO->getRHS() == Cond; 1948 } 1949 case Stmt::IfStmtClass: 1950 return cast<IfStmt>(S)->getCond() == Cond; 1951 case Stmt::ForStmtClass: 1952 return cast<ForStmt>(S)->getCond() == Cond; 1953 case Stmt::WhileStmtClass: 1954 return cast<WhileStmt>(S)->getCond() == Cond; 1955 case Stmt::DoStmtClass: 1956 return cast<DoStmt>(S)->getCond() == Cond; 1957 case Stmt::ChooseExprClass: 1958 return cast<ChooseExpr>(S)->getCond() == Cond; 1959 case Stmt::IndirectGotoStmtClass: 1960 return cast<IndirectGotoStmt>(S)->getTarget() == Cond; 1961 case Stmt::SwitchStmtClass: 1962 return cast<SwitchStmt>(S)->getCond() == Cond; 1963 case Stmt::BinaryConditionalOperatorClass: 1964 return cast<BinaryConditionalOperator>(S)->getCond() == Cond; 1965 case Stmt::ConditionalOperatorClass: { 1966 const ConditionalOperator *CO = cast<ConditionalOperator>(S); 1967 return CO->getCond() == Cond || 1968 CO->getLHS() == Cond || 1969 CO->getRHS() == Cond; 1970 } 1971 case Stmt::ObjCForCollectionStmtClass: 1972 return cast<ObjCForCollectionStmt>(S)->getElement() == Cond; 1973 case Stmt::CXXForRangeStmtClass: { 1974 const CXXForRangeStmt *FRS = cast<CXXForRangeStmt>(S); 1975 return FRS->getCond() == Cond || FRS->getRangeInit() == Cond; 1976 } 1977 default: 1978 return false; 1979 } 1980 } 1981 1982 static bool isIncrementOrInitInForLoop(const Stmt *S, const Stmt *FL) { 1983 if (const ForStmt *FS = dyn_cast<ForStmt>(FL)) 1984 return FS->getInc() == S || FS->getInit() == S; 1985 if (const CXXForRangeStmt *FRS = dyn_cast<CXXForRangeStmt>(FL)) 1986 return FRS->getInc() == S || FRS->getRangeStmt() == S || 1987 FRS->getLoopVarStmt() || FRS->getRangeInit() == S; 1988 return false; 1989 } 1990 1991 typedef llvm::DenseSet<const PathDiagnosticCallPiece *> 1992 OptimizedCallsSet; 1993 1994 /// Adds synthetic edges from top-level statements to their subexpressions. 1995 /// 1996 /// This avoids a "swoosh" effect, where an edge from a top-level statement A 1997 /// points to a sub-expression B.1 that's not at the start of B. In these cases, 1998 /// we'd like to see an edge from A to B, then another one from B to B.1. 1999 static void addContextEdges(PathPieces &pieces, SourceManager &SM, 2000 const ParentMap &PM, const LocationContext *LCtx) { 2001 PathPieces::iterator Prev = pieces.end(); 2002 for (PathPieces::iterator I = pieces.begin(), E = Prev; I != E; 2003 Prev = I, ++I) { 2004 PathDiagnosticControlFlowPiece *Piece = 2005 dyn_cast<PathDiagnosticControlFlowPiece>(I->get()); 2006 2007 if (!Piece) 2008 continue; 2009 2010 PathDiagnosticLocation SrcLoc = Piece->getStartLocation(); 2011 SmallVector<PathDiagnosticLocation, 4> SrcContexts; 2012 2013 PathDiagnosticLocation NextSrcContext = SrcLoc; 2014 const Stmt *InnerStmt = nullptr; 2015 while (NextSrcContext.isValid() && NextSrcContext.asStmt() != InnerStmt) { 2016 SrcContexts.push_back(NextSrcContext); 2017 InnerStmt = NextSrcContext.asStmt(); 2018 NextSrcContext = getEnclosingStmtLocation(InnerStmt, SM, PM, LCtx, 2019 /*allowNested=*/true); 2020 } 2021 2022 // Repeatedly split the edge as necessary. 2023 // This is important for nested logical expressions (||, &&, ?:) where we 2024 // want to show all the levels of context. 2025 while (true) { 2026 const Stmt *Dst = getLocStmt(Piece->getEndLocation()); 2027 2028 // We are looking at an edge. Is the destination within a larger 2029 // expression? 2030 PathDiagnosticLocation DstContext = 2031 getEnclosingStmtLocation(Dst, SM, PM, LCtx, /*allowNested=*/true); 2032 if (!DstContext.isValid() || DstContext.asStmt() == Dst) 2033 break; 2034 2035 // If the source is in the same context, we're already good. 2036 if (std::find(SrcContexts.begin(), SrcContexts.end(), DstContext) != 2037 SrcContexts.end()) 2038 break; 2039 2040 // Update the subexpression node to point to the context edge. 2041 Piece->setStartLocation(DstContext); 2042 2043 // Try to extend the previous edge if it's at the same level as the source 2044 // context. 2045 if (Prev != E) { 2046 auto *PrevPiece = dyn_cast<PathDiagnosticControlFlowPiece>(Prev->get()); 2047 2048 if (PrevPiece) { 2049 if (const Stmt *PrevSrc = getLocStmt(PrevPiece->getStartLocation())) { 2050 const Stmt *PrevSrcParent = getStmtParent(PrevSrc, PM); 2051 if (PrevSrcParent == getStmtParent(getLocStmt(DstContext), PM)) { 2052 PrevPiece->setEndLocation(DstContext); 2053 break; 2054 } 2055 } 2056 } 2057 } 2058 2059 // Otherwise, split the current edge into a context edge and a 2060 // subexpression edge. Note that the context statement may itself have 2061 // context. 2062 auto P = 2063 std::make_shared<PathDiagnosticControlFlowPiece>(SrcLoc, DstContext); 2064 Piece = P.get(); 2065 I = pieces.insert(I, std::move(P)); 2066 } 2067 } 2068 } 2069 2070 /// \brief Move edges from a branch condition to a branch target 2071 /// when the condition is simple. 2072 /// 2073 /// This restructures some of the work of addContextEdges. That function 2074 /// creates edges this may destroy, but they work together to create a more 2075 /// aesthetically set of edges around branches. After the call to 2076 /// addContextEdges, we may have (1) an edge to the branch, (2) an edge from 2077 /// the branch to the branch condition, and (3) an edge from the branch 2078 /// condition to the branch target. We keep (1), but may wish to remove (2) 2079 /// and move the source of (3) to the branch if the branch condition is simple. 2080 /// 2081 static void simplifySimpleBranches(PathPieces &pieces) { 2082 for (PathPieces::iterator I = pieces.begin(), E = pieces.end(); I != E; ++I) { 2083 2084 auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get()); 2085 2086 if (!PieceI) 2087 continue; 2088 2089 const Stmt *s1Start = getLocStmt(PieceI->getStartLocation()); 2090 const Stmt *s1End = getLocStmt(PieceI->getEndLocation()); 2091 2092 if (!s1Start || !s1End) 2093 continue; 2094 2095 PathPieces::iterator NextI = I; ++NextI; 2096 if (NextI == E) 2097 break; 2098 2099 PathDiagnosticControlFlowPiece *PieceNextI = nullptr; 2100 2101 while (true) { 2102 if (NextI == E) 2103 break; 2104 2105 auto *EV = dyn_cast<PathDiagnosticEventPiece>(NextI->get()); 2106 if (EV) { 2107 StringRef S = EV->getString(); 2108 if (S == StrEnteringLoop || S == StrLoopBodyZero || 2109 S == StrLoopCollectionEmpty || S == StrLoopRangeEmpty) { 2110 ++NextI; 2111 continue; 2112 } 2113 break; 2114 } 2115 2116 PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get()); 2117 break; 2118 } 2119 2120 if (!PieceNextI) 2121 continue; 2122 2123 const Stmt *s2Start = getLocStmt(PieceNextI->getStartLocation()); 2124 const Stmt *s2End = getLocStmt(PieceNextI->getEndLocation()); 2125 2126 if (!s2Start || !s2End || s1End != s2Start) 2127 continue; 2128 2129 // We only perform this transformation for specific branch kinds. 2130 // We don't want to do this for do..while, for example. 2131 if (!(isa<ForStmt>(s1Start) || isa<WhileStmt>(s1Start) || 2132 isa<IfStmt>(s1Start) || isa<ObjCForCollectionStmt>(s1Start) || 2133 isa<CXXForRangeStmt>(s1Start))) 2134 continue; 2135 2136 // Is s1End the branch condition? 2137 if (!isConditionForTerminator(s1Start, s1End)) 2138 continue; 2139 2140 // Perform the hoisting by eliminating (2) and changing the start 2141 // location of (3). 2142 PieceNextI->setStartLocation(PieceI->getStartLocation()); 2143 I = pieces.erase(I); 2144 } 2145 } 2146 2147 /// Returns the number of bytes in the given (character-based) SourceRange. 2148 /// 2149 /// If the locations in the range are not on the same line, returns None. 2150 /// 2151 /// Note that this does not do a precise user-visible character or column count. 2152 static Optional<size_t> getLengthOnSingleLine(SourceManager &SM, 2153 SourceRange Range) { 2154 SourceRange ExpansionRange(SM.getExpansionLoc(Range.getBegin()), 2155 SM.getExpansionRange(Range.getEnd()).second); 2156 2157 FileID FID = SM.getFileID(ExpansionRange.getBegin()); 2158 if (FID != SM.getFileID(ExpansionRange.getEnd())) 2159 return None; 2160 2161 bool Invalid; 2162 const llvm::MemoryBuffer *Buffer = SM.getBuffer(FID, &Invalid); 2163 if (Invalid) 2164 return None; 2165 2166 unsigned BeginOffset = SM.getFileOffset(ExpansionRange.getBegin()); 2167 unsigned EndOffset = SM.getFileOffset(ExpansionRange.getEnd()); 2168 StringRef Snippet = Buffer->getBuffer().slice(BeginOffset, EndOffset); 2169 2170 // We're searching the raw bytes of the buffer here, which might include 2171 // escaped newlines and such. That's okay; we're trying to decide whether the 2172 // SourceRange is covering a large or small amount of space in the user's 2173 // editor. 2174 if (Snippet.find_first_of("\r\n") != StringRef::npos) 2175 return None; 2176 2177 // This isn't Unicode-aware, but it doesn't need to be. 2178 return Snippet.size(); 2179 } 2180 2181 /// \sa getLengthOnSingleLine(SourceManager, SourceRange) 2182 static Optional<size_t> getLengthOnSingleLine(SourceManager &SM, 2183 const Stmt *S) { 2184 return getLengthOnSingleLine(SM, S->getSourceRange()); 2185 } 2186 2187 /// Eliminate two-edge cycles created by addContextEdges(). 2188 /// 2189 /// Once all the context edges are in place, there are plenty of cases where 2190 /// there's a single edge from a top-level statement to a subexpression, 2191 /// followed by a single path note, and then a reverse edge to get back out to 2192 /// the top level. If the statement is simple enough, the subexpression edges 2193 /// just add noise and make it harder to understand what's going on. 2194 /// 2195 /// This function only removes edges in pairs, because removing only one edge 2196 /// might leave other edges dangling. 2197 /// 2198 /// This will not remove edges in more complicated situations: 2199 /// - if there is more than one "hop" leading to or from a subexpression. 2200 /// - if there is an inlined call between the edges instead of a single event. 2201 /// - if the whole statement is large enough that having subexpression arrows 2202 /// might be helpful. 2203 static void removeContextCycles(PathPieces &Path, SourceManager &SM, 2204 ParentMap &PM) { 2205 for (PathPieces::iterator I = Path.begin(), E = Path.end(); I != E; ) { 2206 // Pattern match the current piece and its successor. 2207 PathDiagnosticControlFlowPiece *PieceI = 2208 dyn_cast<PathDiagnosticControlFlowPiece>(I->get()); 2209 2210 if (!PieceI) { 2211 ++I; 2212 continue; 2213 } 2214 2215 const Stmt *s1Start = getLocStmt(PieceI->getStartLocation()); 2216 const Stmt *s1End = getLocStmt(PieceI->getEndLocation()); 2217 2218 PathPieces::iterator NextI = I; ++NextI; 2219 if (NextI == E) 2220 break; 2221 2222 PathDiagnosticControlFlowPiece *PieceNextI = 2223 dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get()); 2224 2225 if (!PieceNextI) { 2226 if (isa<PathDiagnosticEventPiece>(NextI->get())) { 2227 ++NextI; 2228 if (NextI == E) 2229 break; 2230 PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get()); 2231 } 2232 2233 if (!PieceNextI) { 2234 ++I; 2235 continue; 2236 } 2237 } 2238 2239 const Stmt *s2Start = getLocStmt(PieceNextI->getStartLocation()); 2240 const Stmt *s2End = getLocStmt(PieceNextI->getEndLocation()); 2241 2242 if (s1Start && s2Start && s1Start == s2End && s2Start == s1End) { 2243 const size_t MAX_SHORT_LINE_LENGTH = 80; 2244 Optional<size_t> s1Length = getLengthOnSingleLine(SM, s1Start); 2245 if (s1Length && *s1Length <= MAX_SHORT_LINE_LENGTH) { 2246 Optional<size_t> s2Length = getLengthOnSingleLine(SM, s2Start); 2247 if (s2Length && *s2Length <= MAX_SHORT_LINE_LENGTH) { 2248 Path.erase(I); 2249 I = Path.erase(NextI); 2250 continue; 2251 } 2252 } 2253 } 2254 2255 ++I; 2256 } 2257 } 2258 2259 /// \brief Return true if X is contained by Y. 2260 static bool lexicalContains(ParentMap &PM, 2261 const Stmt *X, 2262 const Stmt *Y) { 2263 while (X) { 2264 if (X == Y) 2265 return true; 2266 X = PM.getParent(X); 2267 } 2268 return false; 2269 } 2270 2271 // Remove short edges on the same line less than 3 columns in difference. 2272 static void removePunyEdges(PathPieces &path, 2273 SourceManager &SM, 2274 ParentMap &PM) { 2275 2276 bool erased = false; 2277 2278 for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; 2279 erased ? I : ++I) { 2280 2281 erased = false; 2282 2283 auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get()); 2284 2285 if (!PieceI) 2286 continue; 2287 2288 const Stmt *start = getLocStmt(PieceI->getStartLocation()); 2289 const Stmt *end = getLocStmt(PieceI->getEndLocation()); 2290 2291 if (!start || !end) 2292 continue; 2293 2294 const Stmt *endParent = PM.getParent(end); 2295 if (!endParent) 2296 continue; 2297 2298 if (isConditionForTerminator(end, endParent)) 2299 continue; 2300 2301 SourceLocation FirstLoc = start->getLocStart(); 2302 SourceLocation SecondLoc = end->getLocStart(); 2303 2304 if (!SM.isWrittenInSameFile(FirstLoc, SecondLoc)) 2305 continue; 2306 if (SM.isBeforeInTranslationUnit(SecondLoc, FirstLoc)) 2307 std::swap(SecondLoc, FirstLoc); 2308 2309 SourceRange EdgeRange(FirstLoc, SecondLoc); 2310 Optional<size_t> ByteWidth = getLengthOnSingleLine(SM, EdgeRange); 2311 2312 // If the statements are on different lines, continue. 2313 if (!ByteWidth) 2314 continue; 2315 2316 const size_t MAX_PUNY_EDGE_LENGTH = 2; 2317 if (*ByteWidth <= MAX_PUNY_EDGE_LENGTH) { 2318 // FIXME: There are enough /bytes/ between the endpoints of the edge, but 2319 // there might not be enough /columns/. A proper user-visible column count 2320 // is probably too expensive, though. 2321 I = path.erase(I); 2322 erased = true; 2323 continue; 2324 } 2325 } 2326 } 2327 2328 static void removeIdenticalEvents(PathPieces &path) { 2329 for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ++I) { 2330 auto *PieceI = dyn_cast<PathDiagnosticEventPiece>(I->get()); 2331 2332 if (!PieceI) 2333 continue; 2334 2335 PathPieces::iterator NextI = I; ++NextI; 2336 if (NextI == E) 2337 return; 2338 2339 auto *PieceNextI = dyn_cast<PathDiagnosticEventPiece>(NextI->get()); 2340 2341 if (!PieceNextI) 2342 continue; 2343 2344 // Erase the second piece if it has the same exact message text. 2345 if (PieceI->getString() == PieceNextI->getString()) { 2346 path.erase(NextI); 2347 } 2348 } 2349 } 2350 2351 static bool optimizeEdges(PathPieces &path, SourceManager &SM, 2352 OptimizedCallsSet &OCS, 2353 LocationContextMap &LCM) { 2354 bool hasChanges = false; 2355 const LocationContext *LC = LCM[&path]; 2356 assert(LC); 2357 ParentMap &PM = LC->getParentMap(); 2358 2359 for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ) { 2360 // Optimize subpaths. 2361 if (auto *CallI = dyn_cast<PathDiagnosticCallPiece>(I->get())) { 2362 // Record the fact that a call has been optimized so we only do the 2363 // effort once. 2364 if (!OCS.count(CallI)) { 2365 while (optimizeEdges(CallI->path, SM, OCS, LCM)) {} 2366 OCS.insert(CallI); 2367 } 2368 ++I; 2369 continue; 2370 } 2371 2372 // Pattern match the current piece and its successor. 2373 auto *PieceI = dyn_cast<PathDiagnosticControlFlowPiece>(I->get()); 2374 2375 if (!PieceI) { 2376 ++I; 2377 continue; 2378 } 2379 2380 const Stmt *s1Start = getLocStmt(PieceI->getStartLocation()); 2381 const Stmt *s1End = getLocStmt(PieceI->getEndLocation()); 2382 const Stmt *level1 = getStmtParent(s1Start, PM); 2383 const Stmt *level2 = getStmtParent(s1End, PM); 2384 2385 PathPieces::iterator NextI = I; ++NextI; 2386 if (NextI == E) 2387 break; 2388 2389 auto *PieceNextI = dyn_cast<PathDiagnosticControlFlowPiece>(NextI->get()); 2390 2391 if (!PieceNextI) { 2392 ++I; 2393 continue; 2394 } 2395 2396 const Stmt *s2Start = getLocStmt(PieceNextI->getStartLocation()); 2397 const Stmt *s2End = getLocStmt(PieceNextI->getEndLocation()); 2398 const Stmt *level3 = getStmtParent(s2Start, PM); 2399 const Stmt *level4 = getStmtParent(s2End, PM); 2400 2401 // Rule I. 2402 // 2403 // If we have two consecutive control edges whose end/begin locations 2404 // are at the same level (e.g. statements or top-level expressions within 2405 // a compound statement, or siblings share a single ancestor expression), 2406 // then merge them if they have no interesting intermediate event. 2407 // 2408 // For example: 2409 // 2410 // (1.1 -> 1.2) -> (1.2 -> 1.3) becomes (1.1 -> 1.3) because the common 2411 // parent is '1'. Here 'x.y.z' represents the hierarchy of statements. 2412 // 2413 // NOTE: this will be limited later in cases where we add barriers 2414 // to prevent this optimization. 2415 // 2416 if (level1 && level1 == level2 && level1 == level3 && level1 == level4) { 2417 PieceI->setEndLocation(PieceNextI->getEndLocation()); 2418 path.erase(NextI); 2419 hasChanges = true; 2420 continue; 2421 } 2422 2423 // Rule II. 2424 // 2425 // Eliminate edges between subexpressions and parent expressions 2426 // when the subexpression is consumed. 2427 // 2428 // NOTE: this will be limited later in cases where we add barriers 2429 // to prevent this optimization. 2430 // 2431 if (s1End && s1End == s2Start && level2) { 2432 bool removeEdge = false; 2433 // Remove edges into the increment or initialization of a 2434 // loop that have no interleaving event. This means that 2435 // they aren't interesting. 2436 if (isIncrementOrInitInForLoop(s1End, level2)) 2437 removeEdge = true; 2438 // Next only consider edges that are not anchored on 2439 // the condition of a terminator. This are intermediate edges 2440 // that we might want to trim. 2441 else if (!isConditionForTerminator(level2, s1End)) { 2442 // Trim edges on expressions that are consumed by 2443 // the parent expression. 2444 if (isa<Expr>(s1End) && PM.isConsumedExpr(cast<Expr>(s1End))) { 2445 removeEdge = true; 2446 } 2447 // Trim edges where a lexical containment doesn't exist. 2448 // For example: 2449 // 2450 // X -> Y -> Z 2451 // 2452 // If 'Z' lexically contains Y (it is an ancestor) and 2453 // 'X' does not lexically contain Y (it is a descendant OR 2454 // it has no lexical relationship at all) then trim. 2455 // 2456 // This can eliminate edges where we dive into a subexpression 2457 // and then pop back out, etc. 2458 else if (s1Start && s2End && 2459 lexicalContains(PM, s2Start, s2End) && 2460 !lexicalContains(PM, s1End, s1Start)) { 2461 removeEdge = true; 2462 } 2463 // Trim edges from a subexpression back to the top level if the 2464 // subexpression is on a different line. 2465 // 2466 // A.1 -> A -> B 2467 // becomes 2468 // A.1 -> B 2469 // 2470 // These edges just look ugly and don't usually add anything. 2471 else if (s1Start && s2End && 2472 lexicalContains(PM, s1Start, s1End)) { 2473 SourceRange EdgeRange(PieceI->getEndLocation().asLocation(), 2474 PieceI->getStartLocation().asLocation()); 2475 if (!getLengthOnSingleLine(SM, EdgeRange).hasValue()) 2476 removeEdge = true; 2477 } 2478 } 2479 2480 if (removeEdge) { 2481 PieceI->setEndLocation(PieceNextI->getEndLocation()); 2482 path.erase(NextI); 2483 hasChanges = true; 2484 continue; 2485 } 2486 } 2487 2488 // Optimize edges for ObjC fast-enumeration loops. 2489 // 2490 // (X -> collection) -> (collection -> element) 2491 // 2492 // becomes: 2493 // 2494 // (X -> element) 2495 if (s1End == s2Start) { 2496 const ObjCForCollectionStmt *FS = 2497 dyn_cast_or_null<ObjCForCollectionStmt>(level3); 2498 if (FS && FS->getCollection()->IgnoreParens() == s2Start && 2499 s2End == FS->getElement()) { 2500 PieceI->setEndLocation(PieceNextI->getEndLocation()); 2501 path.erase(NextI); 2502 hasChanges = true; 2503 continue; 2504 } 2505 } 2506 2507 // No changes at this index? Move to the next one. 2508 ++I; 2509 } 2510 2511 if (!hasChanges) { 2512 // Adjust edges into subexpressions to make them more uniform 2513 // and aesthetically pleasing. 2514 addContextEdges(path, SM, PM, LC); 2515 // Remove "cyclical" edges that include one or more context edges. 2516 removeContextCycles(path, SM, PM); 2517 // Hoist edges originating from branch conditions to branches 2518 // for simple branches. 2519 simplifySimpleBranches(path); 2520 // Remove any puny edges left over after primary optimization pass. 2521 removePunyEdges(path, SM, PM); 2522 // Remove identical events. 2523 removeIdenticalEvents(path); 2524 } 2525 2526 return hasChanges; 2527 } 2528 2529 /// Drop the very first edge in a path, which should be a function entry edge. 2530 /// 2531 /// If the first edge is not a function entry edge (say, because the first 2532 /// statement had an invalid source location), this function does nothing. 2533 // FIXME: We should just generate invalid edges anyway and have the optimizer 2534 // deal with them. 2535 static void dropFunctionEntryEdge(PathPieces &Path, 2536 LocationContextMap &LCM, 2537 SourceManager &SM) { 2538 const auto *FirstEdge = 2539 dyn_cast<PathDiagnosticControlFlowPiece>(Path.front().get()); 2540 if (!FirstEdge) 2541 return; 2542 2543 const Decl *D = LCM[&Path]->getDecl(); 2544 PathDiagnosticLocation EntryLoc = PathDiagnosticLocation::createBegin(D, SM); 2545 if (FirstEdge->getStartLocation() != EntryLoc) 2546 return; 2547 2548 Path.pop_front(); 2549 } 2550 2551 2552 //===----------------------------------------------------------------------===// 2553 // Methods for BugType and subclasses. 2554 //===----------------------------------------------------------------------===// 2555 void BugType::anchor() { } 2556 2557 void BugType::FlushReports(BugReporter &BR) {} 2558 2559 void BuiltinBug::anchor() {} 2560 2561 //===----------------------------------------------------------------------===// 2562 // Methods for BugReport and subclasses. 2563 //===----------------------------------------------------------------------===// 2564 2565 void BugReport::NodeResolver::anchor() {} 2566 2567 void BugReport::addVisitor(std::unique_ptr<BugReporterVisitor> visitor) { 2568 if (!visitor) 2569 return; 2570 2571 llvm::FoldingSetNodeID ID; 2572 visitor->Profile(ID); 2573 void *InsertPos; 2574 2575 if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) 2576 return; 2577 2578 CallbacksSet.InsertNode(visitor.get(), InsertPos); 2579 Callbacks.push_back(std::move(visitor)); 2580 ++ConfigurationChangeToken; 2581 } 2582 2583 BugReport::~BugReport() { 2584 while (!interestingSymbols.empty()) { 2585 popInterestingSymbolsAndRegions(); 2586 } 2587 } 2588 2589 const Decl *BugReport::getDeclWithIssue() const { 2590 if (DeclWithIssue) 2591 return DeclWithIssue; 2592 2593 const ExplodedNode *N = getErrorNode(); 2594 if (!N) 2595 return nullptr; 2596 2597 const LocationContext *LC = N->getLocationContext(); 2598 return LC->getCurrentStackFrame()->getDecl(); 2599 } 2600 2601 void BugReport::Profile(llvm::FoldingSetNodeID& hash) const { 2602 hash.AddPointer(&BT); 2603 hash.AddString(Description); 2604 PathDiagnosticLocation UL = getUniqueingLocation(); 2605 if (UL.isValid()) { 2606 UL.Profile(hash); 2607 } else if (Location.isValid()) { 2608 Location.Profile(hash); 2609 } else { 2610 assert(ErrorNode); 2611 hash.AddPointer(GetCurrentOrPreviousStmt(ErrorNode)); 2612 } 2613 2614 for (SourceRange range : Ranges) { 2615 if (!range.isValid()) 2616 continue; 2617 hash.AddInteger(range.getBegin().getRawEncoding()); 2618 hash.AddInteger(range.getEnd().getRawEncoding()); 2619 } 2620 } 2621 2622 void BugReport::markInteresting(SymbolRef sym) { 2623 if (!sym) 2624 return; 2625 2626 // If the symbol wasn't already in our set, note a configuration change. 2627 if (getInterestingSymbols().insert(sym).second) 2628 ++ConfigurationChangeToken; 2629 2630 if (const SymbolMetadata *meta = dyn_cast<SymbolMetadata>(sym)) 2631 getInterestingRegions().insert(meta->getRegion()); 2632 } 2633 2634 void BugReport::markInteresting(const MemRegion *R) { 2635 if (!R) 2636 return; 2637 2638 // If the base region wasn't already in our set, note a configuration change. 2639 R = R->getBaseRegion(); 2640 if (getInterestingRegions().insert(R).second) 2641 ++ConfigurationChangeToken; 2642 2643 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) 2644 getInterestingSymbols().insert(SR->getSymbol()); 2645 } 2646 2647 void BugReport::markInteresting(SVal V) { 2648 markInteresting(V.getAsRegion()); 2649 markInteresting(V.getAsSymbol()); 2650 } 2651 2652 void BugReport::markInteresting(const LocationContext *LC) { 2653 if (!LC) 2654 return; 2655 InterestingLocationContexts.insert(LC); 2656 } 2657 2658 bool BugReport::isInteresting(SVal V) { 2659 return isInteresting(V.getAsRegion()) || isInteresting(V.getAsSymbol()); 2660 } 2661 2662 bool BugReport::isInteresting(SymbolRef sym) { 2663 if (!sym) 2664 return false; 2665 // We don't currently consider metadata symbols to be interesting 2666 // even if we know their region is interesting. Is that correct behavior? 2667 return getInterestingSymbols().count(sym); 2668 } 2669 2670 bool BugReport::isInteresting(const MemRegion *R) { 2671 if (!R) 2672 return false; 2673 R = R->getBaseRegion(); 2674 bool b = getInterestingRegions().count(R); 2675 if (b) 2676 return true; 2677 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) 2678 return getInterestingSymbols().count(SR->getSymbol()); 2679 return false; 2680 } 2681 2682 bool BugReport::isInteresting(const LocationContext *LC) { 2683 if (!LC) 2684 return false; 2685 return InterestingLocationContexts.count(LC); 2686 } 2687 2688 void BugReport::lazyInitializeInterestingSets() { 2689 if (interestingSymbols.empty()) { 2690 interestingSymbols.push_back(new Symbols()); 2691 interestingRegions.push_back(new Regions()); 2692 } 2693 } 2694 2695 BugReport::Symbols &BugReport::getInterestingSymbols() { 2696 lazyInitializeInterestingSets(); 2697 return *interestingSymbols.back(); 2698 } 2699 2700 BugReport::Regions &BugReport::getInterestingRegions() { 2701 lazyInitializeInterestingSets(); 2702 return *interestingRegions.back(); 2703 } 2704 2705 void BugReport::pushInterestingSymbolsAndRegions() { 2706 interestingSymbols.push_back(new Symbols(getInterestingSymbols())); 2707 interestingRegions.push_back(new Regions(getInterestingRegions())); 2708 } 2709 2710 void BugReport::popInterestingSymbolsAndRegions() { 2711 delete interestingSymbols.pop_back_val(); 2712 delete interestingRegions.pop_back_val(); 2713 } 2714 2715 const Stmt *BugReport::getStmt() const { 2716 if (!ErrorNode) 2717 return nullptr; 2718 2719 ProgramPoint ProgP = ErrorNode->getLocation(); 2720 const Stmt *S = nullptr; 2721 2722 if (Optional<BlockEntrance> BE = ProgP.getAs<BlockEntrance>()) { 2723 CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit(); 2724 if (BE->getBlock() == &Exit) 2725 S = GetPreviousStmt(ErrorNode); 2726 } 2727 if (!S) 2728 S = PathDiagnosticLocation::getStmt(ErrorNode); 2729 2730 return S; 2731 } 2732 2733 llvm::iterator_range<BugReport::ranges_iterator> BugReport::getRanges() { 2734 // If no custom ranges, add the range of the statement corresponding to 2735 // the error node. 2736 if (Ranges.empty()) { 2737 if (const Expr *E = dyn_cast_or_null<Expr>(getStmt())) 2738 addRange(E->getSourceRange()); 2739 else 2740 return llvm::make_range(ranges_iterator(), ranges_iterator()); 2741 } 2742 2743 // User-specified absence of range info. 2744 if (Ranges.size() == 1 && !Ranges.begin()->isValid()) 2745 return llvm::make_range(ranges_iterator(), ranges_iterator()); 2746 2747 return llvm::make_range(Ranges.begin(), Ranges.end()); 2748 } 2749 2750 PathDiagnosticLocation BugReport::getLocation(const SourceManager &SM) const { 2751 if (ErrorNode) { 2752 assert(!Location.isValid() && 2753 "Either Location or ErrorNode should be specified but not both."); 2754 return PathDiagnosticLocation::createEndOfPath(ErrorNode, SM); 2755 } 2756 2757 assert(Location.isValid()); 2758 return Location; 2759 } 2760 2761 //===----------------------------------------------------------------------===// 2762 // Methods for BugReporter and subclasses. 2763 //===----------------------------------------------------------------------===// 2764 2765 BugReportEquivClass::~BugReportEquivClass() { } 2766 GRBugReporter::~GRBugReporter() { } 2767 BugReporterData::~BugReporterData() {} 2768 2769 ExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); } 2770 2771 ProgramStateManager& 2772 GRBugReporter::getStateManager() { return Eng.getStateManager(); } 2773 2774 BugReporter::~BugReporter() { 2775 FlushReports(); 2776 2777 // Free the bug reports we are tracking. 2778 typedef std::vector<BugReportEquivClass *> ContTy; 2779 for (ContTy::iterator I = EQClassesVector.begin(), E = EQClassesVector.end(); 2780 I != E; ++I) { 2781 delete *I; 2782 } 2783 } 2784 2785 void BugReporter::FlushReports() { 2786 if (BugTypes.isEmpty()) 2787 return; 2788 2789 // First flush the warnings for each BugType. This may end up creating new 2790 // warnings and new BugTypes. 2791 // FIXME: Only NSErrorChecker needs BugType's FlushReports. 2792 // Turn NSErrorChecker into a proper checker and remove this. 2793 SmallVector<const BugType *, 16> bugTypes(BugTypes.begin(), BugTypes.end()); 2794 for (SmallVectorImpl<const BugType *>::iterator 2795 I = bugTypes.begin(), E = bugTypes.end(); I != E; ++I) 2796 const_cast<BugType*>(*I)->FlushReports(*this); 2797 2798 // We need to flush reports in deterministic order to ensure the order 2799 // of the reports is consistent between runs. 2800 typedef std::vector<BugReportEquivClass *> ContVecTy; 2801 for (ContVecTy::iterator EI=EQClassesVector.begin(), EE=EQClassesVector.end(); 2802 EI != EE; ++EI){ 2803 BugReportEquivClass& EQ = **EI; 2804 FlushReport(EQ); 2805 } 2806 2807 // BugReporter owns and deletes only BugTypes created implicitly through 2808 // EmitBasicReport. 2809 // FIXME: There are leaks from checkers that assume that the BugTypes they 2810 // create will be destroyed by the BugReporter. 2811 llvm::DeleteContainerSeconds(StrBugTypes); 2812 2813 // Remove all references to the BugType objects. 2814 BugTypes = F.getEmptySet(); 2815 } 2816 2817 //===----------------------------------------------------------------------===// 2818 // PathDiagnostics generation. 2819 //===----------------------------------------------------------------------===// 2820 2821 namespace { 2822 /// A wrapper around a report graph, which contains only a single path, and its 2823 /// node maps. 2824 class ReportGraph { 2825 public: 2826 InterExplodedGraphMap BackMap; 2827 std::unique_ptr<ExplodedGraph> Graph; 2828 const ExplodedNode *ErrorNode; 2829 size_t Index; 2830 }; 2831 2832 /// A wrapper around a trimmed graph and its node maps. 2833 class TrimmedGraph { 2834 InterExplodedGraphMap InverseMap; 2835 2836 typedef llvm::DenseMap<const ExplodedNode *, unsigned> PriorityMapTy; 2837 PriorityMapTy PriorityMap; 2838 2839 typedef std::pair<const ExplodedNode *, size_t> NodeIndexPair; 2840 SmallVector<NodeIndexPair, 32> ReportNodes; 2841 2842 std::unique_ptr<ExplodedGraph> G; 2843 2844 /// A helper class for sorting ExplodedNodes by priority. 2845 template <bool Descending> 2846 class PriorityCompare { 2847 const PriorityMapTy &PriorityMap; 2848 2849 public: 2850 PriorityCompare(const PriorityMapTy &M) : PriorityMap(M) {} 2851 2852 bool operator()(const ExplodedNode *LHS, const ExplodedNode *RHS) const { 2853 PriorityMapTy::const_iterator LI = PriorityMap.find(LHS); 2854 PriorityMapTy::const_iterator RI = PriorityMap.find(RHS); 2855 PriorityMapTy::const_iterator E = PriorityMap.end(); 2856 2857 if (LI == E) 2858 return Descending; 2859 if (RI == E) 2860 return !Descending; 2861 2862 return Descending ? LI->second > RI->second 2863 : LI->second < RI->second; 2864 } 2865 2866 bool operator()(const NodeIndexPair &LHS, const NodeIndexPair &RHS) const { 2867 return (*this)(LHS.first, RHS.first); 2868 } 2869 }; 2870 2871 public: 2872 TrimmedGraph(const ExplodedGraph *OriginalGraph, 2873 ArrayRef<const ExplodedNode *> Nodes); 2874 2875 bool popNextReportGraph(ReportGraph &GraphWrapper); 2876 }; 2877 } 2878 2879 TrimmedGraph::TrimmedGraph(const ExplodedGraph *OriginalGraph, 2880 ArrayRef<const ExplodedNode *> Nodes) { 2881 // The trimmed graph is created in the body of the constructor to ensure 2882 // that the DenseMaps have been initialized already. 2883 InterExplodedGraphMap ForwardMap; 2884 G = OriginalGraph->trim(Nodes, &ForwardMap, &InverseMap); 2885 2886 // Find the (first) error node in the trimmed graph. We just need to consult 2887 // the node map which maps from nodes in the original graph to nodes 2888 // in the new graph. 2889 llvm::SmallPtrSet<const ExplodedNode *, 32> RemainingNodes; 2890 2891 for (unsigned i = 0, count = Nodes.size(); i < count; ++i) { 2892 if (const ExplodedNode *NewNode = ForwardMap.lookup(Nodes[i])) { 2893 ReportNodes.push_back(std::make_pair(NewNode, i)); 2894 RemainingNodes.insert(NewNode); 2895 } 2896 } 2897 2898 assert(!RemainingNodes.empty() && "No error node found in the trimmed graph"); 2899 2900 // Perform a forward BFS to find all the shortest paths. 2901 std::queue<const ExplodedNode *> WS; 2902 2903 assert(G->num_roots() == 1); 2904 WS.push(*G->roots_begin()); 2905 unsigned Priority = 0; 2906 2907 while (!WS.empty()) { 2908 const ExplodedNode *Node = WS.front(); 2909 WS.pop(); 2910 2911 PriorityMapTy::iterator PriorityEntry; 2912 bool IsNew; 2913 std::tie(PriorityEntry, IsNew) = 2914 PriorityMap.insert(std::make_pair(Node, Priority)); 2915 ++Priority; 2916 2917 if (!IsNew) { 2918 assert(PriorityEntry->second <= Priority); 2919 continue; 2920 } 2921 2922 if (RemainingNodes.erase(Node)) 2923 if (RemainingNodes.empty()) 2924 break; 2925 2926 for (ExplodedNode::const_pred_iterator I = Node->succ_begin(), 2927 E = Node->succ_end(); 2928 I != E; ++I) 2929 WS.push(*I); 2930 } 2931 2932 // Sort the error paths from longest to shortest. 2933 std::sort(ReportNodes.begin(), ReportNodes.end(), 2934 PriorityCompare<true>(PriorityMap)); 2935 } 2936 2937 bool TrimmedGraph::popNextReportGraph(ReportGraph &GraphWrapper) { 2938 if (ReportNodes.empty()) 2939 return false; 2940 2941 const ExplodedNode *OrigN; 2942 std::tie(OrigN, GraphWrapper.Index) = ReportNodes.pop_back_val(); 2943 assert(PriorityMap.find(OrigN) != PriorityMap.end() && 2944 "error node not accessible from root"); 2945 2946 // Create a new graph with a single path. This is the graph 2947 // that will be returned to the caller. 2948 auto GNew = llvm::make_unique<ExplodedGraph>(); 2949 GraphWrapper.BackMap.clear(); 2950 2951 // Now walk from the error node up the BFS path, always taking the 2952 // predeccessor with the lowest number. 2953 ExplodedNode *Succ = nullptr; 2954 while (true) { 2955 // Create the equivalent node in the new graph with the same state 2956 // and location. 2957 ExplodedNode *NewN = GNew->createUncachedNode(OrigN->getLocation(), OrigN->getState(), 2958 OrigN->isSink()); 2959 2960 // Store the mapping to the original node. 2961 InterExplodedGraphMap::const_iterator IMitr = InverseMap.find(OrigN); 2962 assert(IMitr != InverseMap.end() && "No mapping to original node."); 2963 GraphWrapper.BackMap[NewN] = IMitr->second; 2964 2965 // Link up the new node with the previous node. 2966 if (Succ) 2967 Succ->addPredecessor(NewN, *GNew); 2968 else 2969 GraphWrapper.ErrorNode = NewN; 2970 2971 Succ = NewN; 2972 2973 // Are we at the final node? 2974 if (OrigN->pred_empty()) { 2975 GNew->addRoot(NewN); 2976 break; 2977 } 2978 2979 // Find the next predeccessor node. We choose the node that is marked 2980 // with the lowest BFS number. 2981 OrigN = *std::min_element(OrigN->pred_begin(), OrigN->pred_end(), 2982 PriorityCompare<false>(PriorityMap)); 2983 } 2984 2985 GraphWrapper.Graph = std::move(GNew); 2986 2987 return true; 2988 } 2989 2990 2991 /// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object 2992 /// and collapses PathDiagosticPieces that are expanded by macros. 2993 static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM) { 2994 typedef std::vector< 2995 std::pair<std::shared_ptr<PathDiagnosticMacroPiece>, SourceLocation>> 2996 MacroStackTy; 2997 2998 typedef std::vector<std::shared_ptr<PathDiagnosticPiece>> PiecesTy; 2999 3000 MacroStackTy MacroStack; 3001 PiecesTy Pieces; 3002 3003 for (PathPieces::const_iterator I = path.begin(), E = path.end(); 3004 I!=E; ++I) { 3005 3006 auto &piece = *I; 3007 3008 // Recursively compact calls. 3009 if (auto *call = dyn_cast<PathDiagnosticCallPiece>(&*piece)) { 3010 CompactPathDiagnostic(call->path, SM); 3011 } 3012 3013 // Get the location of the PathDiagnosticPiece. 3014 const FullSourceLoc Loc = piece->getLocation().asLocation(); 3015 3016 // Determine the instantiation location, which is the location we group 3017 // related PathDiagnosticPieces. 3018 SourceLocation InstantiationLoc = Loc.isMacroID() ? 3019 SM.getExpansionLoc(Loc) : 3020 SourceLocation(); 3021 3022 if (Loc.isFileID()) { 3023 MacroStack.clear(); 3024 Pieces.push_back(piece); 3025 continue; 3026 } 3027 3028 assert(Loc.isMacroID()); 3029 3030 // Is the PathDiagnosticPiece within the same macro group? 3031 if (!MacroStack.empty() && InstantiationLoc == MacroStack.back().second) { 3032 MacroStack.back().first->subPieces.push_back(piece); 3033 continue; 3034 } 3035 3036 // We aren't in the same group. Are we descending into a new macro 3037 // or are part of an old one? 3038 std::shared_ptr<PathDiagnosticMacroPiece> MacroGroup; 3039 3040 SourceLocation ParentInstantiationLoc = InstantiationLoc.isMacroID() ? 3041 SM.getExpansionLoc(Loc) : 3042 SourceLocation(); 3043 3044 // Walk the entire macro stack. 3045 while (!MacroStack.empty()) { 3046 if (InstantiationLoc == MacroStack.back().second) { 3047 MacroGroup = MacroStack.back().first; 3048 break; 3049 } 3050 3051 if (ParentInstantiationLoc == MacroStack.back().second) { 3052 MacroGroup = MacroStack.back().first; 3053 break; 3054 } 3055 3056 MacroStack.pop_back(); 3057 } 3058 3059 if (!MacroGroup || ParentInstantiationLoc == MacroStack.back().second) { 3060 // Create a new macro group and add it to the stack. 3061 auto NewGroup = std::make_shared<PathDiagnosticMacroPiece>( 3062 PathDiagnosticLocation::createSingleLocation(piece->getLocation())); 3063 3064 if (MacroGroup) 3065 MacroGroup->subPieces.push_back(NewGroup); 3066 else { 3067 assert(InstantiationLoc.isFileID()); 3068 Pieces.push_back(NewGroup); 3069 } 3070 3071 MacroGroup = NewGroup; 3072 MacroStack.push_back(std::make_pair(MacroGroup, InstantiationLoc)); 3073 } 3074 3075 // Finally, add the PathDiagnosticPiece to the group. 3076 MacroGroup->subPieces.push_back(piece); 3077 } 3078 3079 // Now take the pieces and construct a new PathDiagnostic. 3080 path.clear(); 3081 3082 path.insert(path.end(), Pieces.begin(), Pieces.end()); 3083 } 3084 3085 bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD, 3086 PathDiagnosticConsumer &PC, 3087 ArrayRef<BugReport *> &bugReports) { 3088 assert(!bugReports.empty()); 3089 3090 bool HasValid = false; 3091 bool HasInvalid = false; 3092 SmallVector<const ExplodedNode *, 32> errorNodes; 3093 for (ArrayRef<BugReport*>::iterator I = bugReports.begin(), 3094 E = bugReports.end(); I != E; ++I) { 3095 if ((*I)->isValid()) { 3096 HasValid = true; 3097 errorNodes.push_back((*I)->getErrorNode()); 3098 } else { 3099 // Keep the errorNodes list in sync with the bugReports list. 3100 HasInvalid = true; 3101 errorNodes.push_back(nullptr); 3102 } 3103 } 3104 3105 // If all the reports have been marked invalid by a previous path generation, 3106 // we're done. 3107 if (!HasValid) 3108 return false; 3109 3110 typedef PathDiagnosticConsumer::PathGenerationScheme PathGenerationScheme; 3111 PathGenerationScheme ActiveScheme = PC.getGenerationScheme(); 3112 3113 if (ActiveScheme == PathDiagnosticConsumer::Extensive) { 3114 AnalyzerOptions &options = getAnalyzerOptions(); 3115 if (options.getBooleanOption("path-diagnostics-alternate", true)) { 3116 ActiveScheme = PathDiagnosticConsumer::AlternateExtensive; 3117 } 3118 } 3119 3120 TrimmedGraph TrimG(&getGraph(), errorNodes); 3121 ReportGraph ErrorGraph; 3122 3123 while (TrimG.popNextReportGraph(ErrorGraph)) { 3124 // Find the BugReport with the original location. 3125 assert(ErrorGraph.Index < bugReports.size()); 3126 BugReport *R = bugReports[ErrorGraph.Index]; 3127 assert(R && "No original report found for sliced graph."); 3128 assert(R->isValid() && "Report selected by trimmed graph marked invalid."); 3129 3130 // Start building the path diagnostic... 3131 PathDiagnosticBuilder PDB(*this, R, ErrorGraph.BackMap, &PC); 3132 const ExplodedNode *N = ErrorGraph.ErrorNode; 3133 3134 // Register additional node visitors. 3135 R->addVisitor(llvm::make_unique<NilReceiverBRVisitor>()); 3136 R->addVisitor(llvm::make_unique<ConditionBRVisitor>()); 3137 R->addVisitor(llvm::make_unique<LikelyFalsePositiveSuppressionBRVisitor>()); 3138 R->addVisitor(llvm::make_unique<CXXSelfAssignmentBRVisitor>()); 3139 3140 BugReport::VisitorList visitors; 3141 unsigned origReportConfigToken, finalReportConfigToken; 3142 LocationContextMap LCM; 3143 3144 // While generating diagnostics, it's possible the visitors will decide 3145 // new symbols and regions are interesting, or add other visitors based on 3146 // the information they find. If they do, we need to regenerate the path 3147 // based on our new report configuration. 3148 do { 3149 // Get a clean copy of all the visitors. 3150 for (BugReport::visitor_iterator I = R->visitor_begin(), 3151 E = R->visitor_end(); I != E; ++I) 3152 visitors.push_back((*I)->clone()); 3153 3154 // Clear out the active path from any previous work. 3155 PD.resetPath(); 3156 origReportConfigToken = R->getConfigurationChangeToken(); 3157 3158 // Generate the very last diagnostic piece - the piece is visible before 3159 // the trace is expanded. 3160 std::unique_ptr<PathDiagnosticPiece> LastPiece; 3161 for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end(); 3162 I != E; ++I) { 3163 if (std::unique_ptr<PathDiagnosticPiece> Piece = 3164 (*I)->getEndPath(PDB, N, *R)) { 3165 assert (!LastPiece && 3166 "There can only be one final piece in a diagnostic."); 3167 LastPiece = std::move(Piece); 3168 } 3169 } 3170 3171 if (ActiveScheme != PathDiagnosticConsumer::None) { 3172 if (!LastPiece) 3173 LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R); 3174 assert(LastPiece); 3175 PD.setEndOfPath(std::move(LastPiece)); 3176 } 3177 3178 // Make sure we get a clean location context map so we don't 3179 // hold onto old mappings. 3180 LCM.clear(); 3181 3182 switch (ActiveScheme) { 3183 case PathDiagnosticConsumer::AlternateExtensive: 3184 GenerateAlternateExtensivePathDiagnostic(PD, PDB, N, LCM, visitors); 3185 break; 3186 case PathDiagnosticConsumer::Extensive: 3187 GenerateExtensivePathDiagnostic(PD, PDB, N, LCM, visitors); 3188 break; 3189 case PathDiagnosticConsumer::Minimal: 3190 GenerateMinimalPathDiagnostic(PD, PDB, N, LCM, visitors); 3191 break; 3192 case PathDiagnosticConsumer::None: 3193 GenerateVisitorsOnlyPathDiagnostic(PD, PDB, N, visitors); 3194 break; 3195 } 3196 3197 // Clean up the visitors we used. 3198 visitors.clear(); 3199 3200 // Did anything change while generating this path? 3201 finalReportConfigToken = R->getConfigurationChangeToken(); 3202 } while (finalReportConfigToken != origReportConfigToken); 3203 3204 if (!R->isValid()) 3205 continue; 3206 3207 // Finally, prune the diagnostic path of uninteresting stuff. 3208 if (!PD.path.empty()) { 3209 if (R->shouldPrunePath() && getAnalyzerOptions().shouldPrunePaths()) { 3210 bool stillHasNotes = removeUnneededCalls(PD.getMutablePieces(), R, LCM); 3211 assert(stillHasNotes); 3212 (void)stillHasNotes; 3213 } 3214 3215 // Redirect all call pieces to have valid locations. 3216 adjustCallLocations(PD.getMutablePieces()); 3217 removePiecesWithInvalidLocations(PD.getMutablePieces()); 3218 3219 if (ActiveScheme == PathDiagnosticConsumer::AlternateExtensive) { 3220 SourceManager &SM = getSourceManager(); 3221 3222 // Reduce the number of edges from a very conservative set 3223 // to an aesthetically pleasing subset that conveys the 3224 // necessary information. 3225 OptimizedCallsSet OCS; 3226 while (optimizeEdges(PD.getMutablePieces(), SM, OCS, LCM)) {} 3227 3228 // Drop the very first function-entry edge. It's not really necessary 3229 // for top-level functions. 3230 dropFunctionEntryEdge(PD.getMutablePieces(), LCM, SM); 3231 } 3232 3233 // Remove messages that are basically the same, and edges that may not 3234 // make sense. 3235 // We have to do this after edge optimization in the Extensive mode. 3236 removeRedundantMsgs(PD.getMutablePieces()); 3237 removeEdgesToDefaultInitializers(PD.getMutablePieces()); 3238 } 3239 3240 // We found a report and didn't suppress it. 3241 return true; 3242 } 3243 3244 // We suppressed all the reports in this equivalence class. 3245 assert(!HasInvalid && "Inconsistent suppression"); 3246 (void)HasInvalid; 3247 return false; 3248 } 3249 3250 void BugReporter::Register(BugType *BT) { 3251 BugTypes = F.add(BugTypes, BT); 3252 } 3253 3254 void BugReporter::emitReport(std::unique_ptr<BugReport> R) { 3255 if (const ExplodedNode *E = R->getErrorNode()) { 3256 // An error node must either be a sink or have a tag, otherwise 3257 // it could get reclaimed before the path diagnostic is created. 3258 assert((E->isSink() || E->getLocation().getTag()) && 3259 "Error node must either be a sink or have a tag"); 3260 3261 const AnalysisDeclContext *DeclCtx = 3262 E->getLocationContext()->getAnalysisDeclContext(); 3263 // The source of autosynthesized body can be handcrafted AST or a model 3264 // file. The locations from handcrafted ASTs have no valid source locations 3265 // and have to be discarded. Locations from model files should be preserved 3266 // for processing and reporting. 3267 if (DeclCtx->isBodyAutosynthesized() && 3268 !DeclCtx->isBodyAutosynthesizedFromModelFile()) 3269 return; 3270 } 3271 3272 bool ValidSourceLoc = R->getLocation(getSourceManager()).isValid(); 3273 assert(ValidSourceLoc); 3274 // If we mess up in a release build, we'd still prefer to just drop the bug 3275 // instead of trying to go on. 3276 if (!ValidSourceLoc) 3277 return; 3278 3279 // Compute the bug report's hash to determine its equivalence class. 3280 llvm::FoldingSetNodeID ID; 3281 R->Profile(ID); 3282 3283 // Lookup the equivance class. If there isn't one, create it. 3284 BugType& BT = R->getBugType(); 3285 Register(&BT); 3286 void *InsertPos; 3287 BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos); 3288 3289 if (!EQ) { 3290 EQ = new BugReportEquivClass(std::move(R)); 3291 EQClasses.InsertNode(EQ, InsertPos); 3292 EQClassesVector.push_back(EQ); 3293 } else 3294 EQ->AddReport(std::move(R)); 3295 } 3296 3297 3298 //===----------------------------------------------------------------------===// 3299 // Emitting reports in equivalence classes. 3300 //===----------------------------------------------------------------------===// 3301 3302 namespace { 3303 struct FRIEC_WLItem { 3304 const ExplodedNode *N; 3305 ExplodedNode::const_succ_iterator I, E; 3306 3307 FRIEC_WLItem(const ExplodedNode *n) 3308 : N(n), I(N->succ_begin()), E(N->succ_end()) {} 3309 }; 3310 } 3311 3312 static const CFGBlock *findBlockForNode(const ExplodedNode *N) { 3313 ProgramPoint P = N->getLocation(); 3314 if (auto BEP = P.getAs<BlockEntrance>()) 3315 return BEP->getBlock(); 3316 3317 // Find the node's current statement in the CFG. 3318 if (const Stmt *S = PathDiagnosticLocation::getStmt(N)) 3319 return N->getLocationContext()->getAnalysisDeclContext() 3320 ->getCFGStmtMap()->getBlock(S); 3321 3322 return nullptr; 3323 } 3324 3325 // Returns true if by simply looking at the block, we can be sure that it 3326 // results in a sink during analysis. This is useful to know when the analysis 3327 // was interrupted, and we try to figure out if it would sink eventually. 3328 // There may be many more reasons why a sink would appear during analysis 3329 // (eg. checkers may generate sinks arbitrarily), but here we only consider 3330 // sinks that would be obvious by looking at the CFG. 3331 static bool isImmediateSinkBlock(const CFGBlock *Blk) { 3332 if (Blk->hasNoReturnElement()) 3333 return true; 3334 3335 // FIXME: Throw-expressions are currently generating sinks during analysis: 3336 // they're not supported yet, and also often used for actually terminating 3337 // the program. So we should treat them as sinks in this analysis as well, 3338 // at least for now, but once we have better support for exceptions, 3339 // we'd need to carefully handle the case when the throw is being 3340 // immediately caught. 3341 if (std::any_of(Blk->begin(), Blk->end(), [](const CFGElement &Elm) { 3342 if (Optional<CFGStmt> StmtElm = Elm.getAs<CFGStmt>()) 3343 if (isa<CXXThrowExpr>(StmtElm->getStmt())) 3344 return true; 3345 return false; 3346 })) 3347 return true; 3348 3349 return false; 3350 } 3351 3352 // Returns true if by looking at the CFG surrounding the node's program 3353 // point, we can be sure that any analysis starting from this point would 3354 // eventually end with a sink. We scan the child CFG blocks in a depth-first 3355 // manner and see if all paths eventually end up in an immediate sink block. 3356 static bool isInevitablySinking(const ExplodedNode *N) { 3357 const CFG &Cfg = N->getCFG(); 3358 3359 const CFGBlock *StartBlk = findBlockForNode(N); 3360 if (!StartBlk) 3361 return false; 3362 if (isImmediateSinkBlock(StartBlk)) 3363 return true; 3364 3365 llvm::SmallVector<const CFGBlock *, 32> DFSWorkList; 3366 llvm::SmallPtrSet<const CFGBlock *, 32> Visited; 3367 3368 DFSWorkList.push_back(StartBlk); 3369 while (!DFSWorkList.empty()) { 3370 const CFGBlock *Blk = DFSWorkList.back(); 3371 DFSWorkList.pop_back(); 3372 Visited.insert(Blk); 3373 3374 for (const auto &Succ : Blk->succs()) { 3375 if (const CFGBlock *SuccBlk = Succ.getReachableBlock()) { 3376 if (SuccBlk == &Cfg.getExit()) { 3377 // If at least one path reaches the CFG exit, it means that control is 3378 // returned to the caller. For now, say that we are not sure what 3379 // happens next. If necessary, this can be improved to analyze 3380 // the parent StackFrameContext's call site in a similar manner. 3381 return false; 3382 } 3383 3384 if (!isImmediateSinkBlock(SuccBlk) && !Visited.count(SuccBlk)) { 3385 // If the block has reachable child blocks that aren't no-return, 3386 // add them to the worklist. 3387 DFSWorkList.push_back(SuccBlk); 3388 } 3389 } 3390 } 3391 } 3392 3393 // Nothing reached the exit. It can only mean one thing: there's no return. 3394 return true; 3395 } 3396 3397 static BugReport * 3398 FindReportInEquivalenceClass(BugReportEquivClass& EQ, 3399 SmallVectorImpl<BugReport*> &bugReports) { 3400 3401 BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end(); 3402 assert(I != E); 3403 BugType& BT = I->getBugType(); 3404 3405 // If we don't need to suppress any of the nodes because they are 3406 // post-dominated by a sink, simply add all the nodes in the equivalence class 3407 // to 'Nodes'. Any of the reports will serve as a "representative" report. 3408 if (!BT.isSuppressOnSink()) { 3409 BugReport *R = &*I; 3410 for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) { 3411 const ExplodedNode *N = I->getErrorNode(); 3412 if (N) { 3413 R = &*I; 3414 bugReports.push_back(R); 3415 } 3416 } 3417 return R; 3418 } 3419 3420 // For bug reports that should be suppressed when all paths are post-dominated 3421 // by a sink node, iterate through the reports in the equivalence class 3422 // until we find one that isn't post-dominated (if one exists). We use a 3423 // DFS traversal of the ExplodedGraph to find a non-sink node. We could write 3424 // this as a recursive function, but we don't want to risk blowing out the 3425 // stack for very long paths. 3426 BugReport *exampleReport = nullptr; 3427 3428 for (; I != E; ++I) { 3429 const ExplodedNode *errorNode = I->getErrorNode(); 3430 3431 if (!errorNode) 3432 continue; 3433 if (errorNode->isSink()) { 3434 llvm_unreachable( 3435 "BugType::isSuppressSink() should not be 'true' for sink end nodes"); 3436 } 3437 // No successors? By definition this nodes isn't post-dominated by a sink. 3438 if (errorNode->succ_empty()) { 3439 bugReports.push_back(&*I); 3440 if (!exampleReport) 3441 exampleReport = &*I; 3442 continue; 3443 } 3444 3445 // See if we are in a no-return CFG block. If so, treat this similarly 3446 // to being post-dominated by a sink. This works better when the analysis 3447 // is incomplete and we have never reached the no-return function call(s) 3448 // that we'd inevitably bump into on this path. 3449 if (isInevitablySinking(errorNode)) 3450 continue; 3451 3452 // At this point we know that 'N' is not a sink and it has at least one 3453 // successor. Use a DFS worklist to find a non-sink end-of-path node. 3454 typedef FRIEC_WLItem WLItem; 3455 typedef SmallVector<WLItem, 10> DFSWorkList; 3456 llvm::DenseMap<const ExplodedNode *, unsigned> Visited; 3457 3458 DFSWorkList WL; 3459 WL.push_back(errorNode); 3460 Visited[errorNode] = 1; 3461 3462 while (!WL.empty()) { 3463 WLItem &WI = WL.back(); 3464 assert(!WI.N->succ_empty()); 3465 3466 for (; WI.I != WI.E; ++WI.I) { 3467 const ExplodedNode *Succ = *WI.I; 3468 // End-of-path node? 3469 if (Succ->succ_empty()) { 3470 // If we found an end-of-path node that is not a sink. 3471 if (!Succ->isSink()) { 3472 bugReports.push_back(&*I); 3473 if (!exampleReport) 3474 exampleReport = &*I; 3475 WL.clear(); 3476 break; 3477 } 3478 // Found a sink? Continue on to the next successor. 3479 continue; 3480 } 3481 // Mark the successor as visited. If it hasn't been explored, 3482 // enqueue it to the DFS worklist. 3483 unsigned &mark = Visited[Succ]; 3484 if (!mark) { 3485 mark = 1; 3486 WL.push_back(Succ); 3487 break; 3488 } 3489 } 3490 3491 // The worklist may have been cleared at this point. First 3492 // check if it is empty before checking the last item. 3493 if (!WL.empty() && &WL.back() == &WI) 3494 WL.pop_back(); 3495 } 3496 } 3497 3498 // ExampleReport will be NULL if all the nodes in the equivalence class 3499 // were post-dominated by sinks. 3500 return exampleReport; 3501 } 3502 3503 void BugReporter::FlushReport(BugReportEquivClass& EQ) { 3504 SmallVector<BugReport*, 10> bugReports; 3505 BugReport *exampleReport = FindReportInEquivalenceClass(EQ, bugReports); 3506 if (exampleReport) { 3507 for (PathDiagnosticConsumer *PDC : getPathDiagnosticConsumers()) { 3508 FlushReport(exampleReport, *PDC, bugReports); 3509 } 3510 } 3511 } 3512 3513 void BugReporter::FlushReport(BugReport *exampleReport, 3514 PathDiagnosticConsumer &PD, 3515 ArrayRef<BugReport*> bugReports) { 3516 3517 // FIXME: Make sure we use the 'R' for the path that was actually used. 3518 // Probably doesn't make a difference in practice. 3519 BugType& BT = exampleReport->getBugType(); 3520 3521 std::unique_ptr<PathDiagnostic> D(new PathDiagnostic( 3522 exampleReport->getBugType().getCheckName(), 3523 exampleReport->getDeclWithIssue(), exampleReport->getBugType().getName(), 3524 exampleReport->getDescription(), 3525 exampleReport->getShortDescription(/*Fallback=*/false), BT.getCategory(), 3526 exampleReport->getUniqueingLocation(), 3527 exampleReport->getUniqueingDecl())); 3528 3529 if (exampleReport->isPathSensitive()) { 3530 // Generate the full path diagnostic, using the generation scheme 3531 // specified by the PathDiagnosticConsumer. Note that we have to generate 3532 // path diagnostics even for consumers which do not support paths, because 3533 // the BugReporterVisitors may mark this bug as a false positive. 3534 assert(!bugReports.empty()); 3535 3536 MaxBugClassSize.updateMax(bugReports.size()); 3537 3538 if (!generatePathDiagnostic(*D.get(), PD, bugReports)) 3539 return; 3540 3541 MaxValidBugClassSize.updateMax(bugReports.size()); 3542 3543 // Examine the report and see if the last piece is in a header. Reset the 3544 // report location to the last piece in the main source file. 3545 AnalyzerOptions &Opts = getAnalyzerOptions(); 3546 if (Opts.shouldReportIssuesInMainSourceFile() && !Opts.AnalyzeAll) 3547 D->resetDiagnosticLocationToMainFile(); 3548 } 3549 3550 // If the path is empty, generate a single step path with the location 3551 // of the issue. 3552 if (D->path.empty()) { 3553 PathDiagnosticLocation L = exampleReport->getLocation(getSourceManager()); 3554 auto piece = llvm::make_unique<PathDiagnosticEventPiece>( 3555 L, exampleReport->getDescription()); 3556 for (SourceRange Range : exampleReport->getRanges()) 3557 piece->addRange(Range); 3558 D->setEndOfPath(std::move(piece)); 3559 } 3560 3561 PathPieces &Pieces = D->getMutablePieces(); 3562 if (getAnalyzerOptions().shouldDisplayNotesAsEvents()) { 3563 // For path diagnostic consumers that don't support extra notes, 3564 // we may optionally convert those to path notes. 3565 for (auto I = exampleReport->getNotes().rbegin(), 3566 E = exampleReport->getNotes().rend(); I != E; ++I) { 3567 PathDiagnosticNotePiece *Piece = I->get(); 3568 auto ConvertedPiece = std::make_shared<PathDiagnosticEventPiece>( 3569 Piece->getLocation(), Piece->getString()); 3570 for (const auto &R: Piece->getRanges()) 3571 ConvertedPiece->addRange(R); 3572 3573 Pieces.push_front(std::move(ConvertedPiece)); 3574 } 3575 } else { 3576 for (auto I = exampleReport->getNotes().rbegin(), 3577 E = exampleReport->getNotes().rend(); I != E; ++I) 3578 Pieces.push_front(*I); 3579 } 3580 3581 // Get the meta data. 3582 const BugReport::ExtraTextList &Meta = exampleReport->getExtraText(); 3583 for (BugReport::ExtraTextList::const_iterator i = Meta.begin(), 3584 e = Meta.end(); i != e; ++i) { 3585 D->addMeta(*i); 3586 } 3587 3588 PD.HandlePathDiagnostic(std::move(D)); 3589 } 3590 3591 void BugReporter::EmitBasicReport(const Decl *DeclWithIssue, 3592 const CheckerBase *Checker, 3593 StringRef Name, StringRef Category, 3594 StringRef Str, PathDiagnosticLocation Loc, 3595 ArrayRef<SourceRange> Ranges) { 3596 EmitBasicReport(DeclWithIssue, Checker->getCheckName(), Name, Category, Str, 3597 Loc, Ranges); 3598 } 3599 void BugReporter::EmitBasicReport(const Decl *DeclWithIssue, 3600 CheckName CheckName, 3601 StringRef name, StringRef category, 3602 StringRef str, PathDiagnosticLocation Loc, 3603 ArrayRef<SourceRange> Ranges) { 3604 3605 // 'BT' is owned by BugReporter. 3606 BugType *BT = getBugTypeForName(CheckName, name, category); 3607 auto R = llvm::make_unique<BugReport>(*BT, str, Loc); 3608 R->setDeclWithIssue(DeclWithIssue); 3609 for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end(); 3610 I != E; ++I) 3611 R->addRange(*I); 3612 emitReport(std::move(R)); 3613 } 3614 3615 BugType *BugReporter::getBugTypeForName(CheckName CheckName, StringRef name, 3616 StringRef category) { 3617 SmallString<136> fullDesc; 3618 llvm::raw_svector_ostream(fullDesc) << CheckName.getName() << ":" << name 3619 << ":" << category; 3620 BugType *&BT = StrBugTypes[fullDesc]; 3621 if (!BT) 3622 BT = new BugType(CheckName, name, category); 3623 return BT; 3624 } 3625 3626 LLVM_DUMP_METHOD void PathPieces::dump() const { 3627 unsigned index = 0; 3628 for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) { 3629 llvm::errs() << "[" << index++ << "] "; 3630 (*I)->dump(); 3631 llvm::errs() << "\n"; 3632 } 3633 } 3634 3635 LLVM_DUMP_METHOD void PathDiagnosticCallPiece::dump() const { 3636 llvm::errs() << "CALL\n--------------\n"; 3637 3638 if (const Stmt *SLoc = getLocStmt(getLocation())) 3639 SLoc->dump(); 3640 else if (const NamedDecl *ND = dyn_cast<NamedDecl>(getCallee())) 3641 llvm::errs() << *ND << "\n"; 3642 else 3643 getLocation().dump(); 3644 } 3645 3646 LLVM_DUMP_METHOD void PathDiagnosticEventPiece::dump() const { 3647 llvm::errs() << "EVENT\n--------------\n"; 3648 llvm::errs() << getString() << "\n"; 3649 llvm::errs() << " ---- at ----\n"; 3650 getLocation().dump(); 3651 } 3652 3653 LLVM_DUMP_METHOD void PathDiagnosticControlFlowPiece::dump() const { 3654 llvm::errs() << "CONTROL\n--------------\n"; 3655 getStartLocation().dump(); 3656 llvm::errs() << " ---- to ----\n"; 3657 getEndLocation().dump(); 3658 } 3659 3660 LLVM_DUMP_METHOD void PathDiagnosticMacroPiece::dump() const { 3661 llvm::errs() << "MACRO\n--------------\n"; 3662 // FIXME: Print which macro is being invoked. 3663 } 3664 3665 LLVM_DUMP_METHOD void PathDiagnosticNotePiece::dump() const { 3666 llvm::errs() << "NOTE\n--------------\n"; 3667 llvm::errs() << getString() << "\n"; 3668 llvm::errs() << " ---- at ----\n"; 3669 getLocation().dump(); 3670 } 3671 3672 LLVM_DUMP_METHOD void PathDiagnosticLocation::dump() const { 3673 if (!isValid()) { 3674 llvm::errs() << "<INVALID>\n"; 3675 return; 3676 } 3677 3678 switch (K) { 3679 case RangeK: 3680 // FIXME: actually print the range. 3681 llvm::errs() << "<range>\n"; 3682 break; 3683 case SingleLocK: 3684 asLocation().dump(); 3685 llvm::errs() << "\n"; 3686 break; 3687 case StmtK: 3688 if (S) 3689 S->dump(); 3690 else 3691 llvm::errs() << "<NULL STMT>\n"; 3692 break; 3693 case DeclK: 3694 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) 3695 llvm::errs() << *ND << "\n"; 3696 else if (isa<BlockDecl>(D)) 3697 // FIXME: Make this nicer. 3698 llvm::errs() << "<block>\n"; 3699 else if (D) 3700 llvm::errs() << "<unknown decl>\n"; 3701 else 3702 llvm::errs() << "<NULL DECL>\n"; 3703 break; 3704 } 3705 } 3706