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