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