ExprEngineCXX.cpp revision eafb5c694cc5d165149fcb9453bc9355fb0d44a5
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 SVal V = state->getSVal(tempExpr, LCtx); 34 35 // If the value is already a CXXTempObjectRegion, it is fine as it is. 36 // Otherwise, create a new CXXTempObjectRegion, and copy the value into it. 37 // This is an optimization for when an rvalue is constructed and then 38 // immediately materialized. 39 const MemRegion *MR = V.getAsRegion(); 40 if (const CXXTempObjectRegion *TR = 41 dyn_cast_or_null<CXXTempObjectRegion>(MR)) { 42 if (getContext().hasSameUnqualifiedType(TR->getValueType(), ME->getType())) 43 state = state->BindExpr(ME, LCtx, V); 44 } 45 46 if (state == Pred->getState()) 47 state = createTemporaryRegionIfNeeded(state, LCtx, tempExpr, ME); 48 Bldr.generateNode(ME, Pred, state); 49} 50 51void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred, 52 const CXXConstructorCall &Call) { 53 const CXXConstructExpr *CtorExpr = Call.getOriginExpr(); 54 assert(CtorExpr->getConstructor()->isCopyOrMoveConstructor()); 55 assert(CtorExpr->getConstructor()->isTrivial()); 56 57 SVal ThisVal = Call.getCXXThisVal(); 58 const LocationContext *LCtx = Pred->getLocationContext(); 59 60 ExplodedNodeSet Dst; 61 Bldr.takeNodes(Pred); 62 63 SVal V = Call.getArgSVal(0); 64 65 // Make sure the value being copied is not unknown. 66 if (Optional<Loc> L = V.getAs<Loc>()) 67 V = Pred->getState()->getSVal(*L); 68 69 evalBind(Dst, CtorExpr, Pred, ThisVal, V, true); 70 71 PostStmt PS(CtorExpr, LCtx); 72 for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); 73 I != E; ++I) { 74 ProgramStateRef State = (*I)->getState(); 75 State = bindReturnValue(Call, LCtx, State); 76 Bldr.generateNode(PS, State, *I); 77 } 78} 79 80void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 81 ExplodedNode *Pred, 82 ExplodedNodeSet &destNodes) { 83 const LocationContext *LCtx = Pred->getLocationContext(); 84 ProgramStateRef State = Pred->getState(); 85 86 const MemRegion *Target = 0; 87 bool IsArray = false; 88 89 switch (CE->getConstructionKind()) { 90 case CXXConstructExpr::CK_Complete: { 91 // See if we're constructing an existing region by looking at the next 92 // element in the CFG. 93 const CFGBlock *B = currBldrCtx->getBlock(); 94 if (currStmtIdx + 1 < B->size()) { 95 CFGElement Next = (*B)[currStmtIdx+1]; 96 97 // Is this a constructor for a local variable? 98 if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) { 99 if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) { 100 if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) { 101 if (Var->getInit()->IgnoreImplicit() == CE) { 102 QualType Ty = Var->getType(); 103 if (const ArrayType *AT = getContext().getAsArrayType(Ty)) { 104 // FIXME: Handle arrays, which run the same constructor for 105 // every element. This workaround will just run the first 106 // constructor (which should still invalidate the entire array). 107 SVal Base = State->getLValue(Var, LCtx); 108 Target = State->getLValue(AT->getElementType(), 109 getSValBuilder().makeZeroArrayIndex(), 110 Base).getAsRegion(); 111 IsArray = true; 112 } else { 113 Target = State->getLValue(Var, LCtx).getAsRegion(); 114 } 115 } 116 } 117 } 118 } 119 120 // Is this a constructor for a member? 121 if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) { 122 const CXXCtorInitializer *Init = InitElem->getInitializer(); 123 assert(Init->isAnyMemberInitializer()); 124 125 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 126 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 127 LCtx->getCurrentStackFrame()); 128 SVal ThisVal = State->getSVal(ThisPtr); 129 130 if (Init->isIndirectMemberInitializer()) { 131 SVal Field = State->getLValue(Init->getIndirectMember(), ThisVal); 132 Target = Field.getAsRegion(); 133 } else { 134 SVal Field = State->getLValue(Init->getMember(), ThisVal); 135 Target = Field.getAsRegion(); 136 } 137 } 138 139 // FIXME: This will eventually need to handle new-expressions as well. 140 } 141 142 // If we couldn't find an existing region to construct into, assume we're 143 // constructing a temporary. 144 if (!Target) { 145 MemRegionManager &MRMgr = getSValBuilder().getRegionManager(); 146 Target = MRMgr.getCXXTempObjectRegion(CE, LCtx); 147 } 148 149 break; 150 } 151 case CXXConstructExpr::CK_NonVirtualBase: 152 case CXXConstructExpr::CK_VirtualBase: 153 case CXXConstructExpr::CK_Delegating: { 154 const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl()); 155 Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor, 156 LCtx->getCurrentStackFrame()); 157 SVal ThisVal = State->getSVal(ThisPtr); 158 159 if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) { 160 Target = ThisVal.getAsRegion(); 161 } else { 162 // Cast to the base type. 163 bool IsVirtual = 164 (CE->getConstructionKind() == CXXConstructExpr::CK_VirtualBase); 165 SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, CE->getType(), 166 IsVirtual); 167 Target = BaseVal.getAsRegion(); 168 } 169 break; 170 } 171 } 172 173 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 174 CallEventRef<CXXConstructorCall> Call = 175 CEMgr.getCXXConstructorCall(CE, Target, State, LCtx); 176 177 ExplodedNodeSet DstPreVisit; 178 getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this); 179 ExplodedNodeSet DstPreCall; 180 getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit, 181 *Call, *this); 182 183 ExplodedNodeSet DstEvaluated; 184 StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx); 185 186 if (CE->getConstructor()->isTrivial() && 187 CE->getConstructor()->isCopyOrMoveConstructor() && 188 !IsArray) { 189 // FIXME: Handle other kinds of trivial constructors as well. 190 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 191 I != E; ++I) 192 performTrivialCopy(Bldr, *I, *Call); 193 194 } else { 195 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 196 I != E; ++I) 197 defaultEvalCall(Bldr, *I, *Call); 198 } 199 200 ExplodedNodeSet DstPostCall; 201 getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated, 202 *Call, *this); 203 getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this); 204} 205 206void ExprEngine::VisitCXXDestructor(QualType ObjectType, 207 const MemRegion *Dest, 208 const Stmt *S, 209 bool IsBaseDtor, 210 ExplodedNode *Pred, 211 ExplodedNodeSet &Dst) { 212 const LocationContext *LCtx = Pred->getLocationContext(); 213 ProgramStateRef State = Pred->getState(); 214 215 // FIXME: We need to run the same destructor on every element of the array. 216 // This workaround will just run the first destructor (which will still 217 // invalidate the entire array). 218 // This is a loop because of multidimensional arrays. 219 while (const ArrayType *AT = getContext().getAsArrayType(ObjectType)) { 220 ObjectType = AT->getElementType(); 221 Dest = State->getLValue(ObjectType, getSValBuilder().makeZeroArrayIndex(), 222 loc::MemRegionVal(Dest)).getAsRegion(); 223 } 224 225 const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl(); 226 assert(RecordDecl && "Only CXXRecordDecls should have destructors"); 227 const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor(); 228 229 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 230 CallEventRef<CXXDestructorCall> Call = 231 CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, IsBaseDtor, State, LCtx); 232 233 PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(), 234 Call->getSourceRange().getBegin(), 235 "Error evaluating destructor"); 236 237 ExplodedNodeSet DstPreCall; 238 getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 239 *Call, *this); 240 241 ExplodedNodeSet DstInvalidated; 242 StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx); 243 for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 244 I != E; ++I) 245 defaultEvalCall(Bldr, *I, *Call); 246 247 ExplodedNodeSet DstPostCall; 248 getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 249 *Call, *this); 250} 251 252void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 253 ExplodedNodeSet &Dst) { 254 // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 255 // Also, we need to decide how allocators actually work -- they're not 256 // really part of the CXXNewExpr because they happen BEFORE the 257 // CXXConstructExpr subexpression. See PR12014 for some discussion. 258 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 259 260 unsigned blockCount = currBldrCtx->blockCount(); 261 const LocationContext *LCtx = Pred->getLocationContext(); 262 DefinedOrUnknownSVal symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, 263 CNE->getType(), 264 blockCount); 265 ProgramStateRef State = Pred->getState(); 266 267 CallEventManager &CEMgr = getStateManager().getCallEventManager(); 268 CallEventRef<CXXAllocatorCall> Call = 269 CEMgr.getCXXAllocatorCall(CNE, State, LCtx); 270 271 // Invalidate placement args. 272 // FIXME: Once we figure out how we want allocators to work, 273 // we should be using the usual pre-/(default-)eval-/post-call checks here. 274 State = Call->invalidateRegions(blockCount); 275 276 // If we're compiling with exceptions enabled, and this allocation function 277 // is not declared as non-throwing, failures /must/ be signalled by 278 // exceptions, and thus the return value will never be NULL. 279 // C++11 [basic.stc.dynamic.allocation]p3. 280 FunctionDecl *FD = CNE->getOperatorNew(); 281 if (FD && getContext().getLangOpts().CXXExceptions) { 282 QualType Ty = FD->getType(); 283 if (const FunctionProtoType *ProtoType = Ty->getAs<FunctionProtoType>()) 284 if (!ProtoType->isNothrow(getContext())) 285 State = State->assume(symVal, true); 286 } 287 288 if (CNE->isArray()) { 289 // FIXME: allocating an array requires simulating the constructors. 290 // For now, just return a symbolicated region. 291 const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion(); 292 QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 293 const ElementRegion *EleReg = 294 getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 295 State = State->BindExpr(CNE, Pred->getLocationContext(), 296 loc::MemRegionVal(EleReg)); 297 Bldr.generateNode(CNE, Pred, State); 298 return; 299 } 300 301 // FIXME: Once we have proper support for CXXConstructExprs inside 302 // CXXNewExpr, we need to make sure that the constructed object is not 303 // immediately invalidated here. (The placement call should happen before 304 // the constructor call anyway.) 305 if (FD && FD->isReservedGlobalPlacementOperator()) { 306 // Non-array placement new should always return the placement location. 307 SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 308 SVal Result = svalBuilder.evalCast(PlacementLoc, CNE->getType(), 309 CNE->getPlacementArg(0)->getType()); 310 State = State->BindExpr(CNE, LCtx, Result); 311 } else { 312 State = State->BindExpr(CNE, LCtx, symVal); 313 } 314 315 // If the type is not a record, we won't have a CXXConstructExpr as an 316 // initializer. Copy the value over. 317 if (const Expr *Init = CNE->getInitializer()) { 318 if (!isa<CXXConstructExpr>(Init)) { 319 QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 320 (void)ObjTy; 321 assert(!ObjTy->isRecordType()); 322 SVal Location = State->getSVal(CNE, LCtx); 323 if (Optional<Loc> LV = Location.getAs<Loc>()) 324 State = State->bindLoc(*LV, State->getSVal(Init, LCtx)); 325 } 326 } 327 328 Bldr.generateNode(CNE, Pred, State); 329} 330 331void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 332 ExplodedNode *Pred, ExplodedNodeSet &Dst) { 333 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 334 ProgramStateRef state = Pred->getState(); 335 Bldr.generateNode(CDE, Pred, state); 336} 337 338void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 339 ExplodedNode *Pred, 340 ExplodedNodeSet &Dst) { 341 const VarDecl *VD = CS->getExceptionDecl(); 342 if (!VD) { 343 Dst.Add(Pred); 344 return; 345 } 346 347 const LocationContext *LCtx = Pred->getLocationContext(); 348 SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(), 349 currBldrCtx->blockCount()); 350 ProgramStateRef state = Pred->getState(); 351 state = state->bindLoc(state->getLValue(VD, LCtx), V); 352 353 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 354 Bldr.generateNode(CS, Pred, state); 355} 356 357void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 358 ExplodedNodeSet &Dst) { 359 StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); 360 361 // Get the this object region from StoreManager. 362 const LocationContext *LCtx = Pred->getLocationContext(); 363 const MemRegion *R = 364 svalBuilder.getRegionManager().getCXXThisRegion( 365 getContext().getCanonicalType(TE->getType()), 366 LCtx); 367 368 ProgramStateRef state = Pred->getState(); 369 SVal V = state->getSVal(loc::MemRegionVal(R)); 370 Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 371} 372