1 //===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===// 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 the C++ expression evaluation engine. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 14 #include "clang/Analysis/ConstructionContext.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->getSubExpr()->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 const CXXRecordDecl *ThisRD = nullptr; 45 if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) { 46 assert(Ctor->getDecl()->isTrivial()); 47 assert(Ctor->getDecl()->isCopyOrMoveConstructor()); 48 ThisVal = Ctor->getCXXThisVal(); 49 ThisRD = Ctor->getDecl()->getParent(); 50 AlwaysReturnsLValue = false; 51 } else { 52 assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial()); 53 assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() == 54 OO_Equal); 55 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal(); 56 ThisRD = cast<CXXMethodDecl>(Call.getDecl())->getParent(); 57 AlwaysReturnsLValue = true; 58 } 59 60 assert(ThisRD); 61 if (ThisRD->isEmpty()) { 62 // Do nothing for empty classes. Otherwise it'd retrieve an UnknownVal 63 // and bind it and RegionStore would think that the actual value 64 // in this region at this offset is unknown. 65 return; 66 } 67 68 const LocationContext *LCtx = Pred->getLocationContext(); 69 70 ExplodedNodeSet Dst; 71 Bldr.takeNodes(Pred); 72 73 SVal V = Call.getArgSVal(0); 74 75 // If the value being copied is not unknown, load from its location to get 76 // an aggregate rvalue. 77 if (Optional<Loc> L = V.getAs<Loc>()) 78 V = Pred->getState()->getSVal(*L); 79 else 80 assert(V.isUnknownOrUndef()); 81 82 const Expr *CallExpr = Call.getOriginExpr(); 83 evalBind(Dst, CallExpr, Pred, ThisVal, V, true); 84 85 PostStmt PS(CallExpr, LCtx); 86 for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); 87 I != E; ++I) { 88 ProgramStateRef State = (*I)->getState(); 89 if (AlwaysReturnsLValue) 90 State = State->BindExpr(CallExpr, LCtx, ThisVal); 91 else 92 State = bindReturnValue(Call, LCtx, State); 93 Bldr.generateNode(PS, State, *I); 94 } 95 } 96 97 SVal ExprEngine::makeElementRegion(ProgramStateRef State, SVal LValue, 98 QualType &Ty, bool &IsArray, unsigned Idx) { 99 SValBuilder &SVB = State->getStateManager().getSValBuilder(); 100 ASTContext &Ctx = SVB.getContext(); 101 102 if (const ArrayType *AT = Ctx.getAsArrayType(Ty)) { 103 while (AT) { 104 Ty = AT->getElementType(); 105 AT = dyn_cast<ArrayType>(AT->getElementType()); 106 } 107 LValue = State->getLValue(Ty, SVB.makeArrayIndex(Idx), LValue); 108 IsArray = true; 109 } 110 111 return LValue; 112 } 113 114 // In case when the prvalue is returned from the function (kind is one of 115 // SimpleReturnedValueKind, CXX17ElidedCopyReturnedValueKind), then 116 // it's materialization happens in context of the caller. 117 // We pass BldrCtx explicitly, as currBldrCtx always refers to callee's context. 118 SVal ExprEngine::computeObjectUnderConstruction( 119 const Expr *E, ProgramStateRef State, const NodeBuilderContext *BldrCtx, 120 const LocationContext *LCtx, const ConstructionContext *CC, 121 EvalCallOptions &CallOpts, unsigned Idx) { 122 123 SValBuilder &SVB = getSValBuilder(); 124 MemRegionManager &MRMgr = SVB.getRegionManager(); 125 ASTContext &ACtx = SVB.getContext(); 126 127 // Compute the target region by exploring the construction context. 128 if (CC) { 129 switch (CC->getKind()) { 130 case ConstructionContext::CXX17ElidedCopyVariableKind: 131 case ConstructionContext::SimpleVariableKind: { 132 const auto *DSCC = cast<VariableConstructionContext>(CC); 133 const auto *DS = DSCC->getDeclStmt(); 134 const auto *Var = cast<VarDecl>(DS->getSingleDecl()); 135 QualType Ty = Var->getType(); 136 return makeElementRegion(State, State->getLValue(Var, LCtx), Ty, 137 CallOpts.IsArrayCtorOrDtor, Idx); 138 } 139 case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind: 140 case ConstructionContext::SimpleConstructorInitializerKind: { 141 const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC); 142 const auto *Init = ICC->getCXXCtorInitializer(); 143 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 144 Loc ThisPtr = SVB.getCXXThis(CurCtor, LCtx->getStackFrame()); 145 SVal ThisVal = State->getSVal(ThisPtr); 146 if (Init->isBaseInitializer()) { 147 const auto *ThisReg = cast<SubRegion>(ThisVal.getAsRegion()); 148 const CXXRecordDecl *BaseClass = 149 Init->getBaseClass()->getAsCXXRecordDecl(); 150 const auto *BaseReg = 151 MRMgr.getCXXBaseObjectRegion(BaseClass, ThisReg, 152 Init->isBaseVirtual()); 153 return SVB.makeLoc(BaseReg); 154 } 155 if (Init->isDelegatingInitializer()) 156 return ThisVal; 157 158 const ValueDecl *Field; 159 SVal FieldVal; 160 if (Init->isIndirectMemberInitializer()) { 161 Field = Init->getIndirectMember(); 162 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal); 163 } else { 164 Field = Init->getMember(); 165 FieldVal = State->getLValue(Init->getMember(), ThisVal); 166 } 167 168 QualType Ty = Field->getType(); 169 return makeElementRegion(State, FieldVal, Ty, CallOpts.IsArrayCtorOrDtor, 170 Idx); 171 } 172 case ConstructionContext::NewAllocatedObjectKind: { 173 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) { 174 const auto *NECC = cast<NewAllocatedObjectConstructionContext>(CC); 175 const auto *NE = NECC->getCXXNewExpr(); 176 SVal V = *getObjectUnderConstruction(State, NE, LCtx); 177 if (const SubRegion *MR = 178 dyn_cast_or_null<SubRegion>(V.getAsRegion())) { 179 if (NE->isArray()) { 180 CallOpts.IsArrayCtorOrDtor = true; 181 182 auto Ty = NE->getType()->getPointeeType(); 183 while (const auto *AT = getContext().getAsArrayType(Ty)) 184 Ty = AT->getElementType(); 185 186 auto R = MRMgr.getElementRegion(Ty, svalBuilder.makeArrayIndex(Idx), 187 MR, SVB.getContext()); 188 189 return loc::MemRegionVal(R); 190 } 191 return V; 192 } 193 // TODO: Detect when the allocator returns a null pointer. 194 // Constructor shall not be called in this case. 195 } 196 break; 197 } 198 case ConstructionContext::SimpleReturnedValueKind: 199 case ConstructionContext::CXX17ElidedCopyReturnedValueKind: { 200 // The temporary is to be managed by the parent stack frame. 201 // So build it in the parent stack frame if we're not in the 202 // top frame of the analysis. 203 const StackFrameContext *SFC = LCtx->getStackFrame(); 204 if (const LocationContext *CallerLCtx = SFC->getParent()) { 205 auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()] 206 .getAs<CFGCXXRecordTypedCall>(); 207 if (!RTC) { 208 // We were unable to find the correct construction context for the 209 // call in the parent stack frame. This is equivalent to not being 210 // able to find construction context at all. 211 break; 212 } 213 if (isa<BlockInvocationContext>(CallerLCtx)) { 214 // Unwrap block invocation contexts. They're mostly part of 215 // the current stack frame. 216 CallerLCtx = CallerLCtx->getParent(); 217 assert(!isa<BlockInvocationContext>(CallerLCtx)); 218 } 219 220 NodeBuilderContext CallerBldrCtx(getCoreEngine(), 221 SFC->getCallSiteBlock(), CallerLCtx); 222 return computeObjectUnderConstruction( 223 cast<Expr>(SFC->getCallSite()), State, &CallerBldrCtx, CallerLCtx, 224 RTC->getConstructionContext(), CallOpts); 225 } else { 226 // We are on the top frame of the analysis. We do not know where is the 227 // object returned to. Conjure a symbolic region for the return value. 228 // TODO: We probably need a new MemRegion kind to represent the storage 229 // of that SymbolicRegion, so that we cound produce a fancy symbol 230 // instead of an anonymous conjured symbol. 231 // TODO: Do we need to track the region to avoid having it dead 232 // too early? It does die too early, at least in C++17, but because 233 // putting anything into a SymbolicRegion causes an immediate escape, 234 // it doesn't cause any leak false positives. 235 const auto *RCC = cast<ReturnedValueConstructionContext>(CC); 236 // Make sure that this doesn't coincide with any other symbol 237 // conjured for the returned expression. 238 static const int TopLevelSymRegionTag = 0; 239 const Expr *RetE = RCC->getReturnStmt()->getRetValue(); 240 assert(RetE && "Void returns should not have a construction context"); 241 QualType ReturnTy = RetE->getType(); 242 QualType RegionTy = ACtx.getPointerType(ReturnTy); 243 return SVB.conjureSymbolVal(&TopLevelSymRegionTag, RetE, SFC, RegionTy, 244 currBldrCtx->blockCount()); 245 } 246 llvm_unreachable("Unhandled return value construction context!"); 247 } 248 case ConstructionContext::ElidedTemporaryObjectKind: { 249 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors); 250 const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC); 251 252 // Support pre-C++17 copy elision. We'll have the elidable copy 253 // constructor in the AST and in the CFG, but we'll skip it 254 // and construct directly into the final object. This call 255 // also sets the CallOpts flags for us. 256 // If the elided copy/move constructor is not supported, there's still 257 // benefit in trying to model the non-elided constructor. 258 // Stash our state before trying to elide, as it'll get overwritten. 259 ProgramStateRef PreElideState = State; 260 EvalCallOptions PreElideCallOpts = CallOpts; 261 262 SVal V = computeObjectUnderConstruction( 263 TCC->getConstructorAfterElision(), State, BldrCtx, LCtx, 264 TCC->getConstructionContextAfterElision(), CallOpts); 265 266 // FIXME: This definition of "copy elision has not failed" is unreliable. 267 // It doesn't indicate that the constructor will actually be inlined 268 // later; this is still up to evalCall() to decide. 269 if (!CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion) 270 return V; 271 272 // Copy elision failed. Revert the changes and proceed as if we have 273 // a simple temporary. 274 CallOpts = PreElideCallOpts; 275 CallOpts.IsElidableCtorThatHasNotBeenElided = true; 276 [[fallthrough]]; 277 } 278 case ConstructionContext::SimpleTemporaryObjectKind: { 279 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC); 280 const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr(); 281 282 CallOpts.IsTemporaryCtorOrDtor = true; 283 if (MTE) { 284 if (const ValueDecl *VD = MTE->getExtendingDecl()) { 285 assert(MTE->getStorageDuration() != SD_FullExpression); 286 if (!VD->getType()->isReferenceType()) { 287 // We're lifetime-extended by a surrounding aggregate. 288 // Automatic destructors aren't quite working in this case 289 // on the CFG side. We should warn the caller about that. 290 // FIXME: Is there a better way to retrieve this information from 291 // the MaterializeTemporaryExpr? 292 CallOpts.IsTemporaryLifetimeExtendedViaAggregate = true; 293 } 294 } 295 296 if (MTE->getStorageDuration() == SD_Static || 297 MTE->getStorageDuration() == SD_Thread) 298 return loc::MemRegionVal(MRMgr.getCXXStaticTempObjectRegion(E)); 299 } 300 301 return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx)); 302 } 303 case ConstructionContext::LambdaCaptureKind: { 304 CallOpts.IsTemporaryCtorOrDtor = true; 305 306 const auto *LCC = cast<LambdaCaptureConstructionContext>(CC); 307 308 SVal Base = loc::MemRegionVal( 309 MRMgr.getCXXTempObjectRegion(LCC->getInitializer(), LCtx)); 310 311 const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E); 312 if (getIndexOfElementToConstruct(State, CE, LCtx)) { 313 CallOpts.IsArrayCtorOrDtor = true; 314 Base = State->getLValue(E->getType(), svalBuilder.makeArrayIndex(Idx), 315 Base); 316 } 317 318 return Base; 319 } 320 case ConstructionContext::ArgumentKind: { 321 // Arguments are technically temporaries. 322 CallOpts.IsTemporaryCtorOrDtor = true; 323 324 const auto *ACC = cast<ArgumentConstructionContext>(CC); 325 const Expr *E = ACC->getCallLikeExpr(); 326 unsigned Idx = ACC->getIndex(); 327 328 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 329 auto getArgLoc = [&](CallEventRef<> Caller) -> Optional<SVal> { 330 const LocationContext *FutureSFC = 331 Caller->getCalleeStackFrame(BldrCtx->blockCount()); 332 // Return early if we are unable to reliably foresee 333 // the future stack frame. 334 if (!FutureSFC) 335 return None; 336 337 // This should be equivalent to Caller->getDecl() for now, but 338 // FutureSFC->getDecl() is likely to support better stuff (like 339 // virtual functions) earlier. 340 const Decl *CalleeD = FutureSFC->getDecl(); 341 342 // FIXME: Support for variadic arguments is not implemented here yet. 343 if (CallEvent::isVariadic(CalleeD)) 344 return None; 345 346 // Operator arguments do not correspond to operator parameters 347 // because this-argument is implemented as a normal argument in 348 // operator call expressions but not in operator declarations. 349 const TypedValueRegion *TVR = Caller->getParameterLocation( 350 *Caller->getAdjustedParameterIndex(Idx), BldrCtx->blockCount()); 351 if (!TVR) 352 return None; 353 354 return loc::MemRegionVal(TVR); 355 }; 356 357 if (const auto *CE = dyn_cast<CallExpr>(E)) { 358 CallEventRef<> Caller = CEMgr.getSimpleCall(CE, State, LCtx); 359 if (Optional<SVal> V = getArgLoc(Caller)) 360 return *V; 361 else 362 break; 363 } else if (const auto *CCE = dyn_cast<CXXConstructExpr>(E)) { 364 // Don't bother figuring out the target region for the future 365 // constructor because we won't need it. 366 CallEventRef<> Caller = 367 CEMgr.getCXXConstructorCall(CCE, /*Target=*/nullptr, State, LCtx); 368 if (Optional<SVal> V = getArgLoc(Caller)) 369 return *V; 370 else 371 break; 372 } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) { 373 CallEventRef<> Caller = CEMgr.getObjCMethodCall(ME, State, LCtx); 374 if (Optional<SVal> V = getArgLoc(Caller)) 375 return *V; 376 else 377 break; 378 } 379 } 380 } // switch (CC->getKind()) 381 } 382 383 // If we couldn't find an existing region to construct into, assume we're 384 // constructing a temporary. Notify the caller of our failure. 385 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true; 386 return loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx)); 387 } 388 389 ProgramStateRef ExprEngine::updateObjectsUnderConstruction( 390 SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx, 391 const ConstructionContext *CC, const EvalCallOptions &CallOpts) { 392 if (CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion) { 393 // Sounds like we failed to find the target region and therefore 394 // copy elision failed. There's nothing we can do about it here. 395 return State; 396 } 397 398 // See if we're constructing an existing region by looking at the 399 // current construction context. 400 assert(CC && "Computed target region without construction context?"); 401 switch (CC->getKind()) { 402 case ConstructionContext::CXX17ElidedCopyVariableKind: 403 case ConstructionContext::SimpleVariableKind: { 404 const auto *DSCC = cast<VariableConstructionContext>(CC); 405 return addObjectUnderConstruction(State, DSCC->getDeclStmt(), LCtx, V); 406 } 407 case ConstructionContext::CXX17ElidedCopyConstructorInitializerKind: 408 case ConstructionContext::SimpleConstructorInitializerKind: { 409 const auto *ICC = cast<ConstructorInitializerConstructionContext>(CC); 410 const auto *Init = ICC->getCXXCtorInitializer(); 411 // Base and delegating initializers handled above 412 assert(Init->isAnyMemberInitializer() && 413 "Base and delegating initializers should have been handled by" 414 "computeObjectUnderConstruction()"); 415 return addObjectUnderConstruction(State, Init, LCtx, V); 416 } 417 case ConstructionContext::NewAllocatedObjectKind: { 418 return State; 419 } 420 case ConstructionContext::SimpleReturnedValueKind: 421 case ConstructionContext::CXX17ElidedCopyReturnedValueKind: { 422 const StackFrameContext *SFC = LCtx->getStackFrame(); 423 const LocationContext *CallerLCtx = SFC->getParent(); 424 if (!CallerLCtx) { 425 // No extra work is necessary in top frame. 426 return State; 427 } 428 429 auto RTC = (*SFC->getCallSiteBlock())[SFC->getIndex()] 430 .getAs<CFGCXXRecordTypedCall>(); 431 assert(RTC && "Could not have had a target region without it"); 432 if (isa<BlockInvocationContext>(CallerLCtx)) { 433 // Unwrap block invocation contexts. They're mostly part of 434 // the current stack frame. 435 CallerLCtx = CallerLCtx->getParent(); 436 assert(!isa<BlockInvocationContext>(CallerLCtx)); 437 } 438 439 return updateObjectsUnderConstruction(V, 440 cast<Expr>(SFC->getCallSite()), State, CallerLCtx, 441 RTC->getConstructionContext(), CallOpts); 442 } 443 case ConstructionContext::ElidedTemporaryObjectKind: { 444 assert(AMgr.getAnalyzerOptions().ShouldElideConstructors); 445 if (!CallOpts.IsElidableCtorThatHasNotBeenElided) { 446 const auto *TCC = cast<ElidedTemporaryObjectConstructionContext>(CC); 447 State = updateObjectsUnderConstruction( 448 V, TCC->getConstructorAfterElision(), State, LCtx, 449 TCC->getConstructionContextAfterElision(), CallOpts); 450 451 // Remember that we've elided the constructor. 452 State = addObjectUnderConstruction( 453 State, TCC->getConstructorAfterElision(), LCtx, V); 454 455 // Remember that we've elided the destructor. 456 if (const auto *BTE = TCC->getCXXBindTemporaryExpr()) 457 State = elideDestructor(State, BTE, LCtx); 458 459 // Instead of materialization, shamelessly return 460 // the final object destination. 461 if (const auto *MTE = TCC->getMaterializedTemporaryExpr()) 462 State = addObjectUnderConstruction(State, MTE, LCtx, V); 463 464 return State; 465 } 466 // If we decided not to elide the constructor, proceed as if 467 // it's a simple temporary. 468 [[fallthrough]]; 469 } 470 case ConstructionContext::SimpleTemporaryObjectKind: { 471 const auto *TCC = cast<TemporaryObjectConstructionContext>(CC); 472 if (const auto *BTE = TCC->getCXXBindTemporaryExpr()) 473 State = addObjectUnderConstruction(State, BTE, LCtx, V); 474 475 if (const auto *MTE = TCC->getMaterializedTemporaryExpr()) 476 State = addObjectUnderConstruction(State, MTE, LCtx, V); 477 478 return State; 479 } 480 case ConstructionContext::LambdaCaptureKind: { 481 const auto *LCC = cast<LambdaCaptureConstructionContext>(CC); 482 483 // If we capture and array, we want to store the super region, not a 484 // sub-region. 485 if (const auto *EL = dyn_cast_or_null<ElementRegion>(V.getAsRegion())) 486 V = loc::MemRegionVal(EL->getSuperRegion()); 487 488 return addObjectUnderConstruction( 489 State, {LCC->getLambdaExpr(), LCC->getIndex()}, LCtx, V); 490 } 491 case ConstructionContext::ArgumentKind: { 492 const auto *ACC = cast<ArgumentConstructionContext>(CC); 493 if (const auto *BTE = ACC->getCXXBindTemporaryExpr()) 494 State = addObjectUnderConstruction(State, BTE, LCtx, V); 495 496 return addObjectUnderConstruction( 497 State, {ACC->getCallLikeExpr(), ACC->getIndex()}, LCtx, V); 498 } 499 } 500 llvm_unreachable("Unhandled construction context!"); 501 } 502 503 static ProgramStateRef 504 bindRequiredArrayElementToEnvironment(ProgramStateRef State, 505 const ArrayInitLoopExpr *AILE, 506 const LocationContext *LCtx, SVal Idx) { 507 // The ctor in this case is guaranteed to be a copy ctor, otherwise we hit a 508 // compile time error. 509 // 510 // -ArrayInitLoopExpr <-- we're here 511 // |-OpaqueValueExpr 512 // | `-DeclRefExpr <-- match this 513 // `-CXXConstructExpr 514 // `-ImplicitCastExpr 515 // `-ArraySubscriptExpr 516 // |-ImplicitCastExpr 517 // | `-OpaqueValueExpr 518 // | `-DeclRefExpr 519 // `-ArrayInitIndexExpr 520 // 521 // The resulting expression might look like the one below in an implicit 522 // copy/move ctor. 523 // 524 // ArrayInitLoopExpr <-- we're here 525 // |-OpaqueValueExpr 526 // | `-MemberExpr <-- match this 527 // | (`-CXXStaticCastExpr) <-- move ctor only 528 // | `-DeclRefExpr 529 // `-CXXConstructExpr 530 // `-ArraySubscriptExpr 531 // |-ImplicitCastExpr 532 // | `-OpaqueValueExpr 533 // | `-MemberExpr 534 // | `-DeclRefExpr 535 // `-ArrayInitIndexExpr 536 // 537 // The resulting expression for a multidimensional array. 538 // ArrayInitLoopExpr <-- we're here 539 // |-OpaqueValueExpr 540 // | `-DeclRefExpr <-- match this 541 // `-ArrayInitLoopExpr 542 // |-OpaqueValueExpr 543 // | `-ArraySubscriptExpr 544 // | |-ImplicitCastExpr 545 // | | `-OpaqueValueExpr 546 // | | `-DeclRefExpr 547 // | `-ArrayInitIndexExpr 548 // `-CXXConstructExpr <-- extract this 549 // ` ... 550 551 const auto *OVESrc = AILE->getCommonExpr()->getSourceExpr(); 552 553 // HACK: There is no way we can put the index of the array element into the 554 // CFG unless we unroll the loop, so we manually select and bind the required 555 // parameter to the environment. 556 const auto *CE = 557 cast<CXXConstructExpr>(extractElementInitializerFromNestedAILE(AILE)); 558 559 SVal Base = UnknownVal(); 560 if (const auto *ME = dyn_cast<MemberExpr>(OVESrc)) 561 Base = State->getSVal(ME, LCtx); 562 else if (const auto *DRE = dyn_cast<DeclRefExpr>(OVESrc)) 563 Base = State->getLValue(cast<VarDecl>(DRE->getDecl()), LCtx); 564 else 565 llvm_unreachable("ArrayInitLoopExpr contains unexpected source expression"); 566 567 SVal NthElem = State->getLValue(CE->getType(), Idx, Base); 568 569 return State->BindExpr(CE->getArg(0), LCtx, NthElem); 570 } 571 572 void ExprEngine::handleConstructor(const Expr *E, 573 ExplodedNode *Pred, 574 ExplodedNodeSet &destNodes) { 575 const auto *CE = dyn_cast<CXXConstructExpr>(E); 576 const auto *CIE = dyn_cast<CXXInheritedCtorInitExpr>(E); 577 assert(CE || CIE); 578 579 const LocationContext *LCtx = Pred->getLocationContext(); 580 ProgramStateRef State = Pred->getState(); 581 582 SVal Target = UnknownVal(); 583 584 if (CE) { 585 if (Optional<SVal> ElidedTarget = 586 getObjectUnderConstruction(State, CE, LCtx)) { 587 // We've previously modeled an elidable constructor by pretending that it 588 // in fact constructs into the correct target. This constructor can 589 // therefore be skipped. 590 Target = *ElidedTarget; 591 StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx); 592 State = finishObjectConstruction(State, CE, LCtx); 593 if (auto L = Target.getAs<Loc>()) 594 State = State->BindExpr(CE, LCtx, State->getSVal(*L, CE->getType())); 595 Bldr.generateNode(CE, Pred, State); 596 return; 597 } 598 } 599 600 EvalCallOptions CallOpts; 601 auto C = getCurrentCFGElement().getAs<CFGConstructor>(); 602 assert(C || getCurrentCFGElement().getAs<CFGStmt>()); 603 const ConstructionContext *CC = C ? C->getConstructionContext() : nullptr; 604 605 const CXXConstructExpr::ConstructionKind CK = 606 CE ? CE->getConstructionKind() : CIE->getConstructionKind(); 607 switch (CK) { 608 case CXXConstructExpr::CK_Complete: { 609 // Inherited constructors are always base class constructors. 610 assert(CE && !CIE && "A complete constructor is inherited?!"); 611 612 // If the ctor is part of an ArrayInitLoopExpr, we want to handle it 613 // differently. 614 auto *AILE = CC ? CC->getArrayInitLoop() : nullptr; 615 616 unsigned Idx = 0; 617 if (CE->getType()->isArrayType() || AILE) { 618 619 auto isZeroSizeArray = [&] { 620 uint64_t Size = 1; 621 622 if (const auto *CAT = dyn_cast<ConstantArrayType>(CE->getType())) 623 Size = getContext().getConstantArrayElementCount(CAT); 624 else if (AILE) 625 Size = getContext().getArrayInitLoopExprElementCount(AILE); 626 627 return Size == 0; 628 }; 629 630 // No element construction will happen in a 0 size array. 631 if (isZeroSizeArray()) { 632 StmtNodeBuilder Bldr(Pred, destNodes, *currBldrCtx); 633 static SimpleProgramPointTag T{"ExprEngine", 634 "Skipping 0 size array construction"}; 635 Bldr.generateNode(CE, Pred, State, &T); 636 return; 637 } 638 639 Idx = getIndexOfElementToConstruct(State, CE, LCtx).value_or(0u); 640 State = setIndexOfElementToConstruct(State, CE, LCtx, Idx + 1); 641 } 642 643 if (AILE) { 644 // Only set this once even though we loop through it multiple times. 645 if (!getPendingInitLoop(State, CE, LCtx)) 646 State = setPendingInitLoop( 647 State, CE, LCtx, 648 getContext().getArrayInitLoopExprElementCount(AILE)); 649 650 State = bindRequiredArrayElementToEnvironment( 651 State, AILE, LCtx, svalBuilder.makeArrayIndex(Idx)); 652 } 653 654 // The target region is found from construction context. 655 std::tie(State, Target) = handleConstructionContext( 656 CE, State, currBldrCtx, LCtx, CC, CallOpts, Idx); 657 break; 658 } 659 case CXXConstructExpr::CK_VirtualBase: { 660 // Make sure we are not calling virtual base class initializers twice. 661 // Only the most-derived object should initialize virtual base classes. 662 const auto *OuterCtor = dyn_cast_or_null<CXXConstructExpr>( 663 LCtx->getStackFrame()->getCallSite()); 664 assert( 665 (!OuterCtor || 666 OuterCtor->getConstructionKind() == CXXConstructExpr::CK_Complete || 667 OuterCtor->getConstructionKind() == CXXConstructExpr::CK_Delegating) && 668 ("This virtual base should have already been initialized by " 669 "the most derived class!")); 670 (void)OuterCtor; 671 [[fallthrough]]; 672 } 673 case CXXConstructExpr::CK_NonVirtualBase: 674 // In C++17, classes with non-virtual bases may be aggregates, so they would 675 // be initialized as aggregates without a constructor call, so we may have 676 // a base class constructed directly into an initializer list without 677 // having the derived-class constructor call on the previous stack frame. 678 // Initializer lists may be nested into more initializer lists that 679 // correspond to surrounding aggregate initializations. 680 // FIXME: For now this code essentially bails out. We need to find the 681 // correct target region and set it. 682 // FIXME: Instead of relying on the ParentMap, we should have the 683 // trigger-statement (InitListExpr in this case) passed down from CFG or 684 // otherwise always available during construction. 685 if (isa_and_nonnull<InitListExpr>(LCtx->getParentMap().getParent(E))) { 686 MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 687 Target = loc::MemRegionVal(MRMgr.getCXXTempObjectRegion(E, LCtx)); 688 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true; 689 break; 690 } 691 [[fallthrough]]; 692 case CXXConstructExpr::CK_Delegating: { 693 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 694 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 695 LCtx->getStackFrame()); 696 SVal ThisVal = State->getSVal(ThisPtr); 697 698 if (CK == CXXConstructExpr::CK_Delegating) { 699 Target = ThisVal; 700 } else { 701 // Cast to the base type. 702 bool IsVirtual = (CK == CXXConstructExpr::CK_VirtualBase); 703 SVal BaseVal = 704 getStoreManager().evalDerivedToBase(ThisVal, E->getType(), IsVirtual); 705 Target = BaseVal; 706 } 707 break; 708 } 709 } 710 711 if (State != Pred->getState()) { 712 static SimpleProgramPointTag T("ExprEngine", 713 "Prepare for object construction"); 714 ExplodedNodeSet DstPrepare; 715 StmtNodeBuilder BldrPrepare(Pred, DstPrepare, *currBldrCtx); 716 BldrPrepare.generateNode(E, Pred, State, &T, ProgramPoint::PreStmtKind); 717 assert(DstPrepare.size() <= 1); 718 if (DstPrepare.size() == 0) 719 return; 720 Pred = *BldrPrepare.begin(); 721 } 722 723 const MemRegion *TargetRegion = Target.getAsRegion(); 724 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 725 CallEventRef<> Call = 726 CIE ? (CallEventRef<>)CEMgr.getCXXInheritedConstructorCall( 727 CIE, TargetRegion, State, LCtx) 728 : (CallEventRef<>)CEMgr.getCXXConstructorCall( 729 CE, TargetRegion, State, LCtx); 730 731 ExplodedNodeSet DstPreVisit; 732 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, E, *this); 733 734 ExplodedNodeSet PreInitialized; 735 if (CE) { 736 // FIXME: Is it possible and/or useful to do this before PreStmt? 737 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx); 738 for (ExplodedNodeSet::iterator I = DstPreVisit.begin(), 739 E = DstPreVisit.end(); 740 I != E; ++I) { 741 ProgramStateRef State = (*I)->getState(); 742 if (CE->requiresZeroInitialization()) { 743 // FIXME: Once we properly handle constructors in new-expressions, we'll 744 // need to invalidate the region before setting a default value, to make 745 // sure there aren't any lingering bindings around. This probably needs 746 // to happen regardless of whether or not the object is zero-initialized 747 // to handle random fields of a placement-initialized object picking up 748 // old bindings. We might only want to do it when we need to, though. 749 // FIXME: This isn't actually correct for arrays -- we need to zero- 750 // initialize the entire array, not just the first element -- but our 751 // handling of arrays everywhere else is weak as well, so this shouldn't 752 // actually make things worse. Placement new makes this tricky as well, 753 // since it's then possible to be initializing one part of a multi- 754 // dimensional array. 755 State = State->bindDefaultZero(Target, LCtx); 756 } 757 758 Bldr.generateNode(CE, *I, State, /*tag=*/nullptr, 759 ProgramPoint::PreStmtKind); 760 } 761 } else { 762 PreInitialized = DstPreVisit; 763 } 764 765 ExplodedNodeSet DstPreCall; 766 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized, 767 *Call, *this); 768 769 ExplodedNodeSet DstEvaluated; 770 771 if (CE && CE->getConstructor()->isTrivial() && 772 CE->getConstructor()->isCopyOrMoveConstructor() && 773 !CallOpts.IsArrayCtorOrDtor) { 774 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx); 775 // FIXME: Handle other kinds of trivial constructors as well. 776 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 777 I != E; ++I) 778 performTrivialCopy(Bldr, *I, *Call); 779 780 } else { 781 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 782 I != E; ++I) 783 getCheckerManager().runCheckersForEvalCall(DstEvaluated, *I, *Call, *this, 784 CallOpts); 785 } 786 787 // If the CFG was constructed without elements for temporary destructors 788 // and the just-called constructor created a temporary object then 789 // stop exploration if the temporary object has a noreturn constructor. 790 // This can lose coverage because the destructor, if it were present 791 // in the CFG, would be called at the end of the full expression or 792 // later (for life-time extended temporaries) -- but avoids infeasible 793 // paths when no-return temporary destructors are used for assertions. 794 ExplodedNodeSet DstEvaluatedPostProcessed; 795 StmtNodeBuilder Bldr(DstEvaluated, DstEvaluatedPostProcessed, *currBldrCtx); 796 const AnalysisDeclContext *ADC = LCtx->getAnalysisDeclContext(); 797 if (!ADC->getCFGBuildOptions().AddTemporaryDtors) { 798 if (llvm::isa_and_nonnull<CXXTempObjectRegion>(TargetRegion) && 799 cast<CXXConstructorDecl>(Call->getDecl()) 800 ->getParent() 801 ->isAnyDestructorNoReturn()) { 802 803 // If we've inlined the constructor, then DstEvaluated would be empty. 804 // In this case we still want a sink, which could be implemented 805 // in processCallExit. But we don't have that implemented at the moment, 806 // so if you hit this assertion, see if you can avoid inlining 807 // the respective constructor when analyzer-config cfg-temporary-dtors 808 // is set to false. 809 // Otherwise there's nothing wrong with inlining such constructor. 810 assert(!DstEvaluated.empty() && 811 "We should not have inlined this constructor!"); 812 813 for (ExplodedNode *N : DstEvaluated) { 814 Bldr.generateSink(E, N, N->getState()); 815 } 816 817 // There is no need to run the PostCall and PostStmt checker 818 // callbacks because we just generated sinks on all nodes in th 819 // frontier. 820 return; 821 } 822 } 823 824 ExplodedNodeSet DstPostArgumentCleanup; 825 for (ExplodedNode *I : DstEvaluatedPostProcessed) 826 finishArgumentConstruction(DstPostArgumentCleanup, I, *Call); 827 828 // If there were other constructors called for object-type arguments 829 // of this constructor, clean them up. 830 ExplodedNodeSet DstPostCall; 831 getCheckerManager().runCheckersForPostCall(DstPostCall, 832 DstPostArgumentCleanup, 833 *Call, *this); 834 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, E, *this); 835 } 836 837 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 838 ExplodedNode *Pred, 839 ExplodedNodeSet &Dst) { 840 handleConstructor(CE, Pred, Dst); 841 } 842 843 void ExprEngine::VisitCXXInheritedCtorInitExpr( 844 const CXXInheritedCtorInitExpr *CE, ExplodedNode *Pred, 845 ExplodedNodeSet &Dst) { 846 handleConstructor(CE, Pred, Dst); 847 } 848 849 void ExprEngine::VisitCXXDestructor(QualType ObjectType, 850 const MemRegion *Dest, 851 const Stmt *S, 852 bool IsBaseDtor, 853 ExplodedNode *Pred, 854 ExplodedNodeSet &Dst, 855 EvalCallOptions &CallOpts) { 856 assert(S && "A destructor without a trigger!"); 857 const LocationContext *LCtx = Pred->getLocationContext(); 858 ProgramStateRef State = Pred->getState(); 859 860 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); 861 assert(RecordDecl && "Only CXXRecordDecls should have destructors"); 862 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); 863 // FIXME: There should always be a Decl, otherwise the destructor call 864 // shouldn't have been added to the CFG in the first place. 865 if (!DtorDecl) { 866 // Skip the invalid destructor. We cannot simply return because 867 // it would interrupt the analysis instead. 868 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor"); 869 // FIXME: PostImplicitCall with a null decl may crash elsewhere anyway. 870 PostImplicitCall PP(/*Decl=*/nullptr, S->getEndLoc(), LCtx, &T); 871 NodeBuilder Bldr(Pred, Dst, *currBldrCtx); 872 Bldr.generateNode(PP, Pred->getState(), Pred); 873 return; 874 } 875 876 if (!Dest) { 877 // We're trying to destroy something that is not a region. This may happen 878 // for a variety of reasons (unknown target region, concrete integer instead 879 // of target region, etc.). The current code makes an attempt to recover. 880 // FIXME: We probably don't really need to recover when we're dealing 881 // with concrete integers specifically. 882 CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion = true; 883 if (const Expr *E = dyn_cast_or_null<Expr>(S)) { 884 Dest = MRMgr.getCXXTempObjectRegion(E, Pred->getLocationContext()); 885 } else { 886 static SimpleProgramPointTag T("ExprEngine", "SkipInvalidDestructor"); 887 NodeBuilder Bldr(Pred, Dst, *currBldrCtx); 888 Bldr.generateSink(Pred->getLocation().withTag(&T), 889 Pred->getState(), Pred); 890 return; 891 } 892 } 893 894 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 895 CallEventRef<CXXDestructorCall> Call = 896 CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); 897 898 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 899 Call->getSourceRange().getBegin(), 900 "Error evaluating destructor"); 901 902 ExplodedNodeSet DstPreCall; 903 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 904 *Call, *this); 905 906 ExplodedNodeSet DstInvalidated; 907 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 908 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 909 I != E; ++I) 910 defaultEvalCall(Bldr, *I, *Call, CallOpts); 911 912 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 913 *Call, *this); 914 } 915 916 void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, 917 ExplodedNode *Pred, 918 ExplodedNodeSet &Dst) { 919 ProgramStateRef State = Pred->getState(); 920 const LocationContext *LCtx = Pred->getLocationContext(); 921 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 922 CNE->getBeginLoc(), 923 "Error evaluating New Allocator Call"); 924 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 925 CallEventRef<CXXAllocatorCall> Call = 926 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 927 928 ExplodedNodeSet DstPreCall; 929 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 930 *Call, *this); 931 932 ExplodedNodeSet DstPostCall; 933 StmtNodeBuilder CallBldr(DstPreCall, DstPostCall, *currBldrCtx); 934 for (ExplodedNode *I : DstPreCall) { 935 // FIXME: Provide evalCall for checkers? 936 defaultEvalCall(CallBldr, I, *Call); 937 } 938 // If the call is inlined, DstPostCall will be empty and we bail out now. 939 940 // Store return value of operator new() for future use, until the actual 941 // CXXNewExpr gets processed. 942 ExplodedNodeSet DstPostValue; 943 StmtNodeBuilder ValueBldr(DstPostCall, DstPostValue, *currBldrCtx); 944 for (ExplodedNode *I : DstPostCall) { 945 // FIXME: Because CNE serves as the "call site" for the allocator (due to 946 // lack of a better expression in the AST), the conjured return value symbol 947 // is going to be of the same type (C++ object pointer type). Technically 948 // this is not correct because the operator new's prototype always says that 949 // it returns a 'void *'. So we should change the type of the symbol, 950 // and then evaluate the cast over the symbolic pointer from 'void *' to 951 // the object pointer type. But without changing the symbol's type it 952 // is breaking too much to evaluate the no-op symbolic cast over it, so we 953 // skip it for now. 954 ProgramStateRef State = I->getState(); 955 SVal RetVal = State->getSVal(CNE, LCtx); 956 957 // If this allocation function is not declared as non-throwing, failures 958 // /must/ be signalled by exceptions, and thus the return value will never 959 // be NULL. -fno-exceptions does not influence this semantics. 960 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case 961 // where new can return NULL. If we end up supporting that option, we can 962 // consider adding a check for it here. 963 // C++11 [basic.stc.dynamic.allocation]p3. 964 if (const FunctionDecl *FD = CNE->getOperatorNew()) { 965 QualType Ty = FD->getType(); 966 if (const auto *ProtoType = Ty->getAs<FunctionProtoType>()) 967 if (!ProtoType->isNothrow()) 968 State = State->assume(RetVal.castAs<DefinedOrUnknownSVal>(), true); 969 } 970 971 ValueBldr.generateNode( 972 CNE, I, addObjectUnderConstruction(State, CNE, LCtx, RetVal)); 973 } 974 975 ExplodedNodeSet DstPostPostCallCallback; 976 getCheckerManager().runCheckersForPostCall(DstPostPostCallCallback, 977 DstPostValue, *Call, *this); 978 for (ExplodedNode *I : DstPostPostCallCallback) { 979 getCheckerManager().runCheckersForNewAllocator(*Call, Dst, I, *this); 980 } 981 } 982 983 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 984 ExplodedNodeSet &Dst) { 985 // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 986 // Also, we need to decide how allocators actually work -- they're not 987 // really part of the CXXNewExpr because they happen BEFORE the 988 // CXXConstructExpr subexpression. See PR12014 for some discussion. 989 990 unsigned blockCount = currBldrCtx->blockCount(); 991 const LocationContext *LCtx = Pred->getLocationContext(); 992 SVal symVal = UnknownVal(); 993 FunctionDecl *FD = CNE->getOperatorNew(); 994 995 bool IsStandardGlobalOpNewFunction = 996 FD->isReplaceableGlobalAllocationFunction(); 997 998 ProgramStateRef State = Pred->getState(); 999 1000 // Retrieve the stored operator new() return value. 1001 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) { 1002 symVal = *getObjectUnderConstruction(State, CNE, LCtx); 1003 State = finishObjectConstruction(State, CNE, LCtx); 1004 } 1005 1006 // We assume all standard global 'operator new' functions allocate memory in 1007 // heap. We realize this is an approximation that might not correctly model 1008 // a custom global allocator. 1009 if (symVal.isUnknown()) { 1010 if (IsStandardGlobalOpNewFunction) 1011 symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount); 1012 else 1013 symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(), 1014 blockCount); 1015 } 1016 1017 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 1018 CallEventRef<CXXAllocatorCall> Call = 1019 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 1020 1021 if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) { 1022 // Invalidate placement args. 1023 // FIXME: Once we figure out how we want allocators to work, 1024 // we should be using the usual pre-/(default-)eval-/post-call checkers 1025 // here. 1026 State = Call->invalidateRegions(blockCount); 1027 if (!State) 1028 return; 1029 1030 // If this allocation function is not declared as non-throwing, failures 1031 // /must/ be signalled by exceptions, and thus the return value will never 1032 // be NULL. -fno-exceptions does not influence this semantics. 1033 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case 1034 // where new can return NULL. If we end up supporting that option, we can 1035 // consider adding a check for it here. 1036 // C++11 [basic.stc.dynamic.allocation]p3. 1037 if (const auto *ProtoType = FD->getType()->getAs<FunctionProtoType>()) 1038 if (!ProtoType->isNothrow()) 1039 if (auto dSymVal = symVal.getAs<DefinedOrUnknownSVal>()) 1040 State = State->assume(*dSymVal, true); 1041 } 1042 1043 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 1044 1045 SVal Result = symVal; 1046 1047 if (CNE->isArray()) { 1048 1049 if (const auto *NewReg = cast_or_null<SubRegion>(symVal.getAsRegion())) { 1050 // If each element is initialized by their default constructor, the field 1051 // values are properly placed inside the required region, however if an 1052 // initializer list is used, this doesn't happen automatically. 1053 auto *Init = CNE->getInitializer(); 1054 bool isInitList = isa_and_nonnull<InitListExpr>(Init); 1055 1056 QualType ObjTy = 1057 isInitList ? Init->getType() : CNE->getType()->getPointeeType(); 1058 const ElementRegion *EleReg = 1059 MRMgr.getElementRegion(ObjTy, svalBuilder.makeArrayIndex(0), NewReg, 1060 svalBuilder.getContext()); 1061 Result = loc::MemRegionVal(EleReg); 1062 1063 // If the array is list initialized, we bind the initializer list to the 1064 // memory region here, otherwise we would lose it. 1065 if (isInitList) { 1066 Bldr.takeNodes(Pred); 1067 Pred = Bldr.generateNode(CNE, Pred, State); 1068 1069 SVal V = State->getSVal(Init, LCtx); 1070 ExplodedNodeSet evaluated; 1071 evalBind(evaluated, CNE, Pred, Result, V, true); 1072 1073 Bldr.takeNodes(Pred); 1074 Bldr.addNodes(evaluated); 1075 1076 Pred = *evaluated.begin(); 1077 State = Pred->getState(); 1078 } 1079 } 1080 1081 State = State->BindExpr(CNE, Pred->getLocationContext(), Result); 1082 Bldr.generateNode(CNE, Pred, State); 1083 return; 1084 } 1085 1086 // FIXME: Once we have proper support for CXXConstructExprs inside 1087 // CXXNewExpr, we need to make sure that the constructed object is not 1088 // immediately invalidated here. (The placement call should happen before 1089 // the constructor call anyway.) 1090 if (FD->isReservedGlobalPlacementOperator()) { 1091 // Non-array placement new should always return the placement location. 1092 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 1093 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), 1094 CNE->getPlacementArg(0)->getType()); 1095 } 1096 1097 // Bind the address of the object, then check to see if we cached out. 1098 State = State->BindExpr(CNE, LCtx, Result); 1099 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State); 1100 if (!NewN) 1101 return; 1102 1103 // If the type is not a record, we won't have a CXXConstructExpr as an 1104 // initializer. Copy the value over. 1105 if (const Expr *Init = CNE->getInitializer()) { 1106 if (!isa<CXXConstructExpr>(Init)) { 1107 assert(Bldr.getResults().size() == 1); 1108 Bldr.takeNodes(NewN); 1109 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx), 1110 /*FirstInit=*/IsStandardGlobalOpNewFunction); 1111 } 1112 } 1113 } 1114 1115 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 1116 ExplodedNode *Pred, ExplodedNodeSet &Dst) { 1117 1118 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 1119 CallEventRef<CXXDeallocatorCall> Call = CEMgr.getCXXDeallocatorCall( 1120 CDE, Pred->getState(), Pred->getLocationContext()); 1121 1122 ExplodedNodeSet DstPreCall; 1123 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this); 1124 ExplodedNodeSet DstPostCall; 1125 1126 if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) { 1127 StmtNodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx); 1128 for (ExplodedNode *I : DstPreCall) { 1129 defaultEvalCall(Bldr, I, *Call); 1130 } 1131 } else { 1132 DstPostCall = DstPreCall; 1133 } 1134 getCheckerManager().runCheckersForPostCall(Dst, DstPostCall, *Call, *this); 1135 } 1136 1137 void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, 1138 ExplodedNodeSet &Dst) { 1139 const VarDecl *VD = CS->getExceptionDecl(); 1140 if (!VD) { 1141 Dst.Add(Pred); 1142 return; 1143 } 1144 1145 const LocationContext *LCtx = Pred->getLocationContext(); 1146 SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(), 1147 currBldrCtx->blockCount()); 1148 ProgramStateRef state = Pred->getState(); 1149 state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx); 1150 1151 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 1152 Bldr.generateNode(CS, Pred, state); 1153 } 1154 1155 void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 1156 ExplodedNodeSet &Dst) { 1157 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 1158 1159 // Get the this object region from StoreManager. 1160 const LocationContext *LCtx = Pred->getLocationContext(); 1161 const MemRegion *R = 1162 svalBuilder.getRegionManager().getCXXThisRegion( 1163 getContext().getCanonicalType(TE->getType()), 1164 LCtx); 1165 1166 ProgramStateRef state = Pred->getState(); 1167 SVal V = state->getSVal(loc::MemRegionVal(R)); 1168 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 1169 } 1170 1171 void ExprEngine::VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, 1172 ExplodedNodeSet &Dst) { 1173 const LocationContext *LocCtxt = Pred->getLocationContext(); 1174 1175 // Get the region of the lambda itself. 1176 const MemRegion *R = svalBuilder.getRegionManager().getCXXTempObjectRegion( 1177 LE, LocCtxt); 1178 SVal V = loc::MemRegionVal(R); 1179 1180 ProgramStateRef State = Pred->getState(); 1181 1182 // If we created a new MemRegion for the lambda, we should explicitly bind 1183 // the captures. 1184 unsigned Idx = 0; 1185 CXXRecordDecl::field_iterator CurField = LE->getLambdaClass()->field_begin(); 1186 for (LambdaExpr::const_capture_init_iterator i = LE->capture_init_begin(), 1187 e = LE->capture_init_end(); 1188 i != e; ++i, ++CurField, ++Idx) { 1189 FieldDecl *FieldForCapture = *CurField; 1190 SVal FieldLoc = State->getLValue(FieldForCapture, V); 1191 1192 SVal InitVal; 1193 if (!FieldForCapture->hasCapturedVLAType()) { 1194 const Expr *InitExpr = *i; 1195 1196 assert(InitExpr && "Capture missing initialization expression"); 1197 1198 // Capturing a 0 length array is a no-op, so we ignore it to get a more 1199 // accurate analysis. If it's not ignored, it would set the default 1200 // binding of the lambda to 'Unknown', which can lead to falsely detecting 1201 // 'Uninitialized' values as 'Unknown' and not reporting a warning. 1202 const auto FTy = FieldForCapture->getType(); 1203 if (FTy->isConstantArrayType() && 1204 getContext().getConstantArrayElementCount( 1205 getContext().getAsConstantArrayType(FTy)) == 0) 1206 continue; 1207 1208 // With C++17 copy elision the InitExpr can be anything, so instead of 1209 // pattern matching all cases, we simple check if the current field is 1210 // under construction or not, regardless what it's InitExpr is. 1211 if (const auto OUC = 1212 getObjectUnderConstruction(State, {LE, Idx}, LocCtxt)) { 1213 InitVal = State->getSVal(OUC->getAsRegion()); 1214 1215 State = finishObjectConstruction(State, {LE, Idx}, LocCtxt); 1216 } else 1217 InitVal = State->getSVal(InitExpr, LocCtxt); 1218 1219 } else { 1220 1221 assert(!getObjectUnderConstruction(State, {LE, Idx}, LocCtxt) && 1222 "VLA capture by value is a compile time error!"); 1223 1224 // The field stores the length of a captured variable-length array. 1225 // These captures don't have initialization expressions; instead we 1226 // get the length from the VLAType size expression. 1227 Expr *SizeExpr = FieldForCapture->getCapturedVLAType()->getSizeExpr(); 1228 InitVal = State->getSVal(SizeExpr, LocCtxt); 1229 } 1230 1231 State = State->bindLoc(FieldLoc, InitVal, LocCtxt); 1232 } 1233 1234 // Decay the Loc into an RValue, because there might be a 1235 // MaterializeTemporaryExpr node above this one which expects the bound value 1236 // to be an RValue. 1237 SVal LambdaRVal = State->getSVal(R); 1238 1239 ExplodedNodeSet Tmp; 1240 StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx); 1241 // FIXME: is this the right program point kind? 1242 Bldr.generateNode(LE, Pred, 1243 State->BindExpr(LE, LocCtxt, LambdaRVal), 1244 nullptr, ProgramPoint::PostLValueKind); 1245 1246 // FIXME: Move all post/pre visits to ::Visit(). 1247 getCheckerManager().runCheckersForPostStmt(Dst, Tmp, LE, *this); 1248 } 1249