1 //===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the C++ expression evaluation engine. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 15 #include "clang/AST/DeclCXX.h" 16 #include "clang/AST/StmtCXX.h" 17 #include "clang/AST/ParentMap.h" 18 #include "clang/Basic/PrettyStackTrace.h" 19 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 20 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 21 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 22 23 using namespace clang; 24 using namespace ento; 25 26 void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 27 ExplodedNode *Pred, 28 ExplodedNodeSet &Dst) { 29 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 30 const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens(); 31 ProgramStateRef state = Pred->getState(); 32 const LocationContext *LCtx = Pred->getLocationContext(); 33 34 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME); 35 Bldr.generateNode(ME, Pred, state); 36 } 37 38 // FIXME: This is the sort of code that should eventually live in a Core 39 // checker rather than as a special case in ExprEngine. 40 void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 41 const CallEvent &Call) { 42 SVal ThisVal; 43 bool AlwaysReturnsLValue; 44 if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) { 45 assert(Ctor->getDecl()->isTrivial()); 46 assert(Ctor->getDecl()->isCopyOrMoveConstructor()); 47 ThisVal = Ctor->getCXXThisVal(); 48 AlwaysReturnsLValue = false; 49 } else { 50 assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial()); 51 assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() == 52 OO_Equal); 53 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal(); 54 AlwaysReturnsLValue = true; 55 } 56 57 const LocationContext *LCtx = Pred->getLocationContext(); 58 59 ExplodedNodeSet Dst; 60 Bldr.takeNodes(Pred); 61 62 SVal V = Call.getArgSVal(0); 63 64 // If the value being copied is not unknown, load from its location to get 65 // an aggregate rvalue. 66 if (Optional<Loc> L = V.getAs<Loc>()) 67 V = Pred->getState()->getSVal(*L); 68 else 69 assert(V.isUnknownOrUndef()); 70 71 const Expr *CallExpr = Call.getOriginExpr(); 72 evalBind(Dst, CallExpr, Pred, ThisVal, V, true); 73 74 PostStmt PS(CallExpr, LCtx); 75 for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); 76 I != E; ++I) { 77 ProgramStateRef State = (*I)->getState(); 78 if (AlwaysReturnsLValue) 79 State = State->BindExpr(CallExpr, LCtx, ThisVal); 80 else 81 State = bindReturnValue(Call, LCtx, State); 82 Bldr.generateNode(PS, State, *I); 83 } 84 } 85 86 87 /// Returns a region representing the first element of a (possibly 88 /// multi-dimensional) array. 89 /// 90 /// On return, \p Ty will be set to the base type of the array. 91 /// 92 /// If the type is not an array type at all, the original value is returned. 93 static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue, 94 QualType &Ty) { 95 SValBuilder &SVB = State->getStateManager().getSValBuilder(); 96 ASTContext &Ctx = SVB.getContext(); 97 98 while (const ArrayType *AT = Ctx.getAsArrayType(Ty)) { 99 Ty = AT->getElementType(); 100 LValue = State->getLValue(Ty, SVB.makeZeroArrayIndex(), LValue); 101 } 102 103 return LValue; 104 } 105 106 107 const MemRegion * 108 ExprEngine::getRegionForConstructedObject(const CXXConstructExpr *CE, 109 ExplodedNode *Pred) { 110 const LocationContext *LCtx = Pred->getLocationContext(); 111 ProgramStateRef State = Pred->getState(); 112 113 // See if we're constructing an existing region by looking at the next 114 // element in the CFG. 115 116 if (auto Elem = findElementDirectlyInitializedByCurrentConstructor()) { 117 if (Optional<CFGStmt> StmtElem = Elem->getAs<CFGStmt>()) { 118 if (const CXXNewExpr *CNE = dyn_cast<CXXNewExpr>(StmtElem->getStmt())) { 119 if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) { 120 // TODO: Detect when the allocator returns a null pointer. 121 // Constructor shall not be called in this case. 122 if (const SubRegion *MR = dyn_cast_or_null<SubRegion>( 123 getCXXNewAllocatorValue(State, CNE, LCtx).getAsRegion())) { 124 if (CNE->isArray()) { 125 // TODO: This code exists only to trigger the suppression for 126 // array constructors. In fact, we need to call the constructor 127 // for every allocated element, not just the first one! 128 return getStoreManager().GetElementZeroRegion( 129 MR, CNE->getType()->getPointeeType()); 130 } 131 return MR; 132 } 133 } 134 } else if (auto *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) { 135 if (const auto *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) { 136 if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) { 137 SVal LValue = State->getLValue(Var, LCtx); 138 QualType Ty = Var->getType(); 139 LValue = makeZeroElementRegion(State, LValue, Ty); 140 return LValue.getAsRegion(); 141 } 142 } 143 } else { 144 llvm_unreachable("Unexpected directly initialized element!"); 145 } 146 } else if (Optional<CFGInitializer> InitElem = Elem->getAs<CFGInitializer>()) { 147 const CXXCtorInitializer *Init = InitElem->getInitializer(); 148 assert(Init->isAnyMemberInitializer()); 149 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 150 Loc ThisPtr = 151 getSValBuilder().getCXXThis(CurCtor, LCtx->getCurrentStackFrame()); 152 SVal ThisVal = State->getSVal(ThisPtr); 153 154 const ValueDecl *Field; 155 SVal FieldVal; 156 if (Init->isIndirectMemberInitializer()) { 157 Field = Init->getIndirectMember(); 158 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal); 159 } else { 160 Field = Init->getMember(); 161 FieldVal = State->getLValue(Init->getMember(), ThisVal); 162 } 163 164 QualType Ty = Field->getType(); 165 FieldVal = makeZeroElementRegion(State, FieldVal, Ty); 166 return FieldVal.getAsRegion(); 167 } 168 169 // FIXME: This will eventually need to handle new-expressions as well. 170 // Don't forget to update the pre-constructor initialization code in 171 // ExprEngine::VisitCXXConstructExpr. 172 } 173 // If we couldn't find an existing region to construct into, assume we're 174 // constructing a temporary. 175 MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 176 return MRMgr.getCXXTempObjectRegion(CE, LCtx); 177 } 178 179 /// Returns true if the initializer for \Elem can be a direct 180 /// constructor. 181 static bool canHaveDirectConstructor(CFGElement Elem){ 182 // DeclStmts and CXXCtorInitializers for fields can be directly constructed. 183 184 if (Optional<CFGStmt> StmtElem = Elem.getAs<CFGStmt>()) { 185 if (isa<DeclStmt>(StmtElem->getStmt())) { 186 return true; 187 } 188 if (isa<CXXNewExpr>(StmtElem->getStmt())) { 189 return true; 190 } 191 } 192 193 if (Elem.getKind() == CFGElement::Initializer) { 194 return true; 195 } 196 197 return false; 198 } 199 200 Optional<CFGElement> 201 ExprEngine::findElementDirectlyInitializedByCurrentConstructor() { 202 const NodeBuilderContext &CurrBldrCtx = getBuilderContext(); 203 // See if we're constructing an existing region by looking at the next 204 // element in the CFG. 205 const CFGBlock *B = CurrBldrCtx.getBlock(); 206 assert(isa<CXXConstructExpr>(((*B)[currStmtIdx]).castAs<CFGStmt>().getStmt())); 207 unsigned int NextStmtIdx = currStmtIdx + 1; 208 if (NextStmtIdx >= B->size()) 209 return None; 210 211 CFGElement Next = (*B)[NextStmtIdx]; 212 213 // Is this a destructor? If so, we might be in the middle of an assignment 214 // to a local or member: look ahead one more element to see what we find. 215 while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) { 216 ++NextStmtIdx; 217 Next = (*B)[NextStmtIdx]; 218 } 219 220 if (canHaveDirectConstructor(Next)) 221 return Next; 222 223 return None; 224 } 225 226 const CXXConstructExpr * 227 ExprEngine::findDirectConstructorForCurrentCFGElement() { 228 // Go backward in the CFG to see if the previous element (ignoring 229 // destructors) was a CXXConstructExpr. If so, that constructor 230 // was constructed directly into an existing region. 231 // This process is essentially the inverse of that performed in 232 // findElementDirectlyInitializedByCurrentConstructor(). 233 if (currStmtIdx == 0) 234 return nullptr; 235 236 const CFGBlock *B = getBuilderContext().getBlock(); 237 assert(canHaveDirectConstructor((*B)[currStmtIdx])); 238 239 unsigned int PreviousStmtIdx = currStmtIdx - 1; 240 CFGElement Previous = (*B)[PreviousStmtIdx]; 241 242 while (Previous.getAs<CFGImplicitDtor>() && PreviousStmtIdx > 0) { 243 --PreviousStmtIdx; 244 Previous = (*B)[PreviousStmtIdx]; 245 } 246 247 if (Optional<CFGStmt> PrevStmtElem = Previous.getAs<CFGStmt>()) { 248 if (auto *CtorExpr = dyn_cast<CXXConstructExpr>(PrevStmtElem->getStmt())) { 249 return CtorExpr; 250 } 251 } 252 253 return nullptr; 254 } 255 256 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 257 ExplodedNode *Pred, 258 ExplodedNodeSet &destNodes) { 259 const LocationContext *LCtx = Pred->getLocationContext(); 260 ProgramStateRef State = Pred->getState(); 261 262 const MemRegion *Target = nullptr; 263 264 // FIXME: Handle arrays, which run the same constructor for every element. 265 // For now, we just run the first constructor (which should still invalidate 266 // the entire array). 267 268 switch (CE->getConstructionKind()) { 269 case CXXConstructExpr::CK_Complete: { 270 Target = getRegionForConstructedObject(CE, Pred); 271 break; 272 } 273 case CXXConstructExpr::CK_VirtualBase: 274 // Make sure we are not calling virtual base class initializers twice. 275 // Only the most-derived object should initialize virtual base classes. 276 if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) { 277 const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer); 278 if (OuterCtor) { 279 switch (OuterCtor->getConstructionKind()) { 280 case CXXConstructExpr::CK_NonVirtualBase: 281 case CXXConstructExpr::CK_VirtualBase: 282 // Bail out! 283 destNodes.Add(Pred); 284 return; 285 case CXXConstructExpr::CK_Complete: 286 case CXXConstructExpr::CK_Delegating: 287 break; 288 } 289 } 290 } 291 // FALLTHROUGH 292 case CXXConstructExpr::CK_NonVirtualBase: 293 // In C++17, classes with non-virtual bases may be aggregates, so they would 294 // be initialized as aggregates without a constructor call, so we may have 295 // a base class constructed directly into an initializer list without 296 // having the derived-class constructor call on the previous stack frame. 297 // Initializer lists may be nested into more initializer lists that 298 // correspond to surrounding aggregate initializations. 299 // FIXME: For now this code essentially bails out. We need to find the 300 // correct target region and set it. 301 // FIXME: Instead of relying on the ParentMap, we should have the 302 // trigger-statement (InitListExpr in this case) passed down from CFG or 303 // otherwise always available during construction. 304 if (dyn_cast_or_null<InitListExpr>(LCtx->getParentMap().getParent(CE))) { 305 MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 306 Target = MRMgr.getCXXTempObjectRegion(CE, LCtx); 307 break; 308 } 309 // FALLTHROUGH 310 case CXXConstructExpr::CK_Delegating: { 311 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 312 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 313 LCtx->getCurrentStackFrame()); 314 SVal ThisVal = State->getSVal(ThisPtr); 315 316 if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) { 317 Target = ThisVal.getAsRegion(); 318 } else { 319 // Cast to the base type. 320 bool IsVirtual = 321 (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase); 322 SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(), 323 IsVirtual); 324 Target = BaseVal.getAsRegion(); 325 } 326 break; 327 } 328 } 329 330 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 331 CallEventRef<CXXConstructorCall> Call = 332 CEMgr.getCXXConstructorCall(CE, Target, State, LCtx); 333 334 ExplodedNodeSet DstPreVisit; 335 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this); 336 337 ExplodedNodeSet PreInitialized; 338 { 339 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx); 340 if (CE->requiresZeroInitialization()) { 341 // Type of the zero doesn't matter. 342 SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy); 343 344 for (ExplodedNodeSet::iterator I = DstPreVisit.begin(), 345 E = DstPreVisit.end(); 346 I != E; ++I) { 347 ProgramStateRef State = (*I)->getState(); 348 // FIXME: Once we properly handle constructors in new-expressions, we'll 349 // need to invalidate the region before setting a default value, to make 350 // sure there aren't any lingering bindings around. This probably needs 351 // to happen regardless of whether or not the object is zero-initialized 352 // to handle random fields of a placement-initialized object picking up 353 // old bindings. We might only want to do it when we need to, though. 354 // FIXME: This isn't actually correct for arrays -- we need to zero- 355 // initialize the entire array, not just the first element -- but our 356 // handling of arrays everywhere else is weak as well, so this shouldn't 357 // actually make things worse. Placement new makes this tricky as well, 358 // since it's then possible to be initializing one part of a multi- 359 // dimensional array. 360 State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal, LCtx); 361 Bldr.generateNode(CE, *I, State, /*tag=*/nullptr, 362 ProgramPoint::PreStmtKind); 363 } 364 } 365 } 366 367 ExplodedNodeSet DstPreCall; 368 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized, 369 *Call, *this); 370 371 ExplodedNodeSet DstEvaluated; 372 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx); 373 374 bool IsArray = isa<ElementRegion>(Target); 375 if (CE->getConstructor()->isTrivial() && 376 CE->getConstructor()->isCopyOrMoveConstructor() && 377 !IsArray) { 378 // FIXME: Handle other kinds of trivial constructors as well. 379 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 380 I != E; ++I) 381 performTrivialCopy(Bldr, *I, *Call); 382 383 } else { 384 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 385 I != E; ++I) 386 defaultEvalCall(Bldr, *I, *Call); 387 } 388 389 // If the CFG was contructed without elements for temporary destructors 390 // and the just-called constructor created a temporary object then 391 // stop exploration if the temporary object has a noreturn constructor. 392 // This can lose coverage because the destructor, if it were present 393 // in the CFG, would be called at the end of the full expression or 394 // later (for life-time extended temporaries) -- but avoids infeasible 395 // paths when no-return temporary destructors are used for assertions. 396 const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext(); 397 if (!ADC->getCFGBuildOptions().AddTemporaryDtors) { 398 const MemRegion *Target = Call->getCXXThisVal().getAsRegion(); 399 if (Target && isa<CXXTempObjectRegion>(Target) && 400 Call->getDecl()->getParent()->isAnyDestructorNoReturn()) { 401 402 for (ExplodedNode *N : DstEvaluated) { 403 Bldr.generateSink(CE, N, N->getState()); 404 } 405 406 // There is no need to run the PostCall and PostStmtchecker 407 // callbacks because we just generated sinks on all nodes in th 408 // frontier. 409 return; 410 } 411 } 412 413 ExplodedNodeSet DstPostCall; 414 getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated, 415 *Call, *this); 416 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this); 417 } 418 419 void ExprEngine::VisitCXXDestructor(QualType ObjectType, 420 const MemRegion *Dest, 421 const Stmt *S, 422 bool IsBaseDtor, 423 ExplodedNode *Pred, 424 ExplodedNodeSet &Dst) { 425 const LocationContext *LCtx = Pred->getLocationContext(); 426 ProgramStateRef State = Pred->getState(); 427 428 // FIXME: We need to run the same destructor on every element of the array. 429 // This workaround will just run the first destructor (which will still 430 // invalidate the entire array). 431 SVal DestVal = UnknownVal(); 432 if (Dest) 433 DestVal = loc::MemRegionVal(Dest); 434 DestVal = makeZeroElementRegion(State, DestVal, ObjectType); 435 Dest = DestVal.getAsRegion(); 436 437 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); 438 assert(RecordDecl && "Only CXXRecordDecls should have destructors"); 439 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); 440 441 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 442 CallEventRef<CXXDestructorCall> Call = 443 CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); 444 445 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 446 Call->getSourceRange().getBegin(), 447 "Error evaluating destructor"); 448 449 ExplodedNodeSet DstPreCall; 450 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 451 *Call, *this); 452 453 ExplodedNodeSet DstInvalidated; 454 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 455 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 456 I != E; ++I) 457 defaultEvalCall(Bldr, *I, *Call); 458 459 ExplodedNodeSet DstPostCall; 460 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 461 *Call, *this); 462 } 463 464 void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, 465 ExplodedNode *Pred, 466 ExplodedNodeSet &Dst) { 467 ProgramStateRef State = Pred->getState(); 468 const LocationContext *LCtx = Pred->getLocationContext(); 469 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 470 CNE->getStartLoc(), 471 "Error evaluating New Allocator Call"); 472 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 473 CallEventRef<CXXAllocatorCall> Call = 474 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 475 476 ExplodedNodeSet DstPreCall; 477 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 478 *Call, *this); 479 480 ExplodedNodeSet DstPostCall; 481 StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx); 482 for (auto I : DstPreCall) { 483 // FIXME: Provide evalCall for checkers? 484 defaultEvalCall(CallBldr, I, *Call); 485 } 486 // If the call is inlined, DstPostCall will be empty and we bail out now. 487 488 // Store return value of operator new() for future use, until the actual 489 // CXXNewExpr gets processed. 490 ExplodedNodeSet DstPostValue; 491 StmtNodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx); 492 for (auto I : DstPostCall) { 493 // FIXME: Because CNE serves as the "call site" for the allocator (due to 494 // lack of a better expression in the AST), the conjured return value symbol 495 // is going to be of the same type (C++ object pointer type). Technically 496 // this is not correct because the operator new's prototype always says that 497 // it returns a 'void *'. So we should change the type of the symbol, 498 // and then evaluate the cast over the symbolic pointer from 'void *' to 499 // the object pointer type. But without changing the symbol's type it 500 // is breaking too much to evaluate the no-op symbolic cast over it, so we 501 // skip it for now. 502 ProgramStateRef State = I->getState(); 503 SVal RetVal = State->getSVal(CNE, LCtx); 504 505 // If this allocation function is not declared as non-throwing, failures 506 // /must/ be signalled by exceptions, and thus the return value will never 507 // be NULL. -fno-exceptions does not influence this semantics. 508 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case 509 // where new can return NULL. If we end up supporting that option, we can 510 // consider adding a check for it here. 511 // C++11 [basic.stc.dynamic.allocation]p3. 512 if (const FunctionDecl *FD = CNE->getOperatorNew()) { 513 QualType Ty = FD->getType(); 514 if (const auto *ProtoType = Ty->getAs<FunctionProtoType>()) 515 if (!ProtoType->isNothrow(getContext())) 516 State = State->assume(RetVal.castAs<DefinedOrUnknownSVal>(), true); 517 } 518 519 ValueBldr.generateNode(CNE, I, 520 setCXXNewAllocatorValue(State, CNE, LCtx, RetVal)); 521 } 522 523 ExplodedNodeSet DstPostPostCallCallback; 524 getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback, 525 DstPostValue, *Call, *this); 526 for (auto I : DstPostPostCallCallback) { 527 getCheckerManager().runCheckersForNewAllocator( 528 CNE, getCXXNewAllocatorValue(I->getState(), CNE, LCtx), Dst, I, *this); 529 } 530 } 531 532 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 533 ExplodedNodeSet &Dst) { 534 // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 535 // Also, we need to decide how allocators actually work -- they're not 536 // really part of the CXXNewExpr because they happen BEFORE the 537 // CXXConstructExpr subexpression. See PR12014 for some discussion. 538 539 unsigned blockCount = currBldrCtx->blockCount(); 540 const LocationContext *LCtx = Pred->getLocationContext(); 541 SVal symVal = UnknownVal(); 542 FunctionDecl *FD = CNE->getOperatorNew(); 543 544 bool IsStandardGlobalOpNewFunction = 545 FD->isReplaceableGlobalAllocationFunction(); 546 547 ProgramStateRef State = Pred->getState(); 548 549 // Retrieve the stored operator new() return value. 550 if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) { 551 symVal = getCXXNewAllocatorValue(State, CNE, LCtx); 552 State = clearCXXNewAllocatorValue(State, CNE, LCtx); 553 } 554 555 // We assume all standard global 'operator new' functions allocate memory in 556 // heap. We realize this is an approximation that might not correctly model 557 // a custom global allocator. 558 if (symVal.isUnknown()) { 559 if (IsStandardGlobalOpNewFunction) 560 symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount); 561 else 562 symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(), 563 blockCount); 564 } 565 566 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 567 CallEventRef<CXXAllocatorCall> Call = 568 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 569 570 if (!AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) { 571 // Invalidate placement args. 572 // FIXME: Once we figure out how we want allocators to work, 573 // we should be using the usual pre-/(default-)eval-/post-call checks here. 574 State = Call->invalidateRegions(blockCount); 575 if (!State) 576 return; 577 578 // If this allocation function is not declared as non-throwing, failures 579 // /must/ be signalled by exceptions, and thus the return value will never 580 // be NULL. -fno-exceptions does not influence this semantics. 581 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case 582 // where new can return NULL. If we end up supporting that option, we can 583 // consider adding a check for it here. 584 // C++11 [basic.stc.dynamic.allocation]p3. 585 if (FD) { 586 QualType Ty = FD->getType(); 587 if (const auto *ProtoType = Ty->getAs<FunctionProtoType>()) 588 if (!ProtoType->isNothrow(getContext())) 589 if (auto dSymVal = symVal.getAs<DefinedOrUnknownSVal>()) 590 State = State->assume(*dSymVal, true); 591 } 592 } 593 594 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 595 596 SVal Result = symVal; 597 598 if (CNE->isArray()) { 599 // FIXME: allocating an array requires simulating the constructors. 600 // For now, just return a symbolicated region. 601 if (const SubRegion *NewReg = 602 dyn_cast_or_null<SubRegion>(symVal.getAsRegion())) { 603 QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 604 const ElementRegion *EleReg = 605 getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 606 Result = loc::MemRegionVal(EleReg); 607 } 608 State = State->BindExpr(CNE, Pred->getLocationContext(), Result); 609 Bldr.generateNode(CNE, Pred, State); 610 return; 611 } 612 613 // FIXME: Once we have proper support for CXXConstructExprs inside 614 // CXXNewExpr, we need to make sure that the constructed object is not 615 // immediately invalidated here. (The placement call should happen before 616 // the constructor call anyway.) 617 if (FD && FD->isReservedGlobalPlacementOperator()) { 618 // Non-array placement new should always return the placement location. 619 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 620 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), 621 CNE->getPlacementArg(0)->getType()); 622 } 623 624 // Bind the address of the object, then check to see if we cached out. 625 State = State->BindExpr(CNE, LCtx, Result); 626 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State); 627 if (!NewN) 628 return; 629 630 // If the type is not a record, we won't have a CXXConstructExpr as an 631 // initializer. Copy the value over. 632 if (const Expr *Init = CNE->getInitializer()) { 633 if (!isa<CXXConstructExpr>(Init)) { 634 assert(Bldr.getResults().size() == 1); 635 Bldr.takeNodes(NewN); 636 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx), 637 /*FirstInit=*/IsStandardGlobalOpNewFunction); 638 } 639 } 640 } 641 642 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 643 ExplodedNode *Pred, ExplodedNodeSet &Dst) { 644 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 645 ProgramStateRef state = Pred->getState(); 646 Bldr.generateNode(CDE, Pred, state); 647 } 648 649 void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 650 ExplodedNode *Pred, 651 ExplodedNodeSet &Dst) { 652 const VarDecl *VD = CS->getExceptionDecl(); 653 if (!VD) { 654 Dst.Add(Pred); 655 return; 656 } 657 658 const LocationContext *LCtx = Pred->getLocationContext(); 659 SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(), 660 currBldrCtx->blockCount()); 661 ProgramStateRef state = Pred->getState(); 662 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx); 663 664 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 665 Bldr.generateNode(CS, Pred, state); 666 } 667 668 void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 669 ExplodedNodeSet &Dst) { 670 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 671 672 // Get the this object region from StoreManager. 673 const LocationContext *LCtx = Pred->getLocationContext(); 674 const MemRegion *R = 675 svalBuilder.getRegionManager().getCXXThisRegion( 676 getContext().getCanonicalType(TE->getType()), 677 LCtx); 678 679 ProgramStateRef state = Pred->getState(); 680 SVal V = state->getSVal(loc::MemRegionVal(R)); 681 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 682 } 683 684 void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, 685 ExplodedNodeSet &Dst) { 686 const LocationContext *LocCtxt = Pred->getLocationContext(); 687 688 // Get the region of the lambda itself. 689 const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion( 690 LE, LocCtxt); 691 SVal V = loc::MemRegionVal(R); 692 693 ProgramStateRef State = Pred->getState(); 694 695 // If we created a new MemRegion for the lambda, we should explicitly bind 696 // the captures. 697 CXXRecordDecl::field_iterator CurField = LE->getLambdaClass()->field_begin(); 698 for (LambdaExpr::const_capture_init_iterator i = LE->capture_init_begin(), 699 e = LE->capture_init_end(); 700 i != e; ++i, ++CurField) { 701 FieldDecl *FieldForCapture = *CurField; 702 SVal FieldLoc = State->getLValue(FieldForCapture, V); 703 704 SVal InitVal; 705 if (!FieldForCapture->hasCapturedVLAType()) { 706 Expr *InitExpr = *i; 707 assert(InitExpr && "Capture missing initialization expression"); 708 InitVal = State->getSVal(InitExpr, LocCtxt); 709 } else { 710 // The field stores the length of a captured variable-length array. 711 // These captures don't have initialization expressions; instead we 712 // get the length from the VLAType size expression. 713 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr(); 714 InitVal = State->getSVal(SizeExpr, LocCtxt); 715 } 716 717 State = State->bindLoc(FieldLoc, InitVal, LocCtxt); 718 } 719 720 // Decay the Loc into an RValue, because there might be a 721 // MaterializeTemporaryExpr node above this one which expects the bound value 722 // to be an RValue. 723 SVal LambdaRVal = State->getSVal(R); 724 725 ExplodedNodeSet Tmp; 726 StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); 727 // FIXME: is this the right program point kind? 728 Bldr.generateNode(LE, Pred, 729 State->BindExpr(LE, LocCtxt, LambdaRVal), 730 nullptr, ProgramPoint::PostLValueKind); 731 732 // FIXME: Move all post/pre visits to ::Visit(). 733 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this); 734 } 735