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/Basic/PrettyStackTrace.h" 18 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 19 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 20 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 21 22 using namespace clang; 23 using namespace ento; 24 25 void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 26 ExplodedNode *Pred, 27 ExplodedNodeSet &Dst) { 28 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 29 const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens(); 30 ProgramStateRef state = Pred->getState(); 31 const LocationContext *LCtx = Pred->getLocationContext(); 32 33 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME); 34 Bldr.generateNode(ME, Pred, state); 35 } 36 37 // FIXME: This is the sort of code that should eventually live in a Core 38 // checker rather than as a special case in ExprEngine. 39 void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 40 const CallEvent &Call) { 41 SVal ThisVal; 42 bool AlwaysReturnsLValue; 43 if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) { 44 assert(Ctor->getDecl()->isTrivial()); 45 assert(Ctor->getDecl()->isCopyOrMoveConstructor()); 46 ThisVal = Ctor->getCXXThisVal(); 47 AlwaysReturnsLValue = false; 48 } else { 49 assert(cast<CXXMethodDecl>(Call.getDecl())->isTrivial()); 50 assert(cast<CXXMethodDecl>(Call.getDecl())->getOverloadedOperator() == 51 OO_Equal); 52 ThisVal = cast<CXXInstanceCall>(Call).getCXXThisVal(); 53 AlwaysReturnsLValue = true; 54 } 55 56 const LocationContext *LCtx = Pred->getLocationContext(); 57 58 ExplodedNodeSet Dst; 59 Bldr.takeNodes(Pred); 60 61 SVal V = Call.getArgSVal(0); 62 63 // If the value being copied is not unknown, load from its location to get 64 // an aggregate rvalue. 65 if (Optional<Loc> L = V.getAs<Loc>()) 66 V = Pred->getState()->getSVal(*L); 67 else 68 assert(V.isUnknown()); 69 70 const Expr *CallExpr = Call.getOriginExpr(); 71 evalBind(Dst, CallExpr, Pred, ThisVal, V, true); 72 73 PostStmt PS(CallExpr, LCtx); 74 for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); 75 I != E; ++I) { 76 ProgramStateRef State = (*I)->getState(); 77 if (AlwaysReturnsLValue) 78 State = State->BindExpr(CallExpr, LCtx, ThisVal); 79 else 80 State = bindReturnValue(Call, LCtx, State); 81 Bldr.generateNode(PS, State, *I); 82 } 83 } 84 85 86 /// Returns a region representing the first element of a (possibly 87 /// multi-dimensional) array. 88 /// 89 /// On return, \p Ty will be set to the base type of the array. 90 /// 91 /// If the type is not an array type at all, the original value is returned. 92 static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue, 93 QualType &Ty) { 94 SValBuilder &SVB = State->getStateManager().getSValBuilder(); 95 ASTContext &Ctx = SVB.getContext(); 96 97 while (const ArrayType *AT = Ctx.getAsArrayType(Ty)) { 98 Ty = AT->getElementType(); 99 LValue = State->getLValue(Ty, SVB.makeZeroArrayIndex(), LValue); 100 } 101 102 return LValue; 103 } 104 105 106 static const MemRegion *getRegionForConstructedObject( 107 const CXXConstructExpr *CE, ExplodedNode *Pred, ExprEngine &Eng, 108 unsigned int CurrStmtIdx) { 109 const LocationContext *LCtx = Pred->getLocationContext(); 110 ProgramStateRef State = Pred->getState(); 111 const NodeBuilderContext &CurrBldrCtx = Eng.getBuilderContext(); 112 113 // See if we're constructing an existing region by looking at the next 114 // element in the CFG. 115 const CFGBlock *B = CurrBldrCtx.getBlock(); 116 unsigned int NextStmtIdx = CurrStmtIdx + 1; 117 if (NextStmtIdx < B->size()) { 118 CFGElement Next = (*B)[NextStmtIdx]; 119 120 // Is this a destructor? If so, we might be in the middle of an assignment 121 // to a local or member: look ahead one more element to see what we find. 122 while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) { 123 ++NextStmtIdx; 124 Next = (*B)[NextStmtIdx]; 125 } 126 127 // Is this a constructor for a local variable? 128 if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) { 129 if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) { 130 if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) { 131 if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) { 132 SVal LValue = State->getLValue(Var, LCtx); 133 QualType Ty = Var->getType(); 134 LValue = makeZeroElementRegion(State, LValue, Ty); 135 return LValue.getAsRegion(); 136 } 137 } 138 } 139 } 140 141 // Is this a constructor for a member? 142 if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) { 143 const CXXCtorInitializer *Init = InitElem->getInitializer(); 144 assert(Init->isAnyMemberInitializer()); 145 146 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 147 Loc ThisPtr = Eng.getSValBuilder().getCXXThis(CurCtor, 148 LCtx->getCurrentStackFrame()); 149 SVal ThisVal = State->getSVal(ThisPtr); 150 151 const ValueDecl *Field; 152 SVal FieldVal; 153 if (Init->isIndirectMemberInitializer()) { 154 Field = Init->getIndirectMember(); 155 FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal); 156 } else { 157 Field = Init->getMember(); 158 FieldVal = State->getLValue(Init->getMember(), ThisVal); 159 } 160 161 QualType Ty = Field->getType(); 162 FieldVal = makeZeroElementRegion(State, FieldVal, Ty); 163 return FieldVal.getAsRegion(); 164 } 165 166 // FIXME: This will eventually need to handle new-expressions as well. 167 // Don't forget to update the pre-constructor initialization code in 168 // ExprEngine::VisitCXXConstructExpr. 169 } 170 171 // If we couldn't find an existing region to construct into, assume we're 172 // constructing a temporary. 173 MemRegionManager &MRMgr = Eng.getSValBuilder().getRegionManager(); 174 return MRMgr.getCXXTempObjectRegion(CE, LCtx); 175 } 176 177 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 178 ExplodedNode *Pred, 179 ExplodedNodeSet &destNodes) { 180 const LocationContext *LCtx = Pred->getLocationContext(); 181 ProgramStateRef State = Pred->getState(); 182 183 const MemRegion *Target = nullptr; 184 185 // FIXME: Handle arrays, which run the same constructor for every element. 186 // For now, we just run the first constructor (which should still invalidate 187 // the entire array). 188 189 switch (CE->getConstructionKind()) { 190 case CXXConstructExpr::CK_Complete: { 191 Target = getRegionForConstructedObject(CE, Pred, *this, currStmtIdx); 192 break; 193 } 194 case CXXConstructExpr::CK_VirtualBase: 195 // Make sure we are not calling virtual base class initializers twice. 196 // Only the most-derived object should initialize virtual base classes. 197 if (const Stmt *Outer = LCtx->getCurrentStackFrame()->getCallSite()) { 198 const CXXConstructExpr *OuterCtor = dyn_cast<CXXConstructExpr>(Outer); 199 if (OuterCtor) { 200 switch (OuterCtor->getConstructionKind()) { 201 case CXXConstructExpr::CK_NonVirtualBase: 202 case CXXConstructExpr::CK_VirtualBase: 203 // Bail out! 204 destNodes.Add(Pred); 205 return; 206 case CXXConstructExpr::CK_Complete: 207 case CXXConstructExpr::CK_Delegating: 208 break; 209 } 210 } 211 } 212 // FALLTHROUGH 213 case CXXConstructExpr::CK_NonVirtualBase: 214 case CXXConstructExpr::CK_Delegating: { 215 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 216 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 217 LCtx->getCurrentStackFrame()); 218 SVal ThisVal = State->getSVal(ThisPtr); 219 220 if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) { 221 Target = ThisVal.getAsRegion(); 222 } else { 223 // Cast to the base type. 224 bool IsVirtual = 225 (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase); 226 SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(), 227 IsVirtual); 228 Target = BaseVal.getAsRegion(); 229 } 230 break; 231 } 232 } 233 234 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 235 CallEventRef<CXXConstructorCall> Call = 236 CEMgr.getCXXConstructorCall(CE, Target, State, LCtx); 237 238 ExplodedNodeSet DstPreVisit; 239 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this); 240 241 ExplodedNodeSet PreInitialized; 242 { 243 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx); 244 if (CE->requiresZeroInitialization()) { 245 // Type of the zero doesn't matter. 246 SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy); 247 248 for (ExplodedNodeSet::iterator I = DstPreVisit.begin(), 249 E = DstPreVisit.end(); 250 I != E; ++I) { 251 ProgramStateRef State = (*I)->getState(); 252 // FIXME: Once we properly handle constructors in new-expressions, we'll 253 // need to invalidate the region before setting a default value, to make 254 // sure there aren't any lingering bindings around. This probably needs 255 // to happen regardless of whether or not the object is zero-initialized 256 // to handle random fields of a placement-initialized object picking up 257 // old bindings. We might only want to do it when we need to, though. 258 // FIXME: This isn't actually correct for arrays -- we need to zero- 259 // initialize the entire array, not just the first element -- but our 260 // handling of arrays everywhere else is weak as well, so this shouldn't 261 // actually make things worse. Placement new makes this tricky as well, 262 // since it's then possible to be initializing one part of a multi- 263 // dimensional array. 264 State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal); 265 Bldr.generateNode(CE, *I, State, /*tag=*/nullptr, 266 ProgramPoint::PreStmtKind); 267 } 268 } 269 } 270 271 ExplodedNodeSet DstPreCall; 272 getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized, 273 *Call, *this); 274 275 ExplodedNodeSet DstEvaluated; 276 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx); 277 278 bool IsArray = isa<ElementRegion>(Target); 279 if (CE->getConstructor()->isTrivial() && 280 CE->getConstructor()->isCopyOrMoveConstructor() && 281 !IsArray) { 282 // FIXME: Handle other kinds of trivial constructors as well. 283 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 284 I != E; ++I) 285 performTrivialCopy(Bldr, *I, *Call); 286 287 } else { 288 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 289 I != E; ++I) 290 defaultEvalCall(Bldr, *I, *Call); 291 } 292 293 ExplodedNodeSet DstPostCall; 294 getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated, 295 *Call, *this); 296 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this); 297 } 298 299 void ExprEngine::VisitCXXDestructor(QualType ObjectType, 300 const MemRegion *Dest, 301 const Stmt *S, 302 bool IsBaseDtor, 303 ExplodedNode *Pred, 304 ExplodedNodeSet &Dst) { 305 const LocationContext *LCtx = Pred->getLocationContext(); 306 ProgramStateRef State = Pred->getState(); 307 308 // FIXME: We need to run the same destructor on every element of the array. 309 // This workaround will just run the first destructor (which will still 310 // invalidate the entire array). 311 SVal DestVal = UnknownVal(); 312 if (Dest) 313 DestVal = loc::MemRegionVal(Dest); 314 DestVal = makeZeroElementRegion(State, DestVal, ObjectType); 315 Dest = DestVal.getAsRegion(); 316 317 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); 318 assert(RecordDecl && "Only CXXRecordDecls should have destructors"); 319 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); 320 321 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 322 CallEventRef<CXXDestructorCall> Call = 323 CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); 324 325 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 326 Call->getSourceRange().getBegin(), 327 "Error evaluating destructor"); 328 329 ExplodedNodeSet DstPreCall; 330 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 331 *Call, *this); 332 333 ExplodedNodeSet DstInvalidated; 334 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 335 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 336 I != E; ++I) 337 defaultEvalCall(Bldr, *I, *Call); 338 339 ExplodedNodeSet DstPostCall; 340 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 341 *Call, *this); 342 } 343 344 void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, 345 ExplodedNode *Pred, 346 ExplodedNodeSet &Dst) { 347 ProgramStateRef State = Pred->getState(); 348 const LocationContext *LCtx = Pred->getLocationContext(); 349 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 350 CNE->getStartLoc(), 351 "Error evaluating New Allocator Call"); 352 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 353 CallEventRef<CXXAllocatorCall> Call = 354 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 355 356 ExplodedNodeSet DstPreCall; 357 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 358 *Call, *this); 359 360 ExplodedNodeSet DstInvalidated; 361 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 362 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 363 I != E; ++I) 364 defaultEvalCall(Bldr, *I, *Call); 365 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 366 *Call, *this); 367 } 368 369 370 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 371 ExplodedNodeSet &Dst) { 372 // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 373 // Also, we need to decide how allocators actually work -- they're not 374 // really part of the CXXNewExpr because they happen BEFORE the 375 // CXXConstructExpr subexpression. See PR12014 for some discussion. 376 377 unsigned blockCount = currBldrCtx->blockCount(); 378 const LocationContext *LCtx = Pred->getLocationContext(); 379 DefinedOrUnknownSVal symVal = UnknownVal(); 380 FunctionDecl *FD = CNE->getOperatorNew(); 381 382 bool IsStandardGlobalOpNewFunction = false; 383 if (FD && !isa<CXXMethodDecl>(FD) && !FD->isVariadic()) { 384 if (FD->getNumParams() == 2) { 385 QualType T = FD->getParamDecl(1)->getType(); 386 if (const IdentifierInfo *II = T.getBaseTypeIdentifier()) 387 // NoThrow placement new behaves as a standard new. 388 IsStandardGlobalOpNewFunction = II->getName().equals("nothrow_t"); 389 } 390 else 391 // Placement forms are considered non-standard. 392 IsStandardGlobalOpNewFunction = (FD->getNumParams() == 1); 393 } 394 395 // We assume all standard global 'operator new' functions allocate memory in 396 // heap. We realize this is an approximation that might not correctly model 397 // a custom global allocator. 398 if (IsStandardGlobalOpNewFunction) 399 symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount); 400 else 401 symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(), 402 blockCount); 403 404 ProgramStateRef State = Pred->getState(); 405 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 406 CallEventRef<CXXAllocatorCall> Call = 407 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 408 409 // Invalidate placement args. 410 // FIXME: Once we figure out how we want allocators to work, 411 // we should be using the usual pre-/(default-)eval-/post-call checks here. 412 State = Call->invalidateRegions(blockCount); 413 if (!State) 414 return; 415 416 // If this allocation function is not declared as non-throwing, failures 417 // /must/ be signalled by exceptions, and thus the return value will never be 418 // NULL. -fno-exceptions does not influence this semantics. 419 // FIXME: GCC has a -fcheck-new option, which forces it to consider the case 420 // where new can return NULL. If we end up supporting that option, we can 421 // consider adding a check for it here. 422 // C++11 [basic.stc.dynamic.allocation]p3. 423 if (FD) { 424 QualType Ty = FD->getType(); 425 if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>()) 426 if (!ProtoType->isNothrow(getContext())) 427 State = State->assume(symVal, true); 428 } 429 430 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 431 432 if (CNE->isArray()) { 433 // FIXME: allocating an array requires simulating the constructors. 434 // For now, just return a symbolicated region. 435 const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion(); 436 QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 437 const ElementRegion *EleReg = 438 getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 439 State = State->BindExpr(CNE, Pred->getLocationContext(), 440 loc::MemRegionVal(EleReg)); 441 Bldr.generateNode(CNE, Pred, State); 442 return; 443 } 444 445 // FIXME: Once we have proper support for CXXConstructExprs inside 446 // CXXNewExpr, we need to make sure that the constructed object is not 447 // immediately invalidated here. (The placement call should happen before 448 // the constructor call anyway.) 449 SVal Result = symVal; 450 if (FD && FD->isReservedGlobalPlacementOperator()) { 451 // Non-array placement new should always return the placement location. 452 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 453 Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), 454 CNE->getPlacementArg(0)->getType()); 455 } 456 457 // Bind the address of the object, then check to see if we cached out. 458 State = State->BindExpr(CNE, LCtx, Result); 459 ExplodedNode *NewN = Bldr.generateNode(CNE, Pred, State); 460 if (!NewN) 461 return; 462 463 // If the type is not a record, we won't have a CXXConstructExpr as an 464 // initializer. Copy the value over. 465 if (const Expr *Init = CNE->getInitializer()) { 466 if (!isa<CXXConstructExpr>(Init)) { 467 assert(Bldr.getResults().size() == 1); 468 Bldr.takeNodes(NewN); 469 evalBind(Dst, CNE, NewN, Result, State->getSVal(Init, LCtx), 470 /*FirstInit=*/IsStandardGlobalOpNewFunction); 471 } 472 } 473 } 474 475 void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 476 ExplodedNode *Pred, ExplodedNodeSet &Dst) { 477 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 478 ProgramStateRef state = Pred->getState(); 479 Bldr.generateNode(CDE, Pred, state); 480 } 481 482 void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 483 ExplodedNode *Pred, 484 ExplodedNodeSet &Dst) { 485 const VarDecl *VD = CS->getExceptionDecl(); 486 if (!VD) { 487 Dst.Add(Pred); 488 return; 489 } 490 491 const LocationContext *LCtx = Pred->getLocationContext(); 492 SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(), 493 currBldrCtx->blockCount()); 494 ProgramStateRef state = Pred->getState(); 495 state = state->bindLoc(state->getLValue(VD, LCtx), V); 496 497 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 498 Bldr.generateNode(CS, Pred, state); 499 } 500 501 void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 502 ExplodedNodeSet &Dst) { 503 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 504 505 // Get the this object region from StoreManager. 506 const LocationContext *LCtx = Pred->getLocationContext(); 507 const MemRegion *R = 508 svalBuilder.getRegionManager().getCXXThisRegion( 509 getContext().getCanonicalType(TE->getType()), 510 LCtx); 511 512 ProgramStateRef state = Pred->getState(); 513 SVal V = state->getSVal(loc::MemRegionVal(R)); 514 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 515 } 516