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