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