1 //===- BugReporterVisitors.cpp - Helpers for reporting 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 a set of BugReporter "visitors" which can be used to 10 // enhance the diagnostics reported for a bug. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/Decl.h" 17 #include "clang/AST/DeclBase.h" 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/Expr.h" 20 #include "clang/AST/ExprCXX.h" 21 #include "clang/AST/ExprObjC.h" 22 #include "clang/AST/Stmt.h" 23 #include "clang/AST/Type.h" 24 #include "clang/ASTMatchers/ASTMatchFinder.h" 25 #include "clang/Analysis/Analyses/Dominators.h" 26 #include "clang/Analysis/AnalysisDeclContext.h" 27 #include "clang/Analysis/CFG.h" 28 #include "clang/Analysis/CFGStmtMap.h" 29 #include "clang/Analysis/ProgramPoint.h" 30 #include "clang/Basic/IdentifierTable.h" 31 #include "clang/Basic/LLVM.h" 32 #include "clang/Basic/SourceLocation.h" 33 #include "clang/Basic/SourceManager.h" 34 #include "clang/Lex/Lexer.h" 35 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" 36 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 37 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" 38 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 39 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 40 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" 41 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 42 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 43 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 44 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" 45 #include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h" 46 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" 47 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 48 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" 49 #include "llvm/ADT/ArrayRef.h" 50 #include "llvm/ADT/None.h" 51 #include "llvm/ADT/Optional.h" 52 #include "llvm/ADT/STLExtras.h" 53 #include "llvm/ADT/SmallPtrSet.h" 54 #include "llvm/ADT/SmallString.h" 55 #include "llvm/ADT/SmallVector.h" 56 #include "llvm/ADT/StringExtras.h" 57 #include "llvm/ADT/StringRef.h" 58 #include "llvm/Support/Casting.h" 59 #include "llvm/Support/ErrorHandling.h" 60 #include "llvm/Support/raw_ostream.h" 61 #include <cassert> 62 #include <deque> 63 #include <memory> 64 #include <string> 65 #include <utility> 66 67 using namespace clang; 68 using namespace ento; 69 70 //===----------------------------------------------------------------------===// 71 // Utility functions. 72 //===----------------------------------------------------------------------===// 73 74 static const Expr *peelOffPointerArithmetic(const BinaryOperator *B) { 75 if (B->isAdditiveOp() && B->getType()->isPointerType()) { 76 if (B->getLHS()->getType()->isPointerType()) { 77 return B->getLHS(); 78 } else if (B->getRHS()->getType()->isPointerType()) { 79 return B->getRHS(); 80 } 81 } 82 return nullptr; 83 } 84 85 /// Given that expression S represents a pointer that would be dereferenced, 86 /// try to find a sub-expression from which the pointer came from. 87 /// This is used for tracking down origins of a null or undefined value: 88 /// "this is null because that is null because that is null" etc. 89 /// We wipe away field and element offsets because they merely add offsets. 90 /// We also wipe away all casts except lvalue-to-rvalue casts, because the 91 /// latter represent an actual pointer dereference; however, we remove 92 /// the final lvalue-to-rvalue cast before returning from this function 93 /// because it demonstrates more clearly from where the pointer rvalue was 94 /// loaded. Examples: 95 /// x->y.z ==> x (lvalue) 96 /// foo()->y.z ==> foo() (rvalue) 97 const Expr *bugreporter::getDerefExpr(const Stmt *S) { 98 const auto *E = dyn_cast<Expr>(S); 99 if (!E) 100 return nullptr; 101 102 while (true) { 103 if (const auto *CE = dyn_cast<CastExpr>(E)) { 104 if (CE->getCastKind() == CK_LValueToRValue) { 105 // This cast represents the load we're looking for. 106 break; 107 } 108 E = CE->getSubExpr(); 109 } else if (const auto *B = dyn_cast<BinaryOperator>(E)) { 110 // Pointer arithmetic: '*(x + 2)' -> 'x') etc. 111 if (const Expr *Inner = peelOffPointerArithmetic(B)) { 112 E = Inner; 113 } else { 114 // Probably more arithmetic can be pattern-matched here, 115 // but for now give up. 116 break; 117 } 118 } else if (const auto *U = dyn_cast<UnaryOperator>(E)) { 119 if (U->getOpcode() == UO_Deref || U->getOpcode() == UO_AddrOf || 120 (U->isIncrementDecrementOp() && U->getType()->isPointerType())) { 121 // Operators '*' and '&' don't actually mean anything. 122 // We look at casts instead. 123 E = U->getSubExpr(); 124 } else { 125 // Probably more arithmetic can be pattern-matched here, 126 // but for now give up. 127 break; 128 } 129 } 130 // Pattern match for a few useful cases: a[0], p->f, *p etc. 131 else if (const auto *ME = dyn_cast<MemberExpr>(E)) { 132 E = ME->getBase(); 133 } else if (const auto *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) { 134 E = IvarRef->getBase(); 135 } else if (const auto *AE = dyn_cast<ArraySubscriptExpr>(E)) { 136 E = AE->getBase(); 137 } else if (const auto *PE = dyn_cast<ParenExpr>(E)) { 138 E = PE->getSubExpr(); 139 } else if (const auto *FE = dyn_cast<FullExpr>(E)) { 140 E = FE->getSubExpr(); 141 } else { 142 // Other arbitrary stuff. 143 break; 144 } 145 } 146 147 // Special case: remove the final lvalue-to-rvalue cast, but do not recurse 148 // deeper into the sub-expression. This way we return the lvalue from which 149 // our pointer rvalue was loaded. 150 if (const auto *CE = dyn_cast<ImplicitCastExpr>(E)) 151 if (CE->getCastKind() == CK_LValueToRValue) 152 E = CE->getSubExpr(); 153 154 return E; 155 } 156 157 /// Comparing internal representations of symbolic values (via 158 /// SVal::operator==()) is a valid way to check if the value was updated, 159 /// unless it's a LazyCompoundVal that may have a different internal 160 /// representation every time it is loaded from the state. In this function we 161 /// do an approximate comparison for lazy compound values, checking that they 162 /// are the immediate snapshots of the tracked region's bindings within the 163 /// node's respective states but not really checking that these snapshots 164 /// actually contain the same set of bindings. 165 static bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal, 166 const ExplodedNode *RightNode, SVal RightVal) { 167 if (LeftVal == RightVal) 168 return true; 169 170 const auto LLCV = LeftVal.getAs<nonloc::LazyCompoundVal>(); 171 if (!LLCV) 172 return false; 173 174 const auto RLCV = RightVal.getAs<nonloc::LazyCompoundVal>(); 175 if (!RLCV) 176 return false; 177 178 return LLCV->getRegion() == RLCV->getRegion() && 179 LLCV->getStore() == LeftNode->getState()->getStore() && 180 RLCV->getStore() == RightNode->getState()->getStore(); 181 } 182 183 static Optional<const llvm::APSInt *> 184 getConcreteIntegerValue(const Expr *CondVarExpr, const ExplodedNode *N) { 185 ProgramStateRef State = N->getState(); 186 const LocationContext *LCtx = N->getLocationContext(); 187 188 // The declaration of the value may rely on a pointer so take its l-value. 189 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(CondVarExpr)) { 190 if (const auto *VD = dyn_cast_or_null<VarDecl>(DRE->getDecl())) { 191 SVal DeclSVal = State->getSVal(State->getLValue(VD, LCtx)); 192 if (auto DeclCI = DeclSVal.getAs<nonloc::ConcreteInt>()) 193 return &DeclCI->getValue(); 194 } 195 } 196 197 return {}; 198 } 199 200 /// \return name of the macro inside the location \p Loc. 201 static StringRef getMacroName(SourceLocation Loc, 202 BugReporterContext &BRC) { 203 return Lexer::getImmediateMacroName( 204 Loc, 205 BRC.getSourceManager(), 206 BRC.getASTContext().getLangOpts()); 207 } 208 209 /// \return Whether given spelling location corresponds to an expansion 210 /// of a function-like macro. 211 static bool isFunctionMacroExpansion(SourceLocation Loc, 212 const SourceManager &SM) { 213 if (!Loc.isMacroID()) 214 return false; 215 while (SM.isMacroArgExpansion(Loc)) 216 Loc = SM.getImmediateExpansionRange(Loc).getBegin(); 217 std::pair<FileID, unsigned> TLInfo = SM.getDecomposedLoc(Loc); 218 SrcMgr::SLocEntry SE = SM.getSLocEntry(TLInfo.first); 219 const SrcMgr::ExpansionInfo &EInfo = SE.getExpansion(); 220 return EInfo.isFunctionMacroExpansion(); 221 } 222 223 /// \return Whether \c RegionOfInterest was modified at \p N, 224 /// where \p ValueAfter is \c RegionOfInterest's value at the end of the 225 /// stack frame. 226 static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest, 227 const ExplodedNode *N, 228 SVal ValueAfter) { 229 ProgramStateRef State = N->getState(); 230 ProgramStateManager &Mgr = N->getState()->getStateManager(); 231 232 if (!N->getLocationAs<PostStore>() && !N->getLocationAs<PostInitializer>() && 233 !N->getLocationAs<PostStmt>()) 234 return false; 235 236 // Writing into region of interest. 237 if (auto PS = N->getLocationAs<PostStmt>()) 238 if (auto *BO = PS->getStmtAs<BinaryOperator>()) 239 if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf( 240 N->getSVal(BO->getLHS()).getAsRegion())) 241 return true; 242 243 // SVal after the state is possibly different. 244 SVal ValueAtN = N->getState()->getSVal(RegionOfInterest); 245 if (!Mgr.getSValBuilder() 246 .areEqual(State, ValueAtN, ValueAfter) 247 .isConstrainedTrue() && 248 (!ValueAtN.isUndef() || !ValueAfter.isUndef())) 249 return true; 250 251 return false; 252 } 253 254 //===----------------------------------------------------------------------===// 255 // Implementation of BugReporterVisitor. 256 //===----------------------------------------------------------------------===// 257 258 PathDiagnosticPieceRef BugReporterVisitor::getEndPath(BugReporterContext &, 259 const ExplodedNode *, 260 BugReport &) { 261 return nullptr; 262 } 263 264 void BugReporterVisitor::finalizeVisitor(BugReporterContext &, 265 const ExplodedNode *, BugReport &) {} 266 267 PathDiagnosticPieceRef 268 BugReporterVisitor::getDefaultEndPath(const BugReporterContext &BRC, 269 const ExplodedNode *EndPathNode, 270 const BugReport &BR) { 271 PathDiagnosticLocation L = PathDiagnosticLocation::createEndOfPath( 272 EndPathNode, BRC.getSourceManager()); 273 274 const auto &Ranges = BR.getRanges(); 275 276 // Only add the statement itself as a range if we didn't specify any 277 // special ranges for this report. 278 auto P = std::make_shared<PathDiagnosticEventPiece>( 279 L, BR.getDescription(), Ranges.begin() == Ranges.end()); 280 for (SourceRange Range : Ranges) 281 P->addRange(Range); 282 283 return P; 284 } 285 286 //===----------------------------------------------------------------------===// 287 // Implementation of NoStoreFuncVisitor. 288 //===----------------------------------------------------------------------===// 289 290 namespace { 291 292 /// Put a diagnostic on return statement of all inlined functions 293 /// for which the region of interest \p RegionOfInterest was passed into, 294 /// but not written inside, and it has caused an undefined read or a null 295 /// pointer dereference outside. 296 class NoStoreFuncVisitor final : public BugReporterVisitor { 297 const SubRegion *RegionOfInterest; 298 MemRegionManager &MmrMgr; 299 const SourceManager &SM; 300 const PrintingPolicy &PP; 301 302 /// Recursion limit for dereferencing fields when looking for the 303 /// region of interest. 304 /// The limit of two indicates that we will dereference fields only once. 305 static const unsigned DEREFERENCE_LIMIT = 2; 306 307 /// Frames writing into \c RegionOfInterest. 308 /// This visitor generates a note only if a function does not write into 309 /// a region of interest. This information is not immediately available 310 /// by looking at the node associated with the exit from the function 311 /// (usually the return statement). To avoid recomputing the same information 312 /// many times (going up the path for each node and checking whether the 313 /// region was written into) we instead lazily compute the 314 /// stack frames along the path which write into the region of interest. 315 llvm::SmallPtrSet<const StackFrameContext *, 32> FramesModifyingRegion; 316 llvm::SmallPtrSet<const StackFrameContext *, 32> FramesModifyingCalculated; 317 318 using RegionVector = SmallVector<const MemRegion *, 5>; 319 320 public: 321 NoStoreFuncVisitor(const SubRegion *R) 322 : RegionOfInterest(R), MmrMgr(*R->getMemRegionManager()), 323 SM(MmrMgr.getContext().getSourceManager()), 324 PP(MmrMgr.getContext().getPrintingPolicy()) {} 325 326 void Profile(llvm::FoldingSetNodeID &ID) const override { 327 static int Tag = 0; 328 ID.AddPointer(&Tag); 329 ID.AddPointer(RegionOfInterest); 330 } 331 332 void *getTag() const { 333 static int Tag = 0; 334 return static_cast<void *>(&Tag); 335 } 336 337 PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, 338 BugReporterContext &BR, 339 BugReport &R) override; 340 341 private: 342 /// Attempts to find the region of interest in a given record decl, 343 /// by either following the base classes or fields. 344 /// Dereferences fields up to a given recursion limit. 345 /// Note that \p Vec is passed by value, leading to quadratic copying cost, 346 /// but it's OK in practice since its length is limited to DEREFERENCE_LIMIT. 347 /// \return A chain fields leading to the region of interest or None. 348 const Optional<RegionVector> 349 findRegionOfInterestInRecord(const RecordDecl *RD, ProgramStateRef State, 350 const MemRegion *R, const RegionVector &Vec = {}, 351 int depth = 0); 352 353 /// Check and lazily calculate whether the region of interest is 354 /// modified in the stack frame to which \p N belongs. 355 /// The calculation is cached in FramesModifyingRegion. 356 bool isRegionOfInterestModifiedInFrame(const ExplodedNode *N) { 357 const LocationContext *Ctx = N->getLocationContext(); 358 const StackFrameContext *SCtx = Ctx->getStackFrame(); 359 if (!FramesModifyingCalculated.count(SCtx)) 360 findModifyingFrames(N); 361 return FramesModifyingRegion.count(SCtx); 362 } 363 364 /// Write to \c FramesModifyingRegion all stack frames along 365 /// the path in the current stack frame which modify \c RegionOfInterest. 366 void findModifyingFrames(const ExplodedNode *N); 367 368 /// Consume the information on the no-store stack frame in order to 369 /// either emit a note or suppress the report enirely. 370 /// \return Diagnostics piece for region not modified in the current function, 371 /// if it decides to emit one. 372 PathDiagnosticPieceRef 373 maybeEmitNote(BugReport &R, const CallEvent &Call, const ExplodedNode *N, 374 const RegionVector &FieldChain, const MemRegion *MatchedRegion, 375 StringRef FirstElement, bool FirstIsReferenceType, 376 unsigned IndirectionLevel); 377 378 /// Pretty-print region \p MatchedRegion to \p os. 379 /// \return Whether printing succeeded. 380 bool prettyPrintRegionName(StringRef FirstElement, bool FirstIsReferenceType, 381 const MemRegion *MatchedRegion, 382 const RegionVector &FieldChain, 383 int IndirectionLevel, 384 llvm::raw_svector_ostream &os); 385 386 /// Print first item in the chain, return new separator. 387 static StringRef prettyPrintFirstElement(StringRef FirstElement, 388 bool MoreItemsExpected, 389 int IndirectionLevel, 390 llvm::raw_svector_ostream &os); 391 }; 392 393 } // end of anonymous namespace 394 395 /// \return Whether the method declaration \p Parent 396 /// syntactically has a binary operation writing into the ivar \p Ivar. 397 static bool potentiallyWritesIntoIvar(const Decl *Parent, 398 const ObjCIvarDecl *Ivar) { 399 using namespace ast_matchers; 400 const char *IvarBind = "Ivar"; 401 if (!Parent || !Parent->hasBody()) 402 return false; 403 StatementMatcher WriteIntoIvarM = binaryOperator( 404 hasOperatorName("="), 405 hasLHS(ignoringParenImpCasts( 406 objcIvarRefExpr(hasDeclaration(equalsNode(Ivar))).bind(IvarBind)))); 407 StatementMatcher ParentM = stmt(hasDescendant(WriteIntoIvarM)); 408 auto Matches = match(ParentM, *Parent->getBody(), Parent->getASTContext()); 409 for (BoundNodes &Match : Matches) { 410 auto IvarRef = Match.getNodeAs<ObjCIvarRefExpr>(IvarBind); 411 if (IvarRef->isFreeIvar()) 412 return true; 413 414 const Expr *Base = IvarRef->getBase(); 415 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(Base)) 416 Base = ICE->getSubExpr(); 417 418 if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) 419 if (const auto *ID = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) 420 if (ID->getParameterKind() == ImplicitParamDecl::ObjCSelf) 421 return true; 422 423 return false; 424 } 425 return false; 426 } 427 428 /// Get parameters associated with runtime definition in order 429 /// to get the correct parameter name. 430 static ArrayRef<ParmVarDecl *> getCallParameters(CallEventRef<> Call) { 431 // Use runtime definition, if available. 432 RuntimeDefinition RD = Call->getRuntimeDefinition(); 433 if (const auto *FD = dyn_cast_or_null<FunctionDecl>(RD.getDecl())) 434 return FD->parameters(); 435 if (const auto *MD = dyn_cast_or_null<ObjCMethodDecl>(RD.getDecl())) 436 return MD->parameters(); 437 438 return Call->parameters(); 439 } 440 441 /// \return whether \p Ty points to a const type, or is a const reference. 442 static bool isPointerToConst(QualType Ty) { 443 return !Ty->getPointeeType().isNull() && 444 Ty->getPointeeType().getCanonicalType().isConstQualified(); 445 } 446 447 /// Attempts to find the region of interest in a given CXX decl, 448 /// by either following the base classes or fields. 449 /// Dereferences fields up to a given recursion limit. 450 /// Note that \p Vec is passed by value, leading to quadratic copying cost, 451 /// but it's OK in practice since its length is limited to DEREFERENCE_LIMIT. 452 /// \return A chain fields leading to the region of interest or None. 453 const Optional<NoStoreFuncVisitor::RegionVector> 454 NoStoreFuncVisitor::findRegionOfInterestInRecord( 455 const RecordDecl *RD, ProgramStateRef State, const MemRegion *R, 456 const NoStoreFuncVisitor::RegionVector &Vec /* = {} */, 457 int depth /* = 0 */) { 458 459 if (depth == DEREFERENCE_LIMIT) // Limit the recursion depth. 460 return None; 461 462 if (const auto *RDX = dyn_cast<CXXRecordDecl>(RD)) 463 if (!RDX->hasDefinition()) 464 return None; 465 466 // Recursively examine the base classes. 467 // Note that following base classes does not increase the recursion depth. 468 if (const auto *RDX = dyn_cast<CXXRecordDecl>(RD)) 469 for (const auto II : RDX->bases()) 470 if (const RecordDecl *RRD = II.getType()->getAsRecordDecl()) 471 if (Optional<RegionVector> Out = 472 findRegionOfInterestInRecord(RRD, State, R, Vec, depth)) 473 return Out; 474 475 for (const FieldDecl *I : RD->fields()) { 476 QualType FT = I->getType(); 477 const FieldRegion *FR = MmrMgr.getFieldRegion(I, cast<SubRegion>(R)); 478 const SVal V = State->getSVal(FR); 479 const MemRegion *VR = V.getAsRegion(); 480 481 RegionVector VecF = Vec; 482 VecF.push_back(FR); 483 484 if (RegionOfInterest == VR) 485 return VecF; 486 487 if (const RecordDecl *RRD = FT->getAsRecordDecl()) 488 if (auto Out = 489 findRegionOfInterestInRecord(RRD, State, FR, VecF, depth + 1)) 490 return Out; 491 492 QualType PT = FT->getPointeeType(); 493 if (PT.isNull() || PT->isVoidType() || !VR) 494 continue; 495 496 if (const RecordDecl *RRD = PT->getAsRecordDecl()) 497 if (Optional<RegionVector> Out = 498 findRegionOfInterestInRecord(RRD, State, VR, VecF, depth + 1)) 499 return Out; 500 } 501 502 return None; 503 } 504 505 PathDiagnosticPieceRef NoStoreFuncVisitor::VisitNode(const ExplodedNode *N, 506 BugReporterContext &BR, 507 BugReport &R) { 508 509 const LocationContext *Ctx = N->getLocationContext(); 510 const StackFrameContext *SCtx = Ctx->getStackFrame(); 511 ProgramStateRef State = N->getState(); 512 auto CallExitLoc = N->getLocationAs<CallExitBegin>(); 513 514 // No diagnostic if region was modified inside the frame. 515 if (!CallExitLoc || isRegionOfInterestModifiedInFrame(N)) 516 return nullptr; 517 518 CallEventRef<> Call = 519 BR.getStateManager().getCallEventManager().getCaller(SCtx, State); 520 521 // Region of interest corresponds to an IVar, exiting a method 522 // which could have written into that IVar, but did not. 523 if (const auto *MC = dyn_cast<ObjCMethodCall>(Call)) { 524 if (const auto *IvarR = dyn_cast<ObjCIvarRegion>(RegionOfInterest)) { 525 const MemRegion *SelfRegion = MC->getReceiverSVal().getAsRegion(); 526 if (RegionOfInterest->isSubRegionOf(SelfRegion) && 527 potentiallyWritesIntoIvar(Call->getRuntimeDefinition().getDecl(), 528 IvarR->getDecl())) 529 return maybeEmitNote(R, *Call, N, {}, SelfRegion, "self", 530 /*FirstIsReferenceType=*/false, 1); 531 } 532 } 533 534 if (const auto *CCall = dyn_cast<CXXConstructorCall>(Call)) { 535 const MemRegion *ThisR = CCall->getCXXThisVal().getAsRegion(); 536 if (RegionOfInterest->isSubRegionOf(ThisR) && 537 !CCall->getDecl()->isImplicit()) 538 return maybeEmitNote(R, *Call, N, {}, ThisR, "this", 539 /*FirstIsReferenceType=*/false, 1); 540 541 // Do not generate diagnostics for not modified parameters in 542 // constructors. 543 return nullptr; 544 } 545 546 ArrayRef<ParmVarDecl *> parameters = getCallParameters(Call); 547 for (unsigned I = 0; I < Call->getNumArgs() && I < parameters.size(); ++I) { 548 const ParmVarDecl *PVD = parameters[I]; 549 SVal V = Call->getArgSVal(I); 550 bool ParamIsReferenceType = PVD->getType()->isReferenceType(); 551 std::string ParamName = PVD->getNameAsString(); 552 553 int IndirectionLevel = 1; 554 QualType T = PVD->getType(); 555 while (const MemRegion *MR = V.getAsRegion()) { 556 if (RegionOfInterest->isSubRegionOf(MR) && !isPointerToConst(T)) 557 return maybeEmitNote(R, *Call, N, {}, MR, ParamName, 558 ParamIsReferenceType, IndirectionLevel); 559 560 QualType PT = T->getPointeeType(); 561 if (PT.isNull() || PT->isVoidType()) 562 break; 563 564 if (const RecordDecl *RD = PT->getAsRecordDecl()) 565 if (Optional<RegionVector> P = 566 findRegionOfInterestInRecord(RD, State, MR)) 567 return maybeEmitNote(R, *Call, N, *P, RegionOfInterest, ParamName, 568 ParamIsReferenceType, IndirectionLevel); 569 570 V = State->getSVal(MR, PT); 571 T = PT; 572 IndirectionLevel++; 573 } 574 } 575 576 return nullptr; 577 } 578 579 void NoStoreFuncVisitor::findModifyingFrames(const ExplodedNode *N) { 580 assert(N->getLocationAs<CallExitBegin>()); 581 ProgramStateRef LastReturnState = N->getState(); 582 SVal ValueAtReturn = LastReturnState->getSVal(RegionOfInterest); 583 const LocationContext *Ctx = N->getLocationContext(); 584 const StackFrameContext *OriginalSCtx = Ctx->getStackFrame(); 585 586 do { 587 ProgramStateRef State = N->getState(); 588 auto CallExitLoc = N->getLocationAs<CallExitBegin>(); 589 if (CallExitLoc) { 590 LastReturnState = State; 591 ValueAtReturn = LastReturnState->getSVal(RegionOfInterest); 592 } 593 594 FramesModifyingCalculated.insert(N->getLocationContext()->getStackFrame()); 595 596 if (wasRegionOfInterestModifiedAt(RegionOfInterest, N, ValueAtReturn)) { 597 const StackFrameContext *SCtx = N->getStackFrame(); 598 while (!SCtx->inTopFrame()) { 599 auto p = FramesModifyingRegion.insert(SCtx); 600 if (!p.second) 601 break; // Frame and all its parents already inserted. 602 SCtx = SCtx->getParent()->getStackFrame(); 603 } 604 } 605 606 // Stop calculation at the call to the current function. 607 if (auto CE = N->getLocationAs<CallEnter>()) 608 if (CE->getCalleeContext() == OriginalSCtx) 609 break; 610 611 N = N->getFirstPred(); 612 } while (N); 613 } 614 615 PathDiagnosticPieceRef NoStoreFuncVisitor::maybeEmitNote( 616 BugReport &R, const CallEvent &Call, const ExplodedNode *N, 617 const RegionVector &FieldChain, const MemRegion *MatchedRegion, 618 StringRef FirstElement, bool FirstIsReferenceType, 619 unsigned IndirectionLevel) { 620 // Optimistically suppress uninitialized value bugs that result 621 // from system headers having a chance to initialize the value 622 // but failing to do so. It's too unlikely a system header's fault. 623 // It's much more likely a situation in which the function has a failure 624 // mode that the user decided not to check. If we want to hunt such 625 // omitted checks, we should provide an explicit function-specific note 626 // describing the precondition under which the function isn't supposed to 627 // initialize its out-parameter, and additionally check that such 628 // precondition can actually be fulfilled on the current path. 629 if (Call.isInSystemHeader()) { 630 // We make an exception for system header functions that have no branches. 631 // Such functions unconditionally fail to initialize the variable. 632 // If they call other functions that have more paths within them, 633 // this suppression would still apply when we visit these inner functions. 634 // One common example of a standard function that doesn't ever initialize 635 // its out parameter is operator placement new; it's up to the follow-up 636 // constructor (if any) to initialize the memory. 637 if (!N->getStackFrame()->getCFG()->isLinear()) 638 R.markInvalid(getTag(), nullptr); 639 return nullptr; 640 } 641 642 PathDiagnosticLocation L = 643 PathDiagnosticLocation::create(N->getLocation(), SM); 644 645 // For now this shouldn't trigger, but once it does (as we add more 646 // functions to the body farm), we'll need to decide if these reports 647 // are worth suppressing as well. 648 if (!L.hasValidLocation()) 649 return nullptr; 650 651 SmallString<256> sbuf; 652 llvm::raw_svector_ostream os(sbuf); 653 os << "Returning without writing to '"; 654 655 // Do not generate the note if failed to pretty-print. 656 if (!prettyPrintRegionName(FirstElement, FirstIsReferenceType, MatchedRegion, 657 FieldChain, IndirectionLevel, os)) 658 return nullptr; 659 660 os << "'"; 661 return std::make_shared<PathDiagnosticEventPiece>(L, os.str()); 662 } 663 664 bool NoStoreFuncVisitor::prettyPrintRegionName(StringRef FirstElement, 665 bool FirstIsReferenceType, 666 const MemRegion *MatchedRegion, 667 const RegionVector &FieldChain, 668 int IndirectionLevel, 669 llvm::raw_svector_ostream &os) { 670 671 if (FirstIsReferenceType) 672 IndirectionLevel--; 673 674 RegionVector RegionSequence; 675 676 // Add the regions in the reverse order, then reverse the resulting array. 677 assert(RegionOfInterest->isSubRegionOf(MatchedRegion)); 678 const MemRegion *R = RegionOfInterest; 679 while (R != MatchedRegion) { 680 RegionSequence.push_back(R); 681 R = cast<SubRegion>(R)->getSuperRegion(); 682 } 683 std::reverse(RegionSequence.begin(), RegionSequence.end()); 684 RegionSequence.append(FieldChain.begin(), FieldChain.end()); 685 686 StringRef Sep; 687 for (const MemRegion *R : RegionSequence) { 688 689 // Just keep going up to the base region. 690 // Element regions may appear due to casts. 691 if (isa<CXXBaseObjectRegion>(R) || isa<CXXTempObjectRegion>(R)) 692 continue; 693 694 if (Sep.empty()) 695 Sep = prettyPrintFirstElement(FirstElement, 696 /*MoreItemsExpected=*/true, 697 IndirectionLevel, os); 698 699 os << Sep; 700 701 // Can only reasonably pretty-print DeclRegions. 702 if (!isa<DeclRegion>(R)) 703 return false; 704 705 const auto *DR = cast<DeclRegion>(R); 706 Sep = DR->getValueType()->isAnyPointerType() ? "->" : "."; 707 DR->getDecl()->getDeclName().print(os, PP); 708 } 709 710 if (Sep.empty()) 711 prettyPrintFirstElement(FirstElement, 712 /*MoreItemsExpected=*/false, IndirectionLevel, os); 713 return true; 714 } 715 716 StringRef NoStoreFuncVisitor::prettyPrintFirstElement( 717 StringRef FirstElement, bool MoreItemsExpected, int IndirectionLevel, 718 llvm::raw_svector_ostream &os) { 719 StringRef Out = "."; 720 721 if (IndirectionLevel > 0 && MoreItemsExpected) { 722 IndirectionLevel--; 723 Out = "->"; 724 } 725 726 if (IndirectionLevel > 0 && MoreItemsExpected) 727 os << "("; 728 729 for (int i = 0; i < IndirectionLevel; i++) 730 os << "*"; 731 os << FirstElement; 732 733 if (IndirectionLevel > 0 && MoreItemsExpected) 734 os << ")"; 735 736 return Out; 737 } 738 739 //===----------------------------------------------------------------------===// 740 // Implementation of MacroNullReturnSuppressionVisitor. 741 //===----------------------------------------------------------------------===// 742 743 namespace { 744 745 /// Suppress null-pointer-dereference bugs where dereferenced null was returned 746 /// the macro. 747 class MacroNullReturnSuppressionVisitor final : public BugReporterVisitor { 748 const SubRegion *RegionOfInterest; 749 const SVal ValueAtDereference; 750 751 // Do not invalidate the reports where the value was modified 752 // after it got assigned to from the macro. 753 bool WasModified = false; 754 755 public: 756 MacroNullReturnSuppressionVisitor(const SubRegion *R, const SVal V) 757 : RegionOfInterest(R), ValueAtDereference(V) {} 758 759 PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, 760 BugReporterContext &BRC, 761 BugReport &BR) override { 762 if (WasModified) 763 return nullptr; 764 765 auto BugPoint = BR.getErrorNode()->getLocation().getAs<StmtPoint>(); 766 if (!BugPoint) 767 return nullptr; 768 769 const SourceManager &SMgr = BRC.getSourceManager(); 770 if (auto Loc = matchAssignment(N)) { 771 if (isFunctionMacroExpansion(*Loc, SMgr)) { 772 std::string MacroName = getMacroName(*Loc, BRC); 773 SourceLocation BugLoc = BugPoint->getStmt()->getBeginLoc(); 774 if (!BugLoc.isMacroID() || getMacroName(BugLoc, BRC) != MacroName) 775 BR.markInvalid(getTag(), MacroName.c_str()); 776 } 777 } 778 779 if (wasRegionOfInterestModifiedAt(RegionOfInterest, N, ValueAtDereference)) 780 WasModified = true; 781 782 return nullptr; 783 } 784 785 static void addMacroVisitorIfNecessary( 786 const ExplodedNode *N, const MemRegion *R, 787 bool EnableNullFPSuppression, BugReport &BR, 788 const SVal V) { 789 AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; 790 if (EnableNullFPSuppression && 791 Options.ShouldSuppressNullReturnPaths && V.getAs<Loc>()) 792 BR.addVisitor(std::make_unique<MacroNullReturnSuppressionVisitor>( 793 R->getAs<SubRegion>(), V)); 794 } 795 796 void* getTag() const { 797 static int Tag = 0; 798 return static_cast<void *>(&Tag); 799 } 800 801 void Profile(llvm::FoldingSetNodeID &ID) const override { 802 ID.AddPointer(getTag()); 803 } 804 805 private: 806 /// \return Source location of right hand side of an assignment 807 /// into \c RegionOfInterest, empty optional if none found. 808 Optional<SourceLocation> matchAssignment(const ExplodedNode *N) { 809 const Stmt *S = PathDiagnosticLocation::getStmt(N); 810 ProgramStateRef State = N->getState(); 811 auto *LCtx = N->getLocationContext(); 812 if (!S) 813 return None; 814 815 if (const auto *DS = dyn_cast<DeclStmt>(S)) { 816 if (const auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) 817 if (const Expr *RHS = VD->getInit()) 818 if (RegionOfInterest->isSubRegionOf( 819 State->getLValue(VD, LCtx).getAsRegion())) 820 return RHS->getBeginLoc(); 821 } else if (const auto *BO = dyn_cast<BinaryOperator>(S)) { 822 const MemRegion *R = N->getSVal(BO->getLHS()).getAsRegion(); 823 const Expr *RHS = BO->getRHS(); 824 if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(R)) { 825 return RHS->getBeginLoc(); 826 } 827 } 828 return None; 829 } 830 }; 831 832 } // end of anonymous namespace 833 834 namespace { 835 836 /// Emits an extra note at the return statement of an interesting stack frame. 837 /// 838 /// The returned value is marked as an interesting value, and if it's null, 839 /// adds a visitor to track where it became null. 840 /// 841 /// This visitor is intended to be used when another visitor discovers that an 842 /// interesting value comes from an inlined function call. 843 class ReturnVisitor : public BugReporterVisitor { 844 const StackFrameContext *CalleeSFC; 845 enum { 846 Initial, 847 MaybeUnsuppress, 848 Satisfied 849 } Mode = Initial; 850 851 bool EnableNullFPSuppression; 852 bool ShouldInvalidate = true; 853 AnalyzerOptions& Options; 854 bugreporter::TrackingKind TKind; 855 856 public: 857 ReturnVisitor(const StackFrameContext *Frame, bool Suppressed, 858 AnalyzerOptions &Options, bugreporter::TrackingKind TKind) 859 : CalleeSFC(Frame), EnableNullFPSuppression(Suppressed), 860 Options(Options), TKind(TKind) {} 861 862 static void *getTag() { 863 static int Tag = 0; 864 return static_cast<void *>(&Tag); 865 } 866 867 void Profile(llvm::FoldingSetNodeID &ID) const override { 868 ID.AddPointer(ReturnVisitor::getTag()); 869 ID.AddPointer(CalleeSFC); 870 ID.AddBoolean(EnableNullFPSuppression); 871 } 872 873 /// Adds a ReturnVisitor if the given statement represents a call that was 874 /// inlined. 875 /// 876 /// This will search back through the ExplodedGraph, starting from the given 877 /// node, looking for when the given statement was processed. If it turns out 878 /// the statement is a call that was inlined, we add the visitor to the 879 /// bug report, so it can print a note later. 880 static void addVisitorIfNecessary(const ExplodedNode *Node, const Stmt *S, 881 BugReport &BR, 882 bool InEnableNullFPSuppression, 883 bugreporter::TrackingKind TKind) { 884 if (!CallEvent::isCallStmt(S)) 885 return; 886 887 // First, find when we processed the statement. 888 // If we work with a 'CXXNewExpr' that is going to be purged away before 889 // its call take place. We would catch that purge in the last condition 890 // as a 'StmtPoint' so we have to bypass it. 891 const bool BypassCXXNewExprEval = isa<CXXNewExpr>(S); 892 893 // This is moving forward when we enter into another context. 894 const StackFrameContext *CurrentSFC = Node->getStackFrame(); 895 896 do { 897 // If that is satisfied we found our statement as an inlined call. 898 if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>()) 899 if (CEE->getCalleeContext()->getCallSite() == S) 900 break; 901 902 // Try to move forward to the end of the call-chain. 903 Node = Node->getFirstPred(); 904 if (!Node) 905 break; 906 907 const StackFrameContext *PredSFC = Node->getStackFrame(); 908 909 // If that is satisfied we found our statement. 910 // FIXME: This code currently bypasses the call site for the 911 // conservatively evaluated allocator. 912 if (!BypassCXXNewExprEval) 913 if (Optional<StmtPoint> SP = Node->getLocationAs<StmtPoint>()) 914 // See if we do not enter into another context. 915 if (SP->getStmt() == S && CurrentSFC == PredSFC) 916 break; 917 918 CurrentSFC = PredSFC; 919 } while (Node->getStackFrame() == CurrentSFC); 920 921 // Next, step over any post-statement checks. 922 while (Node && Node->getLocation().getAs<PostStmt>()) 923 Node = Node->getFirstPred(); 924 if (!Node) 925 return; 926 927 // Finally, see if we inlined the call. 928 Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>(); 929 if (!CEE) 930 return; 931 932 const StackFrameContext *CalleeContext = CEE->getCalleeContext(); 933 if (CalleeContext->getCallSite() != S) 934 return; 935 936 // Check the return value. 937 ProgramStateRef State = Node->getState(); 938 SVal RetVal = Node->getSVal(S); 939 940 // Handle cases where a reference is returned and then immediately used. 941 if (cast<Expr>(S)->isGLValue()) 942 if (Optional<Loc> LValue = RetVal.getAs<Loc>()) 943 RetVal = State->getSVal(*LValue); 944 945 // See if the return value is NULL. If so, suppress the report. 946 AnalyzerOptions &Options = State->getAnalysisManager().options; 947 948 bool EnableNullFPSuppression = false; 949 if (InEnableNullFPSuppression && 950 Options.ShouldSuppressNullReturnPaths) 951 if (Optional<Loc> RetLoc = RetVal.getAs<Loc>()) 952 EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue(); 953 954 BR.addVisitor(std::make_unique<ReturnVisitor>(CalleeContext, 955 EnableNullFPSuppression, 956 Options, TKind)); 957 } 958 959 PathDiagnosticPieceRef visitNodeInitial(const ExplodedNode *N, 960 BugReporterContext &BRC, 961 BugReport &BR) { 962 // Only print a message at the interesting return statement. 963 if (N->getLocationContext() != CalleeSFC) 964 return nullptr; 965 966 Optional<StmtPoint> SP = N->getLocationAs<StmtPoint>(); 967 if (!SP) 968 return nullptr; 969 970 const auto *Ret = dyn_cast<ReturnStmt>(SP->getStmt()); 971 if (!Ret) 972 return nullptr; 973 974 // Okay, we're at the right return statement, but do we have the return 975 // value available? 976 ProgramStateRef State = N->getState(); 977 SVal V = State->getSVal(Ret, CalleeSFC); 978 if (V.isUnknownOrUndef()) 979 return nullptr; 980 981 // Don't print any more notes after this one. 982 Mode = Satisfied; 983 984 const Expr *RetE = Ret->getRetValue(); 985 assert(RetE && "Tracking a return value for a void function"); 986 987 // Handle cases where a reference is returned and then immediately used. 988 Optional<Loc> LValue; 989 if (RetE->isGLValue()) { 990 if ((LValue = V.getAs<Loc>())) { 991 SVal RValue = State->getRawSVal(*LValue, RetE->getType()); 992 if (RValue.getAs<DefinedSVal>()) 993 V = RValue; 994 } 995 } 996 997 // Ignore aggregate rvalues. 998 if (V.getAs<nonloc::LazyCompoundVal>() || 999 V.getAs<nonloc::CompoundVal>()) 1000 return nullptr; 1001 1002 RetE = RetE->IgnoreParenCasts(); 1003 1004 // Let's track the return value. 1005 bugreporter::trackExpressionValue( 1006 N, RetE, BR, TKind, EnableNullFPSuppression); 1007 1008 // Build an appropriate message based on the return value. 1009 SmallString<64> Msg; 1010 llvm::raw_svector_ostream Out(Msg); 1011 1012 bool WouldEventBeMeaningless = false; 1013 1014 if (State->isNull(V).isConstrainedTrue()) { 1015 if (V.getAs<Loc>()) { 1016 1017 // If we have counter-suppression enabled, make sure we keep visiting 1018 // future nodes. We want to emit a path note as well, in case 1019 // the report is resurrected as valid later on. 1020 if (EnableNullFPSuppression && 1021 Options.ShouldAvoidSuppressingNullArgumentPaths) 1022 Mode = MaybeUnsuppress; 1023 1024 if (RetE->getType()->isObjCObjectPointerType()) { 1025 Out << "Returning nil"; 1026 } else { 1027 Out << "Returning null pointer"; 1028 } 1029 } else { 1030 Out << "Returning zero"; 1031 } 1032 1033 } else { 1034 if (auto CI = V.getAs<nonloc::ConcreteInt>()) { 1035 Out << "Returning the value " << CI->getValue(); 1036 } else { 1037 // There is nothing interesting about returning a value, when it is 1038 // plain value without any constraints, and the function is guaranteed 1039 // to return that every time. We could use CFG::isLinear() here, but 1040 // constexpr branches are obvious to the compiler, not necesserily to 1041 // the programmer. 1042 if (N->getCFG().size() == 3) 1043 WouldEventBeMeaningless = true; 1044 1045 if (V.getAs<Loc>()) 1046 Out << "Returning pointer"; 1047 else 1048 Out << "Returning value"; 1049 } 1050 } 1051 1052 if (LValue) { 1053 if (const MemRegion *MR = LValue->getAsRegion()) { 1054 if (MR->canPrintPretty()) { 1055 Out << " (reference to "; 1056 MR->printPretty(Out); 1057 Out << ")"; 1058 } 1059 } 1060 } else { 1061 // FIXME: We should have a more generalized location printing mechanism. 1062 if (const auto *DR = dyn_cast<DeclRefExpr>(RetE)) 1063 if (const auto *DD = dyn_cast<DeclaratorDecl>(DR->getDecl())) 1064 Out << " (loaded from '" << *DD << "')"; 1065 } 1066 1067 PathDiagnosticLocation L(Ret, BRC.getSourceManager(), CalleeSFC); 1068 if (!L.isValid() || !L.asLocation().isValid()) 1069 return nullptr; 1070 1071 auto EventPiece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str()); 1072 1073 // If we determined that the note is meaningless, make it prunable, and 1074 // don't mark the stackframe interesting. 1075 if (WouldEventBeMeaningless) 1076 EventPiece->setPrunable(true); 1077 else 1078 BR.markInteresting(CalleeSFC); 1079 1080 return EventPiece; 1081 } 1082 1083 PathDiagnosticPieceRef visitNodeMaybeUnsuppress(const ExplodedNode *N, 1084 BugReporterContext &BRC, 1085 BugReport &BR) { 1086 #ifndef NDEBUG 1087 assert(Options.ShouldAvoidSuppressingNullArgumentPaths); 1088 #endif 1089 1090 // Are we at the entry node for this call? 1091 Optional<CallEnter> CE = N->getLocationAs<CallEnter>(); 1092 if (!CE) 1093 return nullptr; 1094 1095 if (CE->getCalleeContext() != CalleeSFC) 1096 return nullptr; 1097 1098 Mode = Satisfied; 1099 1100 // Don't automatically suppress a report if one of the arguments is 1101 // known to be a null pointer. Instead, start tracking /that/ null 1102 // value back to its origin. 1103 ProgramStateManager &StateMgr = BRC.getStateManager(); 1104 CallEventManager &CallMgr = StateMgr.getCallEventManager(); 1105 1106 ProgramStateRef State = N->getState(); 1107 CallEventRef<> Call = CallMgr.getCaller(CalleeSFC, State); 1108 for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) { 1109 Optional<Loc> ArgV = Call->getArgSVal(I).getAs<Loc>(); 1110 if (!ArgV) 1111 continue; 1112 1113 const Expr *ArgE = Call->getArgExpr(I); 1114 if (!ArgE) 1115 continue; 1116 1117 // Is it possible for this argument to be non-null? 1118 if (!State->isNull(*ArgV).isConstrainedTrue()) 1119 continue; 1120 1121 if (trackExpressionValue(N, ArgE, BR, TKind, EnableNullFPSuppression)) 1122 ShouldInvalidate = false; 1123 1124 // If we /can't/ track the null pointer, we should err on the side of 1125 // false negatives, and continue towards marking this report invalid. 1126 // (We will still look at the other arguments, though.) 1127 } 1128 1129 return nullptr; 1130 } 1131 1132 PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, 1133 BugReporterContext &BRC, 1134 BugReport &BR) override { 1135 switch (Mode) { 1136 case Initial: 1137 return visitNodeInitial(N, BRC, BR); 1138 case MaybeUnsuppress: 1139 return visitNodeMaybeUnsuppress(N, BRC, BR); 1140 case Satisfied: 1141 return nullptr; 1142 } 1143 1144 llvm_unreachable("Invalid visit mode!"); 1145 } 1146 1147 void finalizeVisitor(BugReporterContext &, const ExplodedNode *, 1148 BugReport &BR) override { 1149 if (EnableNullFPSuppression && ShouldInvalidate) 1150 BR.markInvalid(ReturnVisitor::getTag(), CalleeSFC); 1151 } 1152 }; 1153 1154 } // end of anonymous namespace 1155 1156 //===----------------------------------------------------------------------===// 1157 // Implementation of FindLastStoreBRVisitor. 1158 //===----------------------------------------------------------------------===// 1159 1160 void FindLastStoreBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const { 1161 static int tag = 0; 1162 ID.AddPointer(&tag); 1163 ID.AddPointer(R); 1164 ID.Add(V); 1165 ID.AddInteger(static_cast<int>(TKind)); 1166 ID.AddBoolean(EnableNullFPSuppression); 1167 } 1168 1169 void FindLastStoreBRVisitor::registerStatementVarDecls( 1170 BugReport &BR, const Stmt *S, bool EnableNullFPSuppression, 1171 TrackingKind TKind) { 1172 1173 const ExplodedNode *N = BR.getErrorNode(); 1174 std::deque<const Stmt *> WorkList; 1175 WorkList.push_back(S); 1176 1177 while (!WorkList.empty()) { 1178 const Stmt *Head = WorkList.front(); 1179 WorkList.pop_front(); 1180 1181 ProgramStateManager &StateMgr = N->getState()->getStateManager(); 1182 1183 if (const auto *DR = dyn_cast<DeclRefExpr>(Head)) { 1184 if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) { 1185 const VarRegion *R = 1186 StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext()); 1187 1188 // What did we load? 1189 SVal V = N->getSVal(S); 1190 1191 if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) { 1192 // Register a new visitor with the BugReport. 1193 BR.addVisitor(std::make_unique<FindLastStoreBRVisitor>( 1194 V.castAs<KnownSVal>(), R, EnableNullFPSuppression, TKind)); 1195 } 1196 } 1197 } 1198 1199 for (const Stmt *SubStmt : Head->children()) 1200 WorkList.push_back(SubStmt); 1201 } 1202 } 1203 1204 /// Returns true if \p N represents the DeclStmt declaring and initializing 1205 /// \p VR. 1206 static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR) { 1207 Optional<PostStmt> P = N->getLocationAs<PostStmt>(); 1208 if (!P) 1209 return false; 1210 1211 const DeclStmt *DS = P->getStmtAs<DeclStmt>(); 1212 if (!DS) 1213 return false; 1214 1215 if (DS->getSingleDecl() != VR->getDecl()) 1216 return false; 1217 1218 const MemSpaceRegion *VarSpace = VR->getMemorySpace(); 1219 const auto *FrameSpace = dyn_cast<StackSpaceRegion>(VarSpace); 1220 if (!FrameSpace) { 1221 // If we ever directly evaluate global DeclStmts, this assertion will be 1222 // invalid, but this still seems preferable to silently accepting an 1223 // initialization that may be for a path-sensitive variable. 1224 assert(VR->getDecl()->isStaticLocal() && "non-static stackless VarRegion"); 1225 return true; 1226 } 1227 1228 assert(VR->getDecl()->hasLocalStorage()); 1229 const LocationContext *LCtx = N->getLocationContext(); 1230 return FrameSpace->getStackFrame() == LCtx->getStackFrame(); 1231 } 1232 1233 /// Show diagnostics for initializing or declaring a region \p R with a bad value. 1234 static void showBRDiagnostics(const char *action, llvm::raw_svector_ostream &os, 1235 const MemRegion *R, SVal V, const DeclStmt *DS) { 1236 if (R->canPrintPretty()) { 1237 R->printPretty(os); 1238 os << " "; 1239 } 1240 1241 if (V.getAs<loc::ConcreteInt>()) { 1242 bool b = false; 1243 if (R->isBoundable()) { 1244 if (const auto *TR = dyn_cast<TypedValueRegion>(R)) { 1245 if (TR->getValueType()->isObjCObjectPointerType()) { 1246 os << action << "nil"; 1247 b = true; 1248 } 1249 } 1250 } 1251 if (!b) 1252 os << action << "a null pointer value"; 1253 1254 } else if (auto CVal = V.getAs<nonloc::ConcreteInt>()) { 1255 os << action << CVal->getValue(); 1256 } else if (DS) { 1257 if (V.isUndef()) { 1258 if (isa<VarRegion>(R)) { 1259 const auto *VD = cast<VarDecl>(DS->getSingleDecl()); 1260 if (VD->getInit()) { 1261 os << (R->canPrintPretty() ? "initialized" : "Initializing") 1262 << " to a garbage value"; 1263 } else { 1264 os << (R->canPrintPretty() ? "declared" : "Declaring") 1265 << " without an initial value"; 1266 } 1267 } 1268 } else { 1269 os << (R->canPrintPretty() ? "initialized" : "Initialized") 1270 << " here"; 1271 } 1272 } 1273 } 1274 1275 /// Display diagnostics for passing bad region as a parameter. 1276 static void showBRParamDiagnostics(llvm::raw_svector_ostream& os, 1277 const VarRegion *VR, 1278 SVal V) { 1279 const auto *Param = cast<ParmVarDecl>(VR->getDecl()); 1280 1281 os << "Passing "; 1282 1283 if (V.getAs<loc::ConcreteInt>()) { 1284 if (Param->getType()->isObjCObjectPointerType()) 1285 os << "nil object reference"; 1286 else 1287 os << "null pointer value"; 1288 } else if (V.isUndef()) { 1289 os << "uninitialized value"; 1290 } else if (auto CI = V.getAs<nonloc::ConcreteInt>()) { 1291 os << "the value " << CI->getValue(); 1292 } else { 1293 os << "value"; 1294 } 1295 1296 // Printed parameter indexes are 1-based, not 0-based. 1297 unsigned Idx = Param->getFunctionScopeIndex() + 1; 1298 os << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter"; 1299 if (VR->canPrintPretty()) { 1300 os << " "; 1301 VR->printPretty(os); 1302 } 1303 } 1304 1305 /// Show default diagnostics for storing bad region. 1306 static void showBRDefaultDiagnostics(llvm::raw_svector_ostream& os, 1307 const MemRegion *R, 1308 SVal V) { 1309 if (V.getAs<loc::ConcreteInt>()) { 1310 bool b = false; 1311 if (R->isBoundable()) { 1312 if (const auto *TR = dyn_cast<TypedValueRegion>(R)) { 1313 if (TR->getValueType()->isObjCObjectPointerType()) { 1314 os << "nil object reference stored"; 1315 b = true; 1316 } 1317 } 1318 } 1319 if (!b) { 1320 if (R->canPrintPretty()) 1321 os << "Null pointer value stored"; 1322 else 1323 os << "Storing null pointer value"; 1324 } 1325 1326 } else if (V.isUndef()) { 1327 if (R->canPrintPretty()) 1328 os << "Uninitialized value stored"; 1329 else 1330 os << "Storing uninitialized value"; 1331 1332 } else if (auto CV = V.getAs<nonloc::ConcreteInt>()) { 1333 if (R->canPrintPretty()) 1334 os << "The value " << CV->getValue() << " is assigned"; 1335 else 1336 os << "Assigning " << CV->getValue(); 1337 1338 } else { 1339 if (R->canPrintPretty()) 1340 os << "Value assigned"; 1341 else 1342 os << "Assigning value"; 1343 } 1344 1345 if (R->canPrintPretty()) { 1346 os << " to "; 1347 R->printPretty(os); 1348 } 1349 } 1350 1351 PathDiagnosticPieceRef 1352 FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ, 1353 BugReporterContext &BRC, BugReport &BR) { 1354 if (Satisfied) 1355 return nullptr; 1356 1357 const ExplodedNode *StoreSite = nullptr; 1358 const ExplodedNode *Pred = Succ->getFirstPred(); 1359 const Expr *InitE = nullptr; 1360 bool IsParam = false; 1361 1362 // First see if we reached the declaration of the region. 1363 if (const auto *VR = dyn_cast<VarRegion>(R)) { 1364 if (isInitializationOfVar(Pred, VR)) { 1365 StoreSite = Pred; 1366 InitE = VR->getDecl()->getInit(); 1367 } 1368 } 1369 1370 // If this is a post initializer expression, initializing the region, we 1371 // should track the initializer expression. 1372 if (Optional<PostInitializer> PIP = Pred->getLocationAs<PostInitializer>()) { 1373 const MemRegion *FieldReg = (const MemRegion *)PIP->getLocationValue(); 1374 if (FieldReg == R) { 1375 StoreSite = Pred; 1376 InitE = PIP->getInitializer()->getInit(); 1377 } 1378 } 1379 1380 // Otherwise, see if this is the store site: 1381 // (1) Succ has this binding and Pred does not, i.e. this is 1382 // where the binding first occurred. 1383 // (2) Succ has this binding and is a PostStore node for this region, i.e. 1384 // the same binding was re-assigned here. 1385 if (!StoreSite) { 1386 if (Succ->getState()->getSVal(R) != V) 1387 return nullptr; 1388 1389 if (hasVisibleUpdate(Pred, Pred->getState()->getSVal(R), Succ, V)) { 1390 Optional<PostStore> PS = Succ->getLocationAs<PostStore>(); 1391 if (!PS || PS->getLocationValue() != R) 1392 return nullptr; 1393 } 1394 1395 StoreSite = Succ; 1396 1397 // If this is an assignment expression, we can track the value 1398 // being assigned. 1399 if (Optional<PostStmt> P = Succ->getLocationAs<PostStmt>()) 1400 if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>()) 1401 if (BO->isAssignmentOp()) 1402 InitE = BO->getRHS(); 1403 1404 // If this is a call entry, the variable should be a parameter. 1405 // FIXME: Handle CXXThisRegion as well. (This is not a priority because 1406 // 'this' should never be NULL, but this visitor isn't just for NULL and 1407 // UndefinedVal.) 1408 if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) { 1409 if (const auto *VR = dyn_cast<VarRegion>(R)) { 1410 1411 const auto *Param = cast<ParmVarDecl>(VR->getDecl()); 1412 1413 ProgramStateManager &StateMgr = BRC.getStateManager(); 1414 CallEventManager &CallMgr = StateMgr.getCallEventManager(); 1415 1416 CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(), 1417 Succ->getState()); 1418 InitE = Call->getArgExpr(Param->getFunctionScopeIndex()); 1419 IsParam = true; 1420 } 1421 } 1422 1423 // If this is a CXXTempObjectRegion, the Expr responsible for its creation 1424 // is wrapped inside of it. 1425 if (const auto *TmpR = dyn_cast<CXXTempObjectRegion>(R)) 1426 InitE = TmpR->getExpr(); 1427 } 1428 1429 if (!StoreSite) 1430 return nullptr; 1431 Satisfied = true; 1432 1433 // If we have an expression that provided the value, try to track where it 1434 // came from. 1435 if (InitE) { 1436 if (!IsParam) 1437 InitE = InitE->IgnoreParenCasts(); 1438 1439 bugreporter::trackExpressionValue( 1440 StoreSite, InitE, BR, TKind, EnableNullFPSuppression); 1441 } 1442 1443 if (TKind == TrackingKind::Condition && 1444 !OriginSFC->isParentOf(StoreSite->getStackFrame())) 1445 return nullptr; 1446 1447 // Okay, we've found the binding. Emit an appropriate message. 1448 SmallString<256> sbuf; 1449 llvm::raw_svector_ostream os(sbuf); 1450 1451 if (Optional<PostStmt> PS = StoreSite->getLocationAs<PostStmt>()) { 1452 const Stmt *S = PS->getStmt(); 1453 const char *action = nullptr; 1454 const auto *DS = dyn_cast<DeclStmt>(S); 1455 const auto *VR = dyn_cast<VarRegion>(R); 1456 1457 if (DS) { 1458 action = R->canPrintPretty() ? "initialized to " : 1459 "Initializing to "; 1460 } else if (isa<BlockExpr>(S)) { 1461 action = R->canPrintPretty() ? "captured by block as " : 1462 "Captured by block as "; 1463 if (VR) { 1464 // See if we can get the BlockVarRegion. 1465 ProgramStateRef State = StoreSite->getState(); 1466 SVal V = StoreSite->getSVal(S); 1467 if (const auto *BDR = 1468 dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) { 1469 if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) { 1470 if (auto KV = State->getSVal(OriginalR).getAs<KnownSVal>()) 1471 BR.addVisitor(std::make_unique<FindLastStoreBRVisitor>( 1472 *KV, OriginalR, EnableNullFPSuppression, TKind, OriginSFC)); 1473 } 1474 } 1475 } 1476 } 1477 if (action) 1478 showBRDiagnostics(action, os, R, V, DS); 1479 1480 } else if (StoreSite->getLocation().getAs<CallEnter>()) { 1481 if (const auto *VR = dyn_cast<VarRegion>(R)) 1482 showBRParamDiagnostics(os, VR, V); 1483 } 1484 1485 if (os.str().empty()) 1486 showBRDefaultDiagnostics(os, R, V); 1487 1488 // Construct a new PathDiagnosticPiece. 1489 ProgramPoint P = StoreSite->getLocation(); 1490 PathDiagnosticLocation L; 1491 if (P.getAs<CallEnter>() && InitE) 1492 L = PathDiagnosticLocation(InitE, BRC.getSourceManager(), 1493 P.getLocationContext()); 1494 1495 if (!L.isValid() || !L.asLocation().isValid()) 1496 L = PathDiagnosticLocation::create(P, BRC.getSourceManager()); 1497 1498 if (!L.isValid() || !L.asLocation().isValid()) 1499 return nullptr; 1500 1501 return std::make_shared<PathDiagnosticEventPiece>(L, os.str()); 1502 } 1503 1504 //===----------------------------------------------------------------------===// 1505 // Implementation of TrackConstraintBRVisitor. 1506 //===----------------------------------------------------------------------===// 1507 1508 void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const { 1509 static int tag = 0; 1510 ID.AddPointer(&tag); 1511 ID.AddBoolean(Assumption); 1512 ID.Add(Constraint); 1513 } 1514 1515 /// Return the tag associated with this visitor. This tag will be used 1516 /// to make all PathDiagnosticPieces created by this visitor. 1517 const char *TrackConstraintBRVisitor::getTag() { 1518 return "TrackConstraintBRVisitor"; 1519 } 1520 1521 bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const { 1522 if (IsZeroCheck) 1523 return N->getState()->isNull(Constraint).isUnderconstrained(); 1524 return (bool)N->getState()->assume(Constraint, !Assumption); 1525 } 1526 1527 PathDiagnosticPieceRef 1528 TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N, 1529 BugReporterContext &BRC, BugReport &) { 1530 const ExplodedNode *PrevN = N->getFirstPred(); 1531 if (IsSatisfied) 1532 return nullptr; 1533 1534 // Start tracking after we see the first state in which the value is 1535 // constrained. 1536 if (!IsTrackingTurnedOn) 1537 if (!isUnderconstrained(N)) 1538 IsTrackingTurnedOn = true; 1539 if (!IsTrackingTurnedOn) 1540 return nullptr; 1541 1542 // Check if in the previous state it was feasible for this constraint 1543 // to *not* be true. 1544 if (isUnderconstrained(PrevN)) { 1545 IsSatisfied = true; 1546 1547 // As a sanity check, make sure that the negation of the constraint 1548 // was infeasible in the current state. If it is feasible, we somehow 1549 // missed the transition point. 1550 assert(!isUnderconstrained(N)); 1551 1552 // We found the transition point for the constraint. We now need to 1553 // pretty-print the constraint. (work-in-progress) 1554 SmallString<64> sbuf; 1555 llvm::raw_svector_ostream os(sbuf); 1556 1557 if (Constraint.getAs<Loc>()) { 1558 os << "Assuming pointer value is "; 1559 os << (Assumption ? "non-null" : "null"); 1560 } 1561 1562 if (os.str().empty()) 1563 return nullptr; 1564 1565 // Construct a new PathDiagnosticPiece. 1566 ProgramPoint P = N->getLocation(); 1567 PathDiagnosticLocation L = 1568 PathDiagnosticLocation::create(P, BRC.getSourceManager()); 1569 if (!L.isValid()) 1570 return nullptr; 1571 1572 auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str()); 1573 X->setTag(getTag()); 1574 return std::move(X); 1575 } 1576 1577 return nullptr; 1578 } 1579 1580 //===----------------------------------------------------------------------===// 1581 // Implementation of SuppressInlineDefensiveChecksVisitor. 1582 //===----------------------------------------------------------------------===// 1583 1584 SuppressInlineDefensiveChecksVisitor:: 1585 SuppressInlineDefensiveChecksVisitor(DefinedSVal Value, const ExplodedNode *N) 1586 : V(Value) { 1587 // Check if the visitor is disabled. 1588 AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; 1589 if (!Options.ShouldSuppressInlinedDefensiveChecks) 1590 IsSatisfied = true; 1591 1592 assert(N->getState()->isNull(V).isConstrainedTrue() && 1593 "The visitor only tracks the cases where V is constrained to 0"); 1594 } 1595 1596 void SuppressInlineDefensiveChecksVisitor::Profile( 1597 llvm::FoldingSetNodeID &ID) const { 1598 static int id = 0; 1599 ID.AddPointer(&id); 1600 ID.Add(V); 1601 } 1602 1603 const char *SuppressInlineDefensiveChecksVisitor::getTag() { 1604 return "IDCVisitor"; 1605 } 1606 1607 PathDiagnosticPieceRef SuppressInlineDefensiveChecksVisitor::VisitNode( 1608 const ExplodedNode *Succ, BugReporterContext &BRC, BugReport &BR) { 1609 const ExplodedNode *Pred = Succ->getFirstPred(); 1610 if (IsSatisfied) 1611 return nullptr; 1612 1613 // Start tracking after we see the first state in which the value is null. 1614 if (!IsTrackingTurnedOn) 1615 if (Succ->getState()->isNull(V).isConstrainedTrue()) 1616 IsTrackingTurnedOn = true; 1617 if (!IsTrackingTurnedOn) 1618 return nullptr; 1619 1620 // Check if in the previous state it was feasible for this value 1621 // to *not* be null. 1622 if (!Pred->getState()->isNull(V).isConstrainedTrue()) { 1623 IsSatisfied = true; 1624 1625 assert(Succ->getState()->isNull(V).isConstrainedTrue()); 1626 1627 // Check if this is inlined defensive checks. 1628 const LocationContext *CurLC =Succ->getLocationContext(); 1629 const LocationContext *ReportLC = BR.getErrorNode()->getLocationContext(); 1630 if (CurLC != ReportLC && !CurLC->isParentOf(ReportLC)) { 1631 BR.markInvalid("Suppress IDC", CurLC); 1632 return nullptr; 1633 } 1634 1635 // Treat defensive checks in function-like macros as if they were an inlined 1636 // defensive check. If the bug location is not in a macro and the 1637 // terminator for the current location is in a macro then suppress the 1638 // warning. 1639 auto BugPoint = BR.getErrorNode()->getLocation().getAs<StmtPoint>(); 1640 1641 if (!BugPoint) 1642 return nullptr; 1643 1644 ProgramPoint CurPoint = Succ->getLocation(); 1645 const Stmt *CurTerminatorStmt = nullptr; 1646 if (auto BE = CurPoint.getAs<BlockEdge>()) { 1647 CurTerminatorStmt = BE->getSrc()->getTerminator().getStmt(); 1648 } else if (auto SP = CurPoint.getAs<StmtPoint>()) { 1649 const Stmt *CurStmt = SP->getStmt(); 1650 if (!CurStmt->getBeginLoc().isMacroID()) 1651 return nullptr; 1652 1653 CFGStmtMap *Map = CurLC->getAnalysisDeclContext()->getCFGStmtMap(); 1654 CurTerminatorStmt = Map->getBlock(CurStmt)->getTerminatorStmt(); 1655 } else { 1656 return nullptr; 1657 } 1658 1659 if (!CurTerminatorStmt) 1660 return nullptr; 1661 1662 SourceLocation TerminatorLoc = CurTerminatorStmt->getBeginLoc(); 1663 if (TerminatorLoc.isMacroID()) { 1664 SourceLocation BugLoc = BugPoint->getStmt()->getBeginLoc(); 1665 1666 // Suppress reports unless we are in that same macro. 1667 if (!BugLoc.isMacroID() || 1668 getMacroName(BugLoc, BRC) != getMacroName(TerminatorLoc, BRC)) { 1669 BR.markInvalid("Suppress Macro IDC", CurLC); 1670 } 1671 return nullptr; 1672 } 1673 } 1674 return nullptr; 1675 } 1676 1677 //===----------------------------------------------------------------------===// 1678 // TrackControlDependencyCondBRVisitor. 1679 //===----------------------------------------------------------------------===// 1680 1681 namespace { 1682 /// Tracks the expressions that are a control dependency of the node that was 1683 /// supplied to the constructor. 1684 /// For example: 1685 /// 1686 /// cond = 1; 1687 /// if (cond) 1688 /// 10 / 0; 1689 /// 1690 /// An error is emitted at line 3. This visitor realizes that the branch 1691 /// on line 2 is a control dependency of line 3, and tracks it's condition via 1692 /// trackExpressionValue(). 1693 class TrackControlDependencyCondBRVisitor final : public BugReporterVisitor { 1694 const ExplodedNode *Origin; 1695 ControlDependencyCalculator ControlDeps; 1696 llvm::SmallSet<const CFGBlock *, 32> VisitedBlocks; 1697 1698 public: 1699 TrackControlDependencyCondBRVisitor(const ExplodedNode *O) 1700 : Origin(O), ControlDeps(&O->getCFG()) {} 1701 1702 void Profile(llvm::FoldingSetNodeID &ID) const override { 1703 static int x = 0; 1704 ID.AddPointer(&x); 1705 } 1706 1707 PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, 1708 BugReporterContext &BRC, 1709 BugReport &BR) override; 1710 }; 1711 } // end of anonymous namespace 1712 1713 static std::shared_ptr<PathDiagnosticEventPiece> 1714 constructDebugPieceForTrackedCondition(const Expr *Cond, 1715 const ExplodedNode *N, 1716 BugReporterContext &BRC) { 1717 1718 if (BRC.getAnalyzerOptions().AnalysisDiagOpt == PD_NONE || 1719 !BRC.getAnalyzerOptions().ShouldTrackConditionsDebug) 1720 return nullptr; 1721 1722 std::string ConditionText = Lexer::getSourceText( 1723 CharSourceRange::getTokenRange(Cond->getSourceRange()), 1724 BRC.getSourceManager(), 1725 BRC.getASTContext().getLangOpts()); 1726 1727 return std::make_shared<PathDiagnosticEventPiece>( 1728 PathDiagnosticLocation::createBegin( 1729 Cond, BRC.getSourceManager(), N->getLocationContext()), 1730 (Twine() + "Tracking condition '" + ConditionText + "'").str()); 1731 } 1732 1733 static bool isAssertlikeBlock(const CFGBlock *B, ASTContext &Context) { 1734 if (B->succ_size() != 2) 1735 return false; 1736 1737 const CFGBlock *Then = B->succ_begin()->getReachableBlock(); 1738 const CFGBlock *Else = (B->succ_begin() + 1)->getReachableBlock(); 1739 1740 if (!Then || !Else) 1741 return false; 1742 1743 if (Then->isInevitablySinking() != Else->isInevitablySinking()) 1744 return true; 1745 1746 // For the following condition the following CFG would be built: 1747 // 1748 // -------------> 1749 // / \ 1750 // [B1] -> [B2] -> [B3] -> [sink] 1751 // assert(A && B || C); \ \ 1752 // -----------> [go on with the execution] 1753 // 1754 // It so happens that CFGBlock::getTerminatorCondition returns 'A' for block 1755 // B1, 'A && B' for B2, and 'A && B || C' for B3. Let's check whether we 1756 // reached the end of the condition! 1757 if (const Stmt *ElseCond = Else->getTerminatorCondition()) 1758 if (isa<BinaryOperator>(ElseCond)) { 1759 assert(cast<BinaryOperator>(ElseCond)->isLogicalOp()); 1760 return isAssertlikeBlock(Else, Context); 1761 } 1762 1763 return false; 1764 } 1765 1766 PathDiagnosticPieceRef TrackControlDependencyCondBRVisitor::VisitNode( 1767 const ExplodedNode *N, BugReporterContext &BRC, BugReport &BR) { 1768 // We can only reason about control dependencies within the same stack frame. 1769 if (Origin->getStackFrame() != N->getStackFrame()) 1770 return nullptr; 1771 1772 CFGBlock *NB = const_cast<CFGBlock *>(N->getCFGBlock()); 1773 1774 // Skip if we already inspected this block. 1775 if (!VisitedBlocks.insert(NB).second) 1776 return nullptr; 1777 1778 CFGBlock *OriginB = const_cast<CFGBlock *>(Origin->getCFGBlock()); 1779 1780 // TODO: Cache CFGBlocks for each ExplodedNode. 1781 if (!OriginB || !NB) 1782 return nullptr; 1783 1784 if (isAssertlikeBlock(NB, BRC.getASTContext())) 1785 return nullptr; 1786 1787 if (ControlDeps.isControlDependent(OriginB, NB)) { 1788 if (const Expr *Condition = NB->getLastCondition()) { 1789 // Keeping track of the already tracked conditions on a visitor level 1790 // isn't sufficient, because a new visitor is created for each tracked 1791 // expression, hence the BugReport level set. 1792 if (BR.addTrackedCondition(N)) { 1793 bugreporter::trackExpressionValue( 1794 N, Condition, BR, bugreporter::TrackingKind::Condition, 1795 /*EnableNullFPSuppression=*/false); 1796 return constructDebugPieceForTrackedCondition(Condition, N, BRC); 1797 } 1798 } 1799 } 1800 1801 return nullptr; 1802 } 1803 1804 //===----------------------------------------------------------------------===// 1805 // Implementation of trackExpressionValue. 1806 //===----------------------------------------------------------------------===// 1807 1808 static const MemRegion *getLocationRegionIfReference(const Expr *E, 1809 const ExplodedNode *N) { 1810 if (const auto *DR = dyn_cast<DeclRefExpr>(E)) { 1811 if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) { 1812 if (!VD->getType()->isReferenceType()) 1813 return nullptr; 1814 ProgramStateManager &StateMgr = N->getState()->getStateManager(); 1815 MemRegionManager &MRMgr = StateMgr.getRegionManager(); 1816 return MRMgr.getVarRegion(VD, N->getLocationContext()); 1817 } 1818 } 1819 1820 // FIXME: This does not handle other kinds of null references, 1821 // for example, references from FieldRegions: 1822 // struct Wrapper { int &ref; }; 1823 // Wrapper w = { *(int *)0 }; 1824 // w.ref = 1; 1825 1826 return nullptr; 1827 } 1828 1829 /// \return A subexpression of {@code Ex} which represents the 1830 /// expression-of-interest. 1831 static const Expr *peelOffOuterExpr(const Expr *Ex, 1832 const ExplodedNode *N) { 1833 Ex = Ex->IgnoreParenCasts(); 1834 if (const auto *FE = dyn_cast<FullExpr>(Ex)) 1835 return peelOffOuterExpr(FE->getSubExpr(), N); 1836 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(Ex)) 1837 return peelOffOuterExpr(OVE->getSourceExpr(), N); 1838 if (const auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) { 1839 const auto *PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm()); 1840 if (PropRef && PropRef->isMessagingGetter()) { 1841 const Expr *GetterMessageSend = 1842 POE->getSemanticExpr(POE->getNumSemanticExprs() - 1); 1843 assert(isa<ObjCMessageExpr>(GetterMessageSend->IgnoreParenCasts())); 1844 return peelOffOuterExpr(GetterMessageSend, N); 1845 } 1846 } 1847 1848 // Peel off the ternary operator. 1849 if (const auto *CO = dyn_cast<ConditionalOperator>(Ex)) { 1850 // Find a node where the branching occurred and find out which branch 1851 // we took (true/false) by looking at the ExplodedGraph. 1852 const ExplodedNode *NI = N; 1853 do { 1854 ProgramPoint ProgPoint = NI->getLocation(); 1855 if (Optional<BlockEdge> BE = ProgPoint.getAs<BlockEdge>()) { 1856 const CFGBlock *srcBlk = BE->getSrc(); 1857 if (const Stmt *term = srcBlk->getTerminatorStmt()) { 1858 if (term == CO) { 1859 bool TookTrueBranch = (*(srcBlk->succ_begin()) == BE->getDst()); 1860 if (TookTrueBranch) 1861 return peelOffOuterExpr(CO->getTrueExpr(), N); 1862 else 1863 return peelOffOuterExpr(CO->getFalseExpr(), N); 1864 } 1865 } 1866 } 1867 NI = NI->getFirstPred(); 1868 } while (NI); 1869 } 1870 1871 if (auto *BO = dyn_cast<BinaryOperator>(Ex)) 1872 if (const Expr *SubEx = peelOffPointerArithmetic(BO)) 1873 return peelOffOuterExpr(SubEx, N); 1874 1875 if (auto *UO = dyn_cast<UnaryOperator>(Ex)) { 1876 if (UO->getOpcode() == UO_LNot) 1877 return peelOffOuterExpr(UO->getSubExpr(), N); 1878 1879 // FIXME: There's a hack in our Store implementation that always computes 1880 // field offsets around null pointers as if they are always equal to 0. 1881 // The idea here is to report accesses to fields as null dereferences 1882 // even though the pointer value that's being dereferenced is actually 1883 // the offset of the field rather than exactly 0. 1884 // See the FIXME in StoreManager's getLValueFieldOrIvar() method. 1885 // This code interacts heavily with this hack; otherwise the value 1886 // would not be null at all for most fields, so we'd be unable to track it. 1887 if (UO->getOpcode() == UO_AddrOf && UO->getSubExpr()->isLValue()) 1888 if (const Expr *DerefEx = bugreporter::getDerefExpr(UO->getSubExpr())) 1889 return peelOffOuterExpr(DerefEx, N); 1890 } 1891 1892 return Ex; 1893 } 1894 1895 /// Find the ExplodedNode where the lvalue (the value of 'Ex') 1896 /// was computed. 1897 static const ExplodedNode* findNodeForExpression(const ExplodedNode *N, 1898 const Expr *Inner) { 1899 while (N) { 1900 if (PathDiagnosticLocation::getStmt(N) == Inner) 1901 return N; 1902 N = N->getFirstPred(); 1903 } 1904 return N; 1905 } 1906 1907 bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode, 1908 const Expr *E, BugReport &report, 1909 bugreporter::TrackingKind TKind, 1910 bool EnableNullFPSuppression) { 1911 1912 if (!E || !InputNode) 1913 return false; 1914 1915 const Expr *Inner = peelOffOuterExpr(E, InputNode); 1916 const ExplodedNode *LVNode = findNodeForExpression(InputNode, Inner); 1917 if (!LVNode) 1918 return false; 1919 1920 ProgramStateRef LVState = LVNode->getState(); 1921 const StackFrameContext *SFC = LVNode->getStackFrame(); 1922 1923 // We only track expressions if we believe that they are important. Chances 1924 // are good that control dependencies to the tracking point are also improtant 1925 // because of this, let's explain why we believe control reached this point. 1926 // TODO: Shouldn't we track control dependencies of every bug location, rather 1927 // than only tracked expressions? 1928 if (LVState->getAnalysisManager().getAnalyzerOptions().ShouldTrackConditions) 1929 report.addVisitor(std::make_unique<TrackControlDependencyCondBRVisitor>( 1930 InputNode)); 1931 1932 // The message send could be nil due to the receiver being nil. 1933 // At this point in the path, the receiver should be live since we are at the 1934 // message send expr. If it is nil, start tracking it. 1935 if (const Expr *Receiver = NilReceiverBRVisitor::getNilReceiver(Inner, LVNode)) 1936 trackExpressionValue( 1937 LVNode, Receiver, report, TKind, EnableNullFPSuppression); 1938 1939 // Track the index if this is an array subscript. 1940 if (const auto *Arr = dyn_cast<ArraySubscriptExpr>(Inner)) 1941 trackExpressionValue( 1942 LVNode, Arr->getIdx(), report, TKind, /*EnableNullFPSuppression*/false); 1943 1944 // See if the expression we're interested refers to a variable. 1945 // If so, we can track both its contents and constraints on its value. 1946 if (ExplodedGraph::isInterestingLValueExpr(Inner)) { 1947 SVal LVal = LVNode->getSVal(Inner); 1948 1949 const MemRegion *RR = getLocationRegionIfReference(Inner, LVNode); 1950 bool LVIsNull = LVState->isNull(LVal).isConstrainedTrue(); 1951 1952 // If this is a C++ reference to a null pointer, we are tracking the 1953 // pointer. In addition, we should find the store at which the reference 1954 // got initialized. 1955 if (RR && !LVIsNull) 1956 if (auto KV = LVal.getAs<KnownSVal>()) 1957 report.addVisitor(std::make_unique<FindLastStoreBRVisitor>( 1958 *KV, RR, EnableNullFPSuppression, TKind, SFC)); 1959 1960 // In case of C++ references, we want to differentiate between a null 1961 // reference and reference to null pointer. 1962 // If the LVal is null, check if we are dealing with null reference. 1963 // For those, we want to track the location of the reference. 1964 const MemRegion *R = (RR && LVIsNull) ? RR : 1965 LVNode->getSVal(Inner).getAsRegion(); 1966 1967 if (R) { 1968 1969 // Mark both the variable region and its contents as interesting. 1970 SVal V = LVState->getRawSVal(loc::MemRegionVal(R)); 1971 report.addVisitor( 1972 std::make_unique<NoStoreFuncVisitor>(cast<SubRegion>(R))); 1973 1974 MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary( 1975 LVNode, R, EnableNullFPSuppression, report, V); 1976 1977 report.markInteresting(V); 1978 report.addVisitor(std::make_unique<UndefOrNullArgVisitor>(R)); 1979 1980 // If the contents are symbolic, find out when they became null. 1981 if (V.getAsLocSymbol(/*IncludeBaseRegions*/ true)) 1982 report.addVisitor(std::make_unique<TrackConstraintBRVisitor>( 1983 V.castAs<DefinedSVal>(), false)); 1984 1985 // Add visitor, which will suppress inline defensive checks. 1986 if (auto DV = V.getAs<DefinedSVal>()) 1987 if (!DV->isZeroConstant() && LVState->isNull(*DV).isConstrainedTrue() && 1988 EnableNullFPSuppression) 1989 report.addVisitor( 1990 std::make_unique<SuppressInlineDefensiveChecksVisitor>(*DV, 1991 LVNode)); 1992 1993 if (auto KV = V.getAs<KnownSVal>()) 1994 report.addVisitor(std::make_unique<FindLastStoreBRVisitor>( 1995 *KV, R, EnableNullFPSuppression, TKind, SFC)); 1996 return true; 1997 } 1998 } 1999 2000 // If the expression is not an "lvalue expression", we can still 2001 // track the constraints on its contents. 2002 SVal V = LVState->getSValAsScalarOrLoc(Inner, LVNode->getLocationContext()); 2003 2004 ReturnVisitor::addVisitorIfNecessary( 2005 LVNode, Inner, report, EnableNullFPSuppression, TKind); 2006 2007 // Is it a symbolic value? 2008 if (auto L = V.getAs<loc::MemRegionVal>()) { 2009 report.addVisitor(std::make_unique<UndefOrNullArgVisitor>(L->getRegion())); 2010 2011 // FIXME: this is a hack for fixing a later crash when attempting to 2012 // dereference a void* pointer. 2013 // We should not try to dereference pointers at all when we don't care 2014 // what is written inside the pointer. 2015 bool CanDereference = true; 2016 if (const auto *SR = L->getRegionAs<SymbolicRegion>()) { 2017 if (SR->getSymbol()->getType()->getPointeeType()->isVoidType()) 2018 CanDereference = false; 2019 } else if (L->getRegionAs<AllocaRegion>()) 2020 CanDereference = false; 2021 2022 // At this point we are dealing with the region's LValue. 2023 // However, if the rvalue is a symbolic region, we should track it as well. 2024 // Try to use the correct type when looking up the value. 2025 SVal RVal; 2026 if (ExplodedGraph::isInterestingLValueExpr(Inner)) 2027 RVal = LVState->getRawSVal(L.getValue(), Inner->getType()); 2028 else if (CanDereference) 2029 RVal = LVState->getSVal(L->getRegion()); 2030 2031 if (CanDereference) 2032 if (auto KV = RVal.getAs<KnownSVal>()) 2033 report.addVisitor(std::make_unique<FindLastStoreBRVisitor>( 2034 *KV, L->getRegion(), EnableNullFPSuppression, TKind, SFC)); 2035 2036 const MemRegion *RegionRVal = RVal.getAsRegion(); 2037 if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) { 2038 report.markInteresting(RegionRVal); 2039 report.addVisitor(std::make_unique<TrackConstraintBRVisitor>( 2040 loc::MemRegionVal(RegionRVal), /*assumption=*/false)); 2041 } 2042 } 2043 return true; 2044 } 2045 2046 //===----------------------------------------------------------------------===// 2047 // Implementation of NulReceiverBRVisitor. 2048 //===----------------------------------------------------------------------===// 2049 2050 const Expr *NilReceiverBRVisitor::getNilReceiver(const Stmt *S, 2051 const ExplodedNode *N) { 2052 const auto *ME = dyn_cast<ObjCMessageExpr>(S); 2053 if (!ME) 2054 return nullptr; 2055 if (const Expr *Receiver = ME->getInstanceReceiver()) { 2056 ProgramStateRef state = N->getState(); 2057 SVal V = N->getSVal(Receiver); 2058 if (state->isNull(V).isConstrainedTrue()) 2059 return Receiver; 2060 } 2061 return nullptr; 2062 } 2063 2064 PathDiagnosticPieceRef NilReceiverBRVisitor::VisitNode(const ExplodedNode *N, 2065 BugReporterContext &BRC, 2066 BugReport &BR) { 2067 Optional<PreStmt> P = N->getLocationAs<PreStmt>(); 2068 if (!P) 2069 return nullptr; 2070 2071 const Stmt *S = P->getStmt(); 2072 const Expr *Receiver = getNilReceiver(S, N); 2073 if (!Receiver) 2074 return nullptr; 2075 2076 llvm::SmallString<256> Buf; 2077 llvm::raw_svector_ostream OS(Buf); 2078 2079 if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) { 2080 OS << "'"; 2081 ME->getSelector().print(OS); 2082 OS << "' not called"; 2083 } 2084 else { 2085 OS << "No method is called"; 2086 } 2087 OS << " because the receiver is nil"; 2088 2089 // The receiver was nil, and hence the method was skipped. 2090 // Register a BugReporterVisitor to issue a message telling us how 2091 // the receiver was null. 2092 bugreporter::trackExpressionValue( 2093 N, Receiver, BR, bugreporter::TrackingKind::Thorough, 2094 /*EnableNullFPSuppression*/ false); 2095 // Issue a message saying that the method was skipped. 2096 PathDiagnosticLocation L(Receiver, BRC.getSourceManager(), 2097 N->getLocationContext()); 2098 return std::make_shared<PathDiagnosticEventPiece>(L, OS.str()); 2099 } 2100 2101 //===----------------------------------------------------------------------===// 2102 // Visitor that tries to report interesting diagnostics from conditions. 2103 //===----------------------------------------------------------------------===// 2104 2105 /// Return the tag associated with this visitor. This tag will be used 2106 /// to make all PathDiagnosticPieces created by this visitor. 2107 const char *ConditionBRVisitor::getTag() { return "ConditionBRVisitor"; } 2108 2109 PathDiagnosticPieceRef ConditionBRVisitor::VisitNode(const ExplodedNode *N, 2110 BugReporterContext &BRC, 2111 BugReport &BR) { 2112 auto piece = VisitNodeImpl(N, BRC, BR); 2113 if (piece) { 2114 piece->setTag(getTag()); 2115 if (auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get())) 2116 ev->setPrunable(true, /* override */ false); 2117 } 2118 return piece; 2119 } 2120 2121 PathDiagnosticPieceRef 2122 ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N, 2123 BugReporterContext &BRC, BugReport &BR) { 2124 ProgramPoint ProgPoint = N->getLocation(); 2125 const std::pair<const ProgramPointTag *, const ProgramPointTag *> &Tags = 2126 ExprEngine::geteagerlyAssumeBinOpBifurcationTags(); 2127 2128 // If an assumption was made on a branch, it should be caught 2129 // here by looking at the state transition. 2130 if (Optional<BlockEdge> BE = ProgPoint.getAs<BlockEdge>()) { 2131 const CFGBlock *SrcBlock = BE->getSrc(); 2132 if (const Stmt *Term = SrcBlock->getTerminatorStmt()) { 2133 // If the tag of the previous node is 'Eagerly Assume...' the current 2134 // 'BlockEdge' has the same constraint information. We do not want to 2135 // report the value as it is just an assumption on the predecessor node 2136 // which will be caught in the next VisitNode() iteration as a 'PostStmt'. 2137 const ProgramPointTag *PreviousNodeTag = 2138 N->getFirstPred()->getLocation().getTag(); 2139 if (PreviousNodeTag == Tags.first || PreviousNodeTag == Tags.second) 2140 return nullptr; 2141 2142 return VisitTerminator(Term, N, SrcBlock, BE->getDst(), BR, BRC); 2143 } 2144 return nullptr; 2145 } 2146 2147 if (Optional<PostStmt> PS = ProgPoint.getAs<PostStmt>()) { 2148 const ProgramPointTag *CurrentNodeTag = PS->getTag(); 2149 if (CurrentNodeTag != Tags.first && CurrentNodeTag != Tags.second) 2150 return nullptr; 2151 2152 bool TookTrue = CurrentNodeTag == Tags.first; 2153 return VisitTrueTest(cast<Expr>(PS->getStmt()), BRC, BR, N, TookTrue); 2154 } 2155 2156 return nullptr; 2157 } 2158 2159 PathDiagnosticPieceRef ConditionBRVisitor::VisitTerminator( 2160 const Stmt *Term, const ExplodedNode *N, const CFGBlock *srcBlk, 2161 const CFGBlock *dstBlk, BugReport &R, BugReporterContext &BRC) { 2162 const Expr *Cond = nullptr; 2163 2164 // In the code below, Term is a CFG terminator and Cond is a branch condition 2165 // expression upon which the decision is made on this terminator. 2166 // 2167 // For example, in "if (x == 0)", the "if (x == 0)" statement is a terminator, 2168 // and "x == 0" is the respective condition. 2169 // 2170 // Another example: in "if (x && y)", we've got two terminators and two 2171 // conditions due to short-circuit nature of operator "&&": 2172 // 1. The "if (x && y)" statement is a terminator, 2173 // and "y" is the respective condition. 2174 // 2. Also "x && ..." is another terminator, 2175 // and "x" is its condition. 2176 2177 switch (Term->getStmtClass()) { 2178 // FIXME: Stmt::SwitchStmtClass is worth handling, however it is a bit 2179 // more tricky because there are more than two branches to account for. 2180 default: 2181 return nullptr; 2182 case Stmt::IfStmtClass: 2183 Cond = cast<IfStmt>(Term)->getCond(); 2184 break; 2185 case Stmt::ConditionalOperatorClass: 2186 Cond = cast<ConditionalOperator>(Term)->getCond(); 2187 break; 2188 case Stmt::BinaryOperatorClass: 2189 // When we encounter a logical operator (&& or ||) as a CFG terminator, 2190 // then the condition is actually its LHS; otherwise, we'd encounter 2191 // the parent, such as if-statement, as a terminator. 2192 const auto *BO = cast<BinaryOperator>(Term); 2193 assert(BO->isLogicalOp() && 2194 "CFG terminator is not a short-circuit operator!"); 2195 Cond = BO->getLHS(); 2196 break; 2197 } 2198 2199 Cond = Cond->IgnoreParens(); 2200 2201 // However, when we encounter a logical operator as a branch condition, 2202 // then the condition is actually its RHS, because LHS would be 2203 // the condition for the logical operator terminator. 2204 while (const auto *InnerBO = dyn_cast<BinaryOperator>(Cond)) { 2205 if (!InnerBO->isLogicalOp()) 2206 break; 2207 Cond = InnerBO->getRHS()->IgnoreParens(); 2208 } 2209 2210 assert(Cond); 2211 assert(srcBlk->succ_size() == 2); 2212 const bool TookTrue = *(srcBlk->succ_begin()) == dstBlk; 2213 return VisitTrueTest(Cond, BRC, R, N, TookTrue); 2214 } 2215 2216 PathDiagnosticPieceRef 2217 ConditionBRVisitor::VisitTrueTest(const Expr *Cond, BugReporterContext &BRC, 2218 BugReport &R, const ExplodedNode *N, 2219 bool TookTrue) { 2220 ProgramStateRef CurrentState = N->getState(); 2221 ProgramStateRef PrevState = N->getFirstPred()->getState(); 2222 const LocationContext *LCtx = N->getLocationContext(); 2223 2224 // If the constraint information is changed between the current and the 2225 // previous program state we assuming the newly seen constraint information. 2226 // If we cannot evaluate the condition (and the constraints are the same) 2227 // the analyzer has no information about the value and just assuming it. 2228 bool IsAssuming = 2229 !BRC.getStateManager().haveEqualConstraints(CurrentState, PrevState) || 2230 CurrentState->getSVal(Cond, LCtx).isUnknownOrUndef(); 2231 2232 // These will be modified in code below, but we need to preserve the original 2233 // values in case we want to throw the generic message. 2234 const Expr *CondTmp = Cond; 2235 bool TookTrueTmp = TookTrue; 2236 2237 while (true) { 2238 CondTmp = CondTmp->IgnoreParenCasts(); 2239 switch (CondTmp->getStmtClass()) { 2240 default: 2241 break; 2242 case Stmt::BinaryOperatorClass: 2243 if (auto P = VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp), 2244 BRC, R, N, TookTrueTmp, IsAssuming)) 2245 return P; 2246 break; 2247 case Stmt::DeclRefExprClass: 2248 if (auto P = VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp), 2249 BRC, R, N, TookTrueTmp, IsAssuming)) 2250 return P; 2251 break; 2252 case Stmt::MemberExprClass: 2253 if (auto P = VisitTrueTest(Cond, cast<MemberExpr>(CondTmp), 2254 BRC, R, N, TookTrueTmp, IsAssuming)) 2255 return P; 2256 break; 2257 case Stmt::UnaryOperatorClass: { 2258 const auto *UO = cast<UnaryOperator>(CondTmp); 2259 if (UO->getOpcode() == UO_LNot) { 2260 TookTrueTmp = !TookTrueTmp; 2261 CondTmp = UO->getSubExpr(); 2262 continue; 2263 } 2264 break; 2265 } 2266 } 2267 break; 2268 } 2269 2270 // Condition too complex to explain? Just say something so that the user 2271 // knew we've made some path decision at this point. 2272 // If it is too complex and we know the evaluation of the condition do not 2273 // repeat the note from 'BugReporter.cpp' 2274 if (!IsAssuming) 2275 return nullptr; 2276 2277 PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx); 2278 if (!Loc.isValid() || !Loc.asLocation().isValid()) 2279 return nullptr; 2280 2281 return std::make_shared<PathDiagnosticEventPiece>( 2282 Loc, TookTrue ? GenericTrueMessage : GenericFalseMessage); 2283 } 2284 2285 bool ConditionBRVisitor::patternMatch(const Expr *Ex, 2286 const Expr *ParentEx, 2287 raw_ostream &Out, 2288 BugReporterContext &BRC, 2289 BugReport &report, 2290 const ExplodedNode *N, 2291 Optional<bool> &prunable, 2292 bool IsSameFieldName) { 2293 const Expr *OriginalExpr = Ex; 2294 Ex = Ex->IgnoreParenCasts(); 2295 2296 if (isa<GNUNullExpr>(Ex) || isa<ObjCBoolLiteralExpr>(Ex) || 2297 isa<CXXBoolLiteralExpr>(Ex) || isa<IntegerLiteral>(Ex) || 2298 isa<FloatingLiteral>(Ex)) { 2299 // Use heuristics to determine if the expression is a macro 2300 // expanding to a literal and if so, use the macro's name. 2301 SourceLocation BeginLoc = OriginalExpr->getBeginLoc(); 2302 SourceLocation EndLoc = OriginalExpr->getEndLoc(); 2303 if (BeginLoc.isMacroID() && EndLoc.isMacroID()) { 2304 const SourceManager &SM = BRC.getSourceManager(); 2305 const LangOptions &LO = BRC.getASTContext().getLangOpts(); 2306 if (Lexer::isAtStartOfMacroExpansion(BeginLoc, SM, LO) && 2307 Lexer::isAtEndOfMacroExpansion(EndLoc, SM, LO)) { 2308 CharSourceRange R = Lexer::getAsCharRange({BeginLoc, EndLoc}, SM, LO); 2309 Out << Lexer::getSourceText(R, SM, LO); 2310 return false; 2311 } 2312 } 2313 } 2314 2315 if (const auto *DR = dyn_cast<DeclRefExpr>(Ex)) { 2316 const bool quotes = isa<VarDecl>(DR->getDecl()); 2317 if (quotes) { 2318 Out << '\''; 2319 const LocationContext *LCtx = N->getLocationContext(); 2320 const ProgramState *state = N->getState().get(); 2321 if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()), 2322 LCtx).getAsRegion()) { 2323 if (report.isInteresting(R)) 2324 prunable = false; 2325 else { 2326 const ProgramState *state = N->getState().get(); 2327 SVal V = state->getSVal(R); 2328 if (report.isInteresting(V)) 2329 prunable = false; 2330 } 2331 } 2332 } 2333 Out << DR->getDecl()->getDeclName().getAsString(); 2334 if (quotes) 2335 Out << '\''; 2336 return quotes; 2337 } 2338 2339 if (const auto *IL = dyn_cast<IntegerLiteral>(Ex)) { 2340 QualType OriginalTy = OriginalExpr->getType(); 2341 if (OriginalTy->isPointerType()) { 2342 if (IL->getValue() == 0) { 2343 Out << "null"; 2344 return false; 2345 } 2346 } 2347 else if (OriginalTy->isObjCObjectPointerType()) { 2348 if (IL->getValue() == 0) { 2349 Out << "nil"; 2350 return false; 2351 } 2352 } 2353 2354 Out << IL->getValue(); 2355 return false; 2356 } 2357 2358 if (const auto *ME = dyn_cast<MemberExpr>(Ex)) { 2359 if (!IsSameFieldName) 2360 Out << "field '" << ME->getMemberDecl()->getName() << '\''; 2361 else 2362 Out << '\'' 2363 << Lexer::getSourceText( 2364 CharSourceRange::getTokenRange(Ex->getSourceRange()), 2365 BRC.getSourceManager(), BRC.getASTContext().getLangOpts(), 0) 2366 << '\''; 2367 } 2368 2369 return false; 2370 } 2371 2372 PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest( 2373 const Expr *Cond, const BinaryOperator *BExpr, BugReporterContext &BRC, 2374 BugReport &R, const ExplodedNode *N, bool TookTrue, bool IsAssuming) { 2375 bool shouldInvert = false; 2376 Optional<bool> shouldPrune; 2377 2378 // Check if the field name of the MemberExprs is ambiguous. Example: 2379 // " 'a.d' is equal to 'h.d' " in 'test/Analysis/null-deref-path-notes.cpp'. 2380 bool IsSameFieldName = false; 2381 const auto *LhsME = dyn_cast<MemberExpr>(BExpr->getLHS()->IgnoreParenCasts()); 2382 const auto *RhsME = dyn_cast<MemberExpr>(BExpr->getRHS()->IgnoreParenCasts()); 2383 2384 if (LhsME && RhsME) 2385 IsSameFieldName = 2386 LhsME->getMemberDecl()->getName() == RhsME->getMemberDecl()->getName(); 2387 2388 SmallString<128> LhsString, RhsString; 2389 { 2390 llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString); 2391 const bool isVarLHS = patternMatch(BExpr->getLHS(), BExpr, OutLHS, BRC, R, 2392 N, shouldPrune, IsSameFieldName); 2393 const bool isVarRHS = patternMatch(BExpr->getRHS(), BExpr, OutRHS, BRC, R, 2394 N, shouldPrune, IsSameFieldName); 2395 2396 shouldInvert = !isVarLHS && isVarRHS; 2397 } 2398 2399 BinaryOperator::Opcode Op = BExpr->getOpcode(); 2400 2401 if (BinaryOperator::isAssignmentOp(Op)) { 2402 // For assignment operators, all that we care about is that the LHS 2403 // evaluates to "true" or "false". 2404 return VisitConditionVariable(LhsString, BExpr->getLHS(), BRC, R, N, 2405 TookTrue); 2406 } 2407 2408 // For non-assignment operations, we require that we can understand 2409 // both the LHS and RHS. 2410 if (LhsString.empty() || RhsString.empty() || 2411 !BinaryOperator::isComparisonOp(Op) || Op == BO_Cmp) 2412 return nullptr; 2413 2414 // Should we invert the strings if the LHS is not a variable name? 2415 SmallString<256> buf; 2416 llvm::raw_svector_ostream Out(buf); 2417 Out << (IsAssuming ? "Assuming " : "") 2418 << (shouldInvert ? RhsString : LhsString) << " is "; 2419 2420 // Do we need to invert the opcode? 2421 if (shouldInvert) 2422 switch (Op) { 2423 default: break; 2424 case BO_LT: Op = BO_GT; break; 2425 case BO_GT: Op = BO_LT; break; 2426 case BO_LE: Op = BO_GE; break; 2427 case BO_GE: Op = BO_LE; break; 2428 } 2429 2430 if (!TookTrue) 2431 switch (Op) { 2432 case BO_EQ: Op = BO_NE; break; 2433 case BO_NE: Op = BO_EQ; break; 2434 case BO_LT: Op = BO_GE; break; 2435 case BO_GT: Op = BO_LE; break; 2436 case BO_LE: Op = BO_GT; break; 2437 case BO_GE: Op = BO_LT; break; 2438 default: 2439 return nullptr; 2440 } 2441 2442 switch (Op) { 2443 case BO_EQ: 2444 Out << "equal to "; 2445 break; 2446 case BO_NE: 2447 Out << "not equal to "; 2448 break; 2449 default: 2450 Out << BinaryOperator::getOpcodeStr(Op) << ' '; 2451 break; 2452 } 2453 2454 Out << (shouldInvert ? LhsString : RhsString); 2455 const LocationContext *LCtx = N->getLocationContext(); 2456 const SourceManager &SM = BRC.getSourceManager(); 2457 2458 // Convert 'field ...' to 'Field ...' if it is a MemberExpr. 2459 std::string Message = Out.str(); 2460 Message[0] = toupper(Message[0]); 2461 2462 // If we know the value create a pop-up note to the value part of 'BExpr'. 2463 if (!IsAssuming) { 2464 PathDiagnosticLocation Loc; 2465 if (!shouldInvert) { 2466 if (LhsME && LhsME->getMemberLoc().isValid()) 2467 Loc = PathDiagnosticLocation(LhsME->getMemberLoc(), SM); 2468 else 2469 Loc = PathDiagnosticLocation(BExpr->getLHS(), SM, LCtx); 2470 } else { 2471 if (RhsME && RhsME->getMemberLoc().isValid()) 2472 Loc = PathDiagnosticLocation(RhsME->getMemberLoc(), SM); 2473 else 2474 Loc = PathDiagnosticLocation(BExpr->getRHS(), SM, LCtx); 2475 } 2476 2477 return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Message); 2478 } 2479 2480 PathDiagnosticLocation Loc(Cond, SM, LCtx); 2481 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Message); 2482 if (shouldPrune.hasValue()) 2483 event->setPrunable(shouldPrune.getValue()); 2484 return event; 2485 } 2486 2487 PathDiagnosticPieceRef ConditionBRVisitor::VisitConditionVariable( 2488 StringRef LhsString, const Expr *CondVarExpr, BugReporterContext &BRC, 2489 BugReport &report, const ExplodedNode *N, bool TookTrue) { 2490 // FIXME: If there's already a constraint tracker for this variable, 2491 // we shouldn't emit anything here (c.f. the double note in 2492 // test/Analysis/inlining/path-notes.c) 2493 SmallString<256> buf; 2494 llvm::raw_svector_ostream Out(buf); 2495 Out << "Assuming " << LhsString << " is "; 2496 2497 if (!printValue(CondVarExpr, Out, N, TookTrue, /*IsAssuming=*/true)) 2498 return nullptr; 2499 2500 const LocationContext *LCtx = N->getLocationContext(); 2501 PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx); 2502 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str()); 2503 2504 if (const auto *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) { 2505 if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) { 2506 const ProgramState *state = N->getState().get(); 2507 if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) { 2508 if (report.isInteresting(R)) 2509 event->setPrunable(false); 2510 } 2511 } 2512 } 2513 2514 return event; 2515 } 2516 2517 PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest( 2518 const Expr *Cond, const DeclRefExpr *DRE, BugReporterContext &BRC, 2519 BugReport &report, const ExplodedNode *N, bool TookTrue, bool IsAssuming) { 2520 const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()); 2521 if (!VD) 2522 return nullptr; 2523 2524 SmallString<256> Buf; 2525 llvm::raw_svector_ostream Out(Buf); 2526 2527 Out << (IsAssuming ? "Assuming '" : "'") << VD->getDeclName() << "' is "; 2528 2529 if (!printValue(DRE, Out, N, TookTrue, IsAssuming)) 2530 return nullptr; 2531 2532 const LocationContext *LCtx = N->getLocationContext(); 2533 2534 // If we know the value create a pop-up note to the 'DRE'. 2535 if (!IsAssuming) { 2536 PathDiagnosticLocation Loc(DRE, BRC.getSourceManager(), LCtx); 2537 return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str()); 2538 } 2539 2540 PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx); 2541 auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str()); 2542 const ProgramState *state = N->getState().get(); 2543 if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) { 2544 if (report.isInteresting(R)) 2545 event->setPrunable(false); 2546 else { 2547 SVal V = state->getSVal(R); 2548 if (report.isInteresting(V)) 2549 event->setPrunable(false); 2550 } 2551 } 2552 return std::move(event); 2553 } 2554 2555 PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest( 2556 const Expr *Cond, const MemberExpr *ME, BugReporterContext &BRC, 2557 BugReport &report, const ExplodedNode *N, bool TookTrue, bool IsAssuming) { 2558 SmallString<256> Buf; 2559 llvm::raw_svector_ostream Out(Buf); 2560 2561 Out << (IsAssuming ? "Assuming field '" : "Field '") 2562 << ME->getMemberDecl()->getName() << "' is "; 2563 2564 if (!printValue(ME, Out, N, TookTrue, IsAssuming)) 2565 return nullptr; 2566 2567 const LocationContext *LCtx = N->getLocationContext(); 2568 PathDiagnosticLocation Loc; 2569 2570 // If we know the value create a pop-up note to the member of the MemberExpr. 2571 if (!IsAssuming && ME->getMemberLoc().isValid()) 2572 Loc = PathDiagnosticLocation(ME->getMemberLoc(), BRC.getSourceManager()); 2573 else 2574 Loc = PathDiagnosticLocation(Cond, BRC.getSourceManager(), LCtx); 2575 2576 if (!Loc.isValid() || !Loc.asLocation().isValid()) 2577 return nullptr; 2578 2579 if (!IsAssuming) 2580 return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str()); 2581 2582 return std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str()); 2583 } 2584 2585 bool ConditionBRVisitor::printValue(const Expr *CondVarExpr, raw_ostream &Out, 2586 const ExplodedNode *N, bool TookTrue, 2587 bool IsAssuming) { 2588 QualType Ty = CondVarExpr->getType(); 2589 2590 if (Ty->isPointerType()) { 2591 Out << (TookTrue ? "non-null" : "null"); 2592 return true; 2593 } 2594 2595 if (Ty->isObjCObjectPointerType()) { 2596 Out << (TookTrue ? "non-nil" : "nil"); 2597 return true; 2598 } 2599 2600 if (!Ty->isIntegralOrEnumerationType()) 2601 return false; 2602 2603 Optional<const llvm::APSInt *> IntValue; 2604 if (!IsAssuming) 2605 IntValue = getConcreteIntegerValue(CondVarExpr, N); 2606 2607 if (IsAssuming || !IntValue.hasValue()) { 2608 if (Ty->isBooleanType()) 2609 Out << (TookTrue ? "true" : "false"); 2610 else 2611 Out << (TookTrue ? "not equal to 0" : "0"); 2612 } else { 2613 if (Ty->isBooleanType()) 2614 Out << (IntValue.getValue()->getBoolValue() ? "true" : "false"); 2615 else 2616 Out << *IntValue.getValue(); 2617 } 2618 2619 return true; 2620 } 2621 2622 const char *const ConditionBRVisitor::GenericTrueMessage = 2623 "Assuming the condition is true"; 2624 const char *const ConditionBRVisitor::GenericFalseMessage = 2625 "Assuming the condition is false"; 2626 2627 bool ConditionBRVisitor::isPieceMessageGeneric( 2628 const PathDiagnosticPiece *Piece) { 2629 return Piece->getString() == GenericTrueMessage || 2630 Piece->getString() == GenericFalseMessage; 2631 } 2632 2633 //===----------------------------------------------------------------------===// 2634 // Implementation of LikelyFalsePositiveSuppressionBRVisitor. 2635 //===----------------------------------------------------------------------===// 2636 2637 void LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor( 2638 BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR) { 2639 // Here we suppress false positives coming from system headers. This list is 2640 // based on known issues. 2641 const AnalyzerOptions &Options = BRC.getAnalyzerOptions(); 2642 const Decl *D = N->getLocationContext()->getDecl(); 2643 2644 if (AnalysisDeclContext::isInStdNamespace(D)) { 2645 // Skip reports within the 'std' namespace. Although these can sometimes be 2646 // the user's fault, we currently don't report them very well, and 2647 // Note that this will not help for any other data structure libraries, like 2648 // TR1, Boost, or llvm/ADT. 2649 if (Options.ShouldSuppressFromCXXStandardLibrary) { 2650 BR.markInvalid(getTag(), nullptr); 2651 return; 2652 } else { 2653 // If the complete 'std' suppression is not enabled, suppress reports 2654 // from the 'std' namespace that are known to produce false positives. 2655 2656 // The analyzer issues a false use-after-free when std::list::pop_front 2657 // or std::list::pop_back are called multiple times because we cannot 2658 // reason about the internal invariants of the data structure. 2659 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { 2660 const CXXRecordDecl *CD = MD->getParent(); 2661 if (CD->getName() == "list") { 2662 BR.markInvalid(getTag(), nullptr); 2663 return; 2664 } 2665 } 2666 2667 // The analyzer issues a false positive when the constructor of 2668 // std::__independent_bits_engine from algorithms is used. 2669 if (const auto *MD = dyn_cast<CXXConstructorDecl>(D)) { 2670 const CXXRecordDecl *CD = MD->getParent(); 2671 if (CD->getName() == "__independent_bits_engine") { 2672 BR.markInvalid(getTag(), nullptr); 2673 return; 2674 } 2675 } 2676 2677 for (const LocationContext *LCtx = N->getLocationContext(); LCtx; 2678 LCtx = LCtx->getParent()) { 2679 const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl()); 2680 if (!MD) 2681 continue; 2682 2683 const CXXRecordDecl *CD = MD->getParent(); 2684 // The analyzer issues a false positive on 2685 // std::basic_string<uint8_t> v; v.push_back(1); 2686 // and 2687 // std::u16string s; s += u'a'; 2688 // because we cannot reason about the internal invariants of the 2689 // data structure. 2690 if (CD->getName() == "basic_string") { 2691 BR.markInvalid(getTag(), nullptr); 2692 return; 2693 } 2694 2695 // The analyzer issues a false positive on 2696 // std::shared_ptr<int> p(new int(1)); p = nullptr; 2697 // because it does not reason properly about temporary destructors. 2698 if (CD->getName() == "shared_ptr") { 2699 BR.markInvalid(getTag(), nullptr); 2700 return; 2701 } 2702 } 2703 } 2704 } 2705 2706 // Skip reports within the sys/queue.h macros as we do not have the ability to 2707 // reason about data structure shapes. 2708 const SourceManager &SM = BRC.getSourceManager(); 2709 FullSourceLoc Loc = BR.getLocation(SM).asLocation(); 2710 while (Loc.isMacroID()) { 2711 Loc = Loc.getSpellingLoc(); 2712 if (SM.getFilename(Loc).endswith("sys/queue.h")) { 2713 BR.markInvalid(getTag(), nullptr); 2714 return; 2715 } 2716 } 2717 } 2718 2719 //===----------------------------------------------------------------------===// 2720 // Implementation of UndefOrNullArgVisitor. 2721 //===----------------------------------------------------------------------===// 2722 2723 PathDiagnosticPieceRef UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N, 2724 BugReporterContext &BRC, 2725 BugReport &BR) { 2726 ProgramStateRef State = N->getState(); 2727 ProgramPoint ProgLoc = N->getLocation(); 2728 2729 // We are only interested in visiting CallEnter nodes. 2730 Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>(); 2731 if (!CEnter) 2732 return nullptr; 2733 2734 // Check if one of the arguments is the region the visitor is tracking. 2735 CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager(); 2736 CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State); 2737 unsigned Idx = 0; 2738 ArrayRef<ParmVarDecl *> parms = Call->parameters(); 2739 2740 for (const auto ParamDecl : parms) { 2741 const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion(); 2742 ++Idx; 2743 2744 // Are we tracking the argument or its subregion? 2745 if ( !ArgReg || !R->isSubRegionOf(ArgReg->StripCasts())) 2746 continue; 2747 2748 // Check the function parameter type. 2749 assert(ParamDecl && "Formal parameter has no decl?"); 2750 QualType T = ParamDecl->getType(); 2751 2752 if (!(T->isAnyPointerType() || T->isReferenceType())) { 2753 // Function can only change the value passed in by address. 2754 continue; 2755 } 2756 2757 // If it is a const pointer value, the function does not intend to 2758 // change the value. 2759 if (T->getPointeeType().isConstQualified()) 2760 continue; 2761 2762 // Mark the call site (LocationContext) as interesting if the value of the 2763 // argument is undefined or '0'/'NULL'. 2764 SVal BoundVal = State->getSVal(R); 2765 if (BoundVal.isUndef() || BoundVal.isZeroConstant()) { 2766 BR.markInteresting(CEnter->getCalleeContext()); 2767 return nullptr; 2768 } 2769 } 2770 return nullptr; 2771 } 2772 2773 //===----------------------------------------------------------------------===// 2774 // Implementation of FalsePositiveRefutationBRVisitor. 2775 //===----------------------------------------------------------------------===// 2776 2777 FalsePositiveRefutationBRVisitor::FalsePositiveRefutationBRVisitor() 2778 : Constraints(ConstraintRangeTy::Factory().getEmptyMap()) {} 2779 2780 void FalsePositiveRefutationBRVisitor::finalizeVisitor( 2781 BugReporterContext &BRC, const ExplodedNode *EndPathNode, BugReport &BR) { 2782 // Collect new constraints 2783 VisitNode(EndPathNode, BRC, BR); 2784 2785 // Create a refutation manager 2786 llvm::SMTSolverRef RefutationSolver = llvm::CreateZ3Solver(); 2787 ASTContext &Ctx = BRC.getASTContext(); 2788 2789 // Add constraints to the solver 2790 for (const auto &I : Constraints) { 2791 const SymbolRef Sym = I.first; 2792 auto RangeIt = I.second.begin(); 2793 2794 llvm::SMTExprRef Constraints = SMTConv::getRangeExpr( 2795 RefutationSolver, Ctx, Sym, RangeIt->From(), RangeIt->To(), 2796 /*InRange=*/true); 2797 while ((++RangeIt) != I.second.end()) { 2798 Constraints = RefutationSolver->mkOr( 2799 Constraints, SMTConv::getRangeExpr(RefutationSolver, Ctx, Sym, 2800 RangeIt->From(), RangeIt->To(), 2801 /*InRange=*/true)); 2802 } 2803 2804 RefutationSolver->addConstraint(Constraints); 2805 } 2806 2807 // And check for satisfiability 2808 Optional<bool> isSat = RefutationSolver->check(); 2809 if (!isSat.hasValue()) 2810 return; 2811 2812 if (!isSat.getValue()) 2813 BR.markInvalid("Infeasible constraints", EndPathNode->getLocationContext()); 2814 } 2815 2816 PathDiagnosticPieceRef 2817 FalsePositiveRefutationBRVisitor::VisitNode(const ExplodedNode *N, 2818 BugReporterContext &, BugReport &) { 2819 // Collect new constraints 2820 const ConstraintRangeTy &NewCs = N->getState()->get<ConstraintRange>(); 2821 ConstraintRangeTy::Factory &CF = 2822 N->getState()->get_context<ConstraintRange>(); 2823 2824 // Add constraints if we don't have them yet 2825 for (auto const &C : NewCs) { 2826 const SymbolRef &Sym = C.first; 2827 if (!Constraints.contains(Sym)) { 2828 Constraints = CF.add(Constraints, Sym, C.second); 2829 } 2830 } 2831 2832 return nullptr; 2833 } 2834 2835 void FalsePositiveRefutationBRVisitor::Profile( 2836 llvm::FoldingSetNodeID &ID) const { 2837 static int Tag = 0; 2838 ID.AddPointer(&Tag); 2839 } 2840 2841 //===----------------------------------------------------------------------===// 2842 // Implementation of TagVisitor. 2843 //===----------------------------------------------------------------------===// 2844 2845 int NoteTag::Kind = 0; 2846 2847 void TagVisitor::Profile(llvm::FoldingSetNodeID &ID) const { 2848 static int Tag = 0; 2849 ID.AddPointer(&Tag); 2850 } 2851 2852 PathDiagnosticPieceRef TagVisitor::VisitNode(const ExplodedNode *N, 2853 BugReporterContext &BRC, 2854 BugReport &R) { 2855 ProgramPoint PP = N->getLocation(); 2856 const NoteTag *T = dyn_cast_or_null<NoteTag>(PP.getTag()); 2857 if (!T) 2858 return nullptr; 2859 2860 if (Optional<std::string> Msg = T->generateMessage(BRC, R)) { 2861 PathDiagnosticLocation Loc = 2862 PathDiagnosticLocation::create(PP, BRC.getSourceManager()); 2863 auto Piece = std::make_shared<PathDiagnosticEventPiece>(Loc, *Msg); 2864 Piece->setPrunable(T->isPrunable()); 2865 return Piece; 2866 } 2867 2868 return nullptr; 2869 } 2870