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