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 auto *DS = cast<DeclStmt>(StmtElem->getStmt()); 119 if (const auto *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) { 120 if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) { 121 SVal LValue = State->getLValue(Var, LCtx); 122 QualType Ty = Var->getType(); 123 LValue = makeZeroElementRegion(State, LValue, Ty); 124 return LValue.getAsRegion(); 125 } 126 } 127 } else if (Optional<CFGInitializer> InitElem = Elem->getAs<CFGInitializer>()) { 128 const CXXCtorInitializer *Init = InitElem->getInitializer(); 129 assert(Init->isAnyMemberInitializer()); 130 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 131 Loc ThisPtr = 132 getSValBuilder().getCXXThis(CurCtor, LCtx->getCurrentStackFrame()); 133 SVal ThisVal = State->getSVal(ThisPtr); 134 135 const ValueDecl *Field; 136 SVal FieldVal; 137 if (Init->isIndirectMemberInitializer()) { 138 Field = Init->getIndirectMember(); 139 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal); 140 } else { 141 Field = Init->getMember(); 142 FieldVal = State->getLValue(Init->getMember(), ThisVal); 143 } 144 145 QualType Ty = Field->getType(); 146 FieldVal = makeZeroElementRegion(State, FieldVal, Ty); 147 return FieldVal.getAsRegion(); 148 } 149 150 // FIXME: This will eventually need to handle new-expressions as well. 151 // Don't forget to update the pre-constructor initialization code in 152 // ExprEngine::VisitCXXConstructExpr. 153 } 154 // If we couldn't find an existing region to construct into, assume we're 155 // constructing a temporary. 156 MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 157 return MRMgr.getCXXTempObjectRegion(CE, LCtx); 158 } 159 160 /// Returns true if the initializer for \Elem can be a direct 161 /// constructor. 162 static bool canHaveDirectConstructor(CFGElement Elem){ 163 // DeclStmts and CXXCtorInitializers for fields can be directly constructed. 164 165 if (Optional<CFGStmt> StmtElem = Elem.getAs<CFGStmt>()) { 166 if (isa<DeclStmt>(StmtElem->getStmt())) { 167 return true; 168 } 169 } 170 171 if (Elem.getKind() == CFGElement::Initializer) { 172 return true; 173 } 174 175 return false; 176 } 177 178 Optional<CFGElement> 179 ExprEngine::findElementDirectlyInitializedByCurrentConstructor() { 180 const NodeBuilderContext &CurrBldrCtx = getBuilderContext(); 181 // See if we're constructing an existing region by looking at the next 182 // element in the CFG. 183 const CFGBlock *B = CurrBldrCtx.getBlock(); 184 assert(isa<CXXConstructExpr>(((*B)[currStmtIdx]).castAs<CFGStmt>().getStmt())); 185 unsigned int NextStmtIdx = currStmtIdx + 1; 186 if (NextStmtIdx >= B->size()) 187 return None; 188 189 CFGElement Next = (*B)[NextStmtIdx]; 190 191 // Is this a destructor? If so, we might be in the middle of an assignment 192 // to a local or member: look ahead one more element to see what we find. 193 while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) { 194 ++NextStmtIdx; 195 Next = (*B)[NextStmtIdx]; 196 } 197 198 if (canHaveDirectConstructor(Next)) 199 return Next; 200 201 return None; 202 } 203 204 const CXXConstructExpr * 205 ExprEngine::findDirectConstructorForCurrentCFGElement() { 206 // Go backward in the CFG to see if the previous element (ignoring 207 // destructors) was a CXXConstructExpr. If so, that constructor 208 // was constructed directly into an existing region. 209 // This process is essentially the inverse of that performed in 210 // findElementDirectlyInitializedByCurrentConstructor(). 211 if (currStmtIdx == 0) 212 return nullptr; 213 214 const CFGBlock *B = getBuilderContext().getBlock(); 215 assert(canHaveDirectConstructor((*B)[currStmtIdx])); 216 217 unsigned int PreviousStmtIdx = currStmtIdx - 1; 218 CFGElement Previous = (*B)[PreviousStmtIdx]; 219 220 while (Previous.getAs<CFGImplicitDtor>() && PreviousStmtIdx > 0) { 221 --PreviousStmtIdx; 222 Previous = (*B)[PreviousStmtIdx]; 223 } 224 225 if (Optional<CFGStmt> PrevStmtElem = Previous.getAs<CFGStmt>()) { 226 if (auto *CtorExpr = dyn_cast<CXXConstructExpr>(PrevStmtElem->getStmt())) { 227 return CtorExpr; 228 } 229 } 230 231 return nullptr; 232 } 233 234 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 235 ExplodedNode *Pred, 236 ExplodedNodeSet &destNodes) { 237 const LocationContext *LCtx = Pred->getLocationContext(); 238 ProgramStateRef State = Pred->getState(); 239 240 const MemRegion *Target = nullptr; 241 242 // FIXME: Handle arrays, which run the same constructor for every element. 243 // For now, we just run the first constructor (which should still invalidate 244 // the entire array). 245 246 switch (CE->getConstructionKind()) { 247 case CXXConstructExpr::CK_Complete: { 248 Target = getRegionForConstructedObject(CE, Pred); 249 break; 250 } 251 case CXXConstructExpr::CK_VirtualBase: 252 // Make sure we are not calling virtual base class initializers twice. 253 // Only the most-derived object should initialize virtual base classes. 254 if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) { 255 const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer); 256 if (OuterCtor) { 257 switch (OuterCtor->getConstructionKind()) { 258 case CXXConstructExpr::CK_NonVirtualBase: 259 case CXXConstructExpr::CK_VirtualBase: 260 // Bail out! 261 destNodes.Add(Pred); 262 return; 263 case CXXConstructExpr::CK_Complete: 264 case CXXConstructExpr::CK_Delegating: 265 break; 266 } 267 } 268 } 269 // FALLTHROUGH 270 case CXXConstructExpr::CK_NonVirtualBase: 271 // In C++17, classes with non-virtual bases may be aggregates, so they would 272 // be initialized as aggregates without a constructor call, so we may have 273 // a base class constructed directly into an initializer list without 274 // having the derived-class constructor call on the previous stack frame. 275 // Initializer lists may be nested into more initializer lists that 276 // correspond to surrounding aggregate initializations. 277 // FIXME: For now this code essentially bails out. We need to find the 278 // correct target region and set it. 279 // FIXME: Instead of relying on the ParentMap, we should have the 280 // trigger-statement (InitListExpr in this case) passed down from CFG or 281 // otherwise always available during construction. 282 if (dyn_cast_or_null<InitListExpr>(LCtx->getParentMap().getParent(CE))) { 283 MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 284 Target = MRMgr.getCXXTempObjectRegion(CE, LCtx); 285 break; 286 } 287 // FALLTHROUGH 288 case CXXConstructExpr::CK_Delegating: { 289 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 290 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 291 LCtx->getCurrentStackFrame()); 292 SVal ThisVal = State->getSVal(ThisPtr); 293 294 if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) { 295 Target = ThisVal.getAsRegion(); 296 } else { 297 // Cast to the base type. 298 bool IsVirtual = 299 (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase); 300 SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(), 301 IsVirtual); 302 Target = BaseVal.getAsRegion(); 303 } 304 break; 305 } 306 } 307 308 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 309 CallEventRef<CXXConstructorCall> Call = 310 CEMgr.getCXXConstructorCall(CE, Target, State, LCtx); 311 312 ExplodedNodeSet DstPreVisit; 313 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this); 314 315 ExplodedNodeSet PreInitialized; 316 { 317 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx); 318 if (CE->requiresZeroInitialization()) { 319 // Type of the zero doesn't matter. 320 SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy); 321 322 for (ExplodedNodeSet::iterator I = DstPreVisit.begin(), 323 E = DstPreVisit.end(); 324 I != E; ++I) { 325 ProgramStateRef State = (*I)->getState(); 326 // FIXME: Once we properly handle constructors in new-expressions, we'll 327 // need to invalidate the region before setting a default value, to make 328 // sure there aren't any lingering bindings around. This probably needs 329 // to happen regardless of whether or not the object is zero-initialized 330 // to handle random fields of a placement-initialized object picking up 331 // old bindings. We might only want to do it when we need to, though. 332 // FIXME: This isn't actually correct for arrays -- we need to zero- 333 // initialize the entire array, not just the first element -- but our 334 // handling of arrays everywhere else is weak as well, so this shouldn't 335 // actually make things worse. Placement new makes this tricky as well, 336 // since it's then possible to be initializing one part of a multi- 337 // dimensional array. 338 State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal, LCtx); 339 Bldr.generateNode(CE, *I, State, /*tag=*/nullptr, 340 ProgramPoint::PreStmtKind); 341 } 342 } 343 } 344 345 ExplodedNodeSet DstPreCall; 346 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized, 347 *Call, *this); 348 349 ExplodedNodeSet DstEvaluated; 350 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx); 351 352 bool IsArray = isa<ElementRegion>(Target); 353 if (CE->getConstructor()->isTrivial() && 354 CE->getConstructor()->isCopyOrMoveConstructor() && 355 !IsArray) { 356 // FIXME: Handle other kinds of trivial constructors as well. 357 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 358 I != E; ++I) 359 performTrivialCopy(Bldr, *I, *Call); 360 361 } else { 362 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 363 I != E; ++I) 364 defaultEvalCall(Bldr, *I, *Call); 365 } 366 367 // If the CFG was contructed without elements for temporary destructors 368 // and the just-called constructor created a temporary object then 369 // stop exploration if the temporary object has a noreturn constructor. 370 // This can lose coverage because the destructor, if it were present 371 // in the CFG, would be called at the end of the full expression or 372 // later (for life-time extended temporaries) -- but avoids infeasible 373 // paths when no-return temporary destructors are used for assertions. 374 const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext(); 375 if (!ADC->getCFGBuildOptions().AddTemporaryDtors) { 376 const MemRegion *Target = Call->getCXXThisVal().getAsRegion(); 377 if (Target && isa<CXXTempObjectRegion>(Target) && 378 Call->getDecl()->getParent()->isAnyDestructorNoReturn()) { 379 380 for (ExplodedNode *N : DstEvaluated) { 381 Bldr.generateSink(CE, N, N->getState()); 382 } 383 384 // There is no need to run the PostCall and PostStmtchecker 385 // callbacks because we just generated sinks on all nodes in th 386 // frontier. 387 return; 388 } 389 } 390 391 ExplodedNodeSet DstPostCall; 392 getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated, 393 *Call, *this); 394 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this); 395 } 396 397 void ExprEngine::VisitCXXDestructor(QualType ObjectType, 398 const MemRegion *Dest, 399 const Stmt *S, 400 bool IsBaseDtor, 401 ExplodedNode *Pred, 402 ExplodedNodeSet &Dst) { 403 const LocationContext *LCtx = Pred->getLocationContext(); 404 ProgramStateRef State = Pred->getState(); 405 406 // FIXME: We need to run the same destructor on every element of the array. 407 // This workaround will just run the first destructor (which will still 408 // invalidate the entire array). 409 SVal DestVal = UnknownVal(); 410 if (Dest) 411 DestVal = loc::MemRegionVal(Dest); 412 DestVal = makeZeroElementRegion(State, DestVal, ObjectType); 413 Dest = DestVal.getAsRegion(); 414 415 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); 416 assert(RecordDecl && "Only CXXRecordDecls should have destructors"); 417 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); 418 419 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 420 CallEventRef<CXXDestructorCall> Call = 421 CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); 422 423 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 424 Call->getSourceRange().getBegin(), 425 "Error evaluating destructor"); 426 427 ExplodedNodeSet DstPreCall; 428 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 429 *Call, *this); 430 431 ExplodedNodeSet DstInvalidated; 432 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 433 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 434 I != E; ++I) 435 defaultEvalCall(Bldr, *I, *Call); 436 437 ExplodedNodeSet DstPostCall; 438 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 439 *Call, *this); 440 } 441 442 void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, 443 ExplodedNode *Pred, 444 ExplodedNodeSet &Dst) { 445 ProgramStateRef State = Pred->getState(); 446 const LocationContext *LCtx = Pred->getLocationContext(); 447 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 448 CNE->getStartLoc(), 449 "Error evaluating New Allocator Call"); 450 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 451 CallEventRef<CXXAllocatorCall> Call = 452 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 453 454 ExplodedNodeSet DstPreCall; 455 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 456 *Call, *this); 457 458 ExplodedNodeSet DstInvalidated; 459 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 460 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 461 I != E; ++I) 462 defaultEvalCall(Bldr, *I, *Call); 463 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 464 *Call, *this); 465 } 466 467 468 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 469 ExplodedNodeSet &Dst) { 470 // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 471 // Also, we need to decide how allocators actually work -- they're not 472 // really part of the CXXNewExpr because they happen BEFORE the 473 // CXXConstructExpr subexpression. See PR12014 for some discussion. 474 475 unsigned blockCount = currBldrCtx->blockCount(); 476 const LocationContext *LCtx = Pred->getLocationContext(); 477 DefinedOrUnknownSVal symVal = UnknownVal(); 478 FunctionDecl *FD = CNE->getOperatorNew(); 479 480 bool IsStandardGlobalOpNewFunction = false; 481 if (FD && !isa<CXXMethodDecl>(FD) && !FD->isVariadic()) { 482 if (FD->getNumParams() == 2) { 483 QualType T = FD->getParamDecl(1)->getType(); 484 if (const IdentifierInfo *II = T.getBaseTypeIdentifier()) 485 // NoThrow placement new behaves as a standard new. 486 IsStandardGlobalOpNewFunction = II->getName().equals("nothrow_t"); 487 } 488 else 489 // Placement forms are considered non-standard. 490 IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1); 491 } 492 493 // We assume all standard global 'operator new' functions allocate memory in 494 // heap. We realize this is an approximation that might not correctly model 495 // a custom global allocator. 496 if (IsStandardGlobalOpNewFunction) 497 symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount); 498 else 499 symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(), 500 blockCount); 501 502 ProgramStateRef State = Pred->getState(); 503 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 504 CallEventRef<CXXAllocatorCall> Call = 505 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 506 507 // Invalidate placement args. 508 // FIXME: Once we figure out how we want allocators to work, 509 // we should be using the usual pre-/(default-)eval-/post-call checks here. 510 State = Call->invalidateRegions(blockCount); 511 if (!State) 512 return; 513 514 // If this allocation function is not declared as non-throwing, failures 515 // /must/ be signalled by exceptions, and thus the return value will never be 516 // NULL. -fno-exceptions does not influence this semantics. 517 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case 518 // where new can return NULL. If we end up supporting that option, we can 519 // consider adding a check for it here. 520 // C++11 [basic.stc.dynamic.allocation]p3. 521 if (FD) { 522 QualType Ty = FD->getType(); 523 if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>()) 524 if (!ProtoType->isNothrow(getContext())) 525 State = State->assume(symVal, true); 526 } 527 528 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 529 530 if (CNE->isArray()) { 531 // FIXME: allocating an array requires simulating the constructors. 532 // For now, just return a symbolicated region. 533 const SubRegion *NewReg = 534 symVal.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>(); 535 QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 536 const ElementRegion *EleReg = 537 getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 538 State = State->BindExpr(CNE, Pred->getLocationContext(), 539 loc::MemRegionVal(EleReg)); 540 Bldr.generateNode(CNE, Pred, State); 541 return; 542 } 543 544 // FIXME: Once we have proper support for CXXConstructExprs inside 545 // CXXNewExpr, we need to make sure that the constructed object is not 546 // immediately invalidated here. (The placement call should happen before 547 // the constructor call anyway.) 548 SVal Result = symVal; 549 if (FD && FD->isReservedGlobalPlacementOperator()) { 550 // Non-array placement new should always return the placement location. 551 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 552 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), 553 CNE->getPlacementArg(0)->getType()); 554 } 555 556 // Bind the address of the object, then check to see if we cached out. 557 State = State->BindExpr(CNE, LCtx, Result); 558 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State); 559 if (!NewN) 560 return; 561 562 // If the type is not a record, we won't have a CXXConstructExpr as an 563 // initializer. Copy the value over. 564 if (const Expr *Init = CNE->getInitializer()) { 565 if (!isa<CXXConstructExpr>(Init)) { 566 assert(Bldr.getResults().size() == 1); 567 Bldr.takeNodes(NewN); 568 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx), 569 /*FirstInit=*/IsStandardGlobalOpNewFunction); 570 } 571 } 572 } 573 574 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 575 ExplodedNode *Pred, ExplodedNodeSet &Dst) { 576 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 577 ProgramStateRef state = Pred->getState(); 578 Bldr.generateNode(CDE, Pred, state); 579 } 580 581 void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 582 ExplodedNode *Pred, 583 ExplodedNodeSet &Dst) { 584 const VarDecl *VD = CS->getExceptionDecl(); 585 if (!VD) { 586 Dst.Add(Pred); 587 return; 588 } 589 590 const LocationContext *LCtx = Pred->getLocationContext(); 591 SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(), 592 currBldrCtx->blockCount()); 593 ProgramStateRef state = Pred->getState(); 594 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx); 595 596 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 597 Bldr.generateNode(CS, Pred, state); 598 } 599 600 void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 601 ExplodedNodeSet &Dst) { 602 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 603 604 // Get the this object region from StoreManager. 605 const LocationContext *LCtx = Pred->getLocationContext(); 606 const MemRegion *R = 607 svalBuilder.getRegionManager().getCXXThisRegion( 608 getContext().getCanonicalType(TE->getType()), 609 LCtx); 610 611 ProgramStateRef state = Pred->getState(); 612 SVal V = state->getSVal(loc::MemRegionVal(R)); 613 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 614 } 615 616 void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, 617 ExplodedNodeSet &Dst) { 618 const LocationContext *LocCtxt = Pred->getLocationContext(); 619 620 // Get the region of the lambda itself. 621 const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion( 622 LE, LocCtxt); 623 SVal V = loc::MemRegionVal(R); 624 625 ProgramStateRef State = Pred->getState(); 626 627 // If we created a new MemRegion for the lambda, we should explicitly bind 628 // the captures. 629 CXXRecordDecl::field_iterator CurField = LE->getLambdaClass()->field_begin(); 630 for (LambdaExpr::const_capture_init_iterator i = LE->capture_init_begin(), 631 e = LE->capture_init_end(); 632 i != e; ++i, ++CurField) { 633 FieldDecl *FieldForCapture = *CurField; 634 SVal FieldLoc = State->getLValue(FieldForCapture, V); 635 636 SVal InitVal; 637 if (!FieldForCapture->hasCapturedVLAType()) { 638 Expr *InitExpr = *i; 639 assert(InitExpr && "Capture missing initialization expression"); 640 InitVal = State->getSVal(InitExpr, LocCtxt); 641 } else { 642 // The field stores the length of a captured variable-length array. 643 // These captures don't have initialization expressions; instead we 644 // get the length from the VLAType size expression. 645 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr(); 646 InitVal = State->getSVal(SizeExpr, LocCtxt); 647 } 648 649 State = State->bindLoc(FieldLoc, InitVal, LocCtxt); 650 } 651 652 // Decay the Loc into an RValue, because there might be a 653 // MaterializeTemporaryExpr node above this one which expects the bound value 654 // to be an RValue. 655 SVal LambdaRVal = State->getSVal(R); 656 657 ExplodedNodeSet Tmp; 658 StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); 659 // FIXME: is this the right program point kind? 660 Bldr.generateNode(LE, Pred, 661 State->BindExpr(LE, LocCtxt, LambdaRVal), 662 nullptr, ProgramPoint::PostLValueKind); 663 664 // FIXME: Move all post/pre visits to ::Visit(). 665 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this); 666 } 667