110e25031STed Kremenek //===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===// 210e25031STed Kremenek // 310e25031STed Kremenek // The LLVM Compiler Infrastructure 410e25031STed Kremenek // 510e25031STed Kremenek // This file is distributed under the University of Illinois Open Source 610e25031STed Kremenek // License. See LICENSE.TXT for details. 710e25031STed Kremenek // 810e25031STed Kremenek //===----------------------------------------------------------------------===// 910e25031STed Kremenek // 1010e25031STed Kremenek // This file defines the C++ expression evaluation engine. 1110e25031STed Kremenek // 1210e25031STed Kremenek //===----------------------------------------------------------------------===// 1310e25031STed Kremenek 1410e25031STed Kremenek #include "clang/StaticAnalyzer/Core/CheckerManager.h" 1510e25031STed Kremenek #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 1610e25031STed Kremenek #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 17087611edSJordy Rose #include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" 1810e25031STed Kremenek #include "clang/AST/DeclCXX.h" 198fdb59f9STed Kremenek #include "clang/AST/StmtCXX.h" 2010e25031STed Kremenek 2110e25031STed Kremenek using namespace clang; 2210e25031STed Kremenek using namespace ento; 2310e25031STed Kremenek 2410e25031STed Kremenek const CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXRecordDecl *D, 2510e25031STed Kremenek const StackFrameContext *SFC) { 2610e25031STed Kremenek const Type *T = D->getTypeForDecl(); 2710e25031STed Kremenek QualType PT = getContext().getPointerType(QualType(T, 0)); 2810e25031STed Kremenek return svalBuilder.getRegionManager().getCXXThisRegion(PT, SFC); 2910e25031STed Kremenek } 3010e25031STed Kremenek 3110e25031STed Kremenek const CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXMethodDecl *decl, 3210e25031STed Kremenek const StackFrameContext *frameCtx) { 3310e25031STed Kremenek return svalBuilder.getRegionManager(). 3410e25031STed Kremenek getCXXThisRegion(decl->getThisType(getContext()), frameCtx); 3510e25031STed Kremenek } 3610e25031STed Kremenek 3710e25031STed Kremenek void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 3810e25031STed Kremenek ExplodedNode *Pred, 3910e25031STed Kremenek ExplodedNodeSet &Dst) { 40e4e5712cSAnna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 412a14c695STed Kremenek const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens(); 4249b1e38eSTed Kremenek ProgramStateRef state = Pred->getState(); 43632e3b7eSTed Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 4410e25031STed Kremenek 4510e25031STed Kremenek // Bind the temporary object to the value of the expression. Then bind 4610e25031STed Kremenek // the expression to the location of the object. 47632e3b7eSTed Kremenek SVal V = state->getSVal(tempExpr, Pred->getLocationContext()); 4810e25031STed Kremenek 4910e25031STed Kremenek const MemRegion *R = 50632e3b7eSTed Kremenek svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, LCtx); 5110e25031STed Kremenek 5210e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(R), V); 53632e3b7eSTed Kremenek Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, loc::MemRegionVal(R))); 5410e25031STed Kremenek } 5510e25031STed Kremenek 5611764ab4SBenjamin Kramer void ExprEngine::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr, 5711764ab4SBenjamin Kramer ExplodedNode *Pred, 5811764ab4SBenjamin Kramer ExplodedNodeSet &Dst) { 5911764ab4SBenjamin Kramer VisitCXXConstructExpr(expr, 0, Pred, Dst); 6011764ab4SBenjamin Kramer } 6111764ab4SBenjamin Kramer 6210e25031STed Kremenek void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, 6310e25031STed Kremenek const MemRegion *Dest, 6410e25031STed Kremenek ExplodedNode *Pred, 6510e25031STed Kremenek ExplodedNodeSet &destNodes) { 6610e25031STed Kremenek 67be84d859SMatt Beaumont-Gay #if 0 6810e25031STed Kremenek const CXXConstructorDecl *CD = E->getConstructor(); 6910e25031STed Kremenek assert(CD); 70be84d859SMatt Beaumont-Gay #endif 7110e25031STed Kremenek 7210e25031STed Kremenek #if 0 7310e25031STed Kremenek if (!(CD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) 7410e25031STed Kremenek // FIXME: invalidate the object. 7510e25031STed Kremenek return; 7610e25031STed Kremenek #endif 7710e25031STed Kremenek 7810e25031STed Kremenek #if 0 7910e25031STed Kremenek // Is the constructor elidable? 8010e25031STed Kremenek if (E->isElidable()) { 8110e25031STed Kremenek destNodes.Add(Pred); 8210e25031STed Kremenek return; 8310e25031STed Kremenek } 8410e25031STed Kremenek #endif 8510e25031STed Kremenek 8610e25031STed Kremenek // Perform the previsit of the constructor. 87fe66dd62SErik Verbruggen ExplodedNodeSet SrcNodes; 88fe66dd62SErik Verbruggen SrcNodes.Add(Pred); 89fe66dd62SErik Verbruggen ExplodedNodeSet TmpNodes; 90fe66dd62SErik Verbruggen getCheckerManager().runCheckersForPreStmt(TmpNodes, SrcNodes, E, *this); 9110e25031STed Kremenek 9210e25031STed Kremenek // Evaluate the constructor. Currently we don't now allow checker-specific 9310e25031STed Kremenek // implementations of specific constructors (as we do with ordinary 9410e25031STed Kremenek // function calls. We can re-evaluate this in the future. 9510e25031STed Kremenek 9610e25031STed Kremenek #if 0 9710e25031STed Kremenek // Inlining currently isn't fully implemented. 9810e25031STed Kremenek 9910e25031STed Kremenek if (AMgr.shouldInlineCall()) { 10010e25031STed Kremenek if (!Dest) 10110e25031STed Kremenek Dest = 10210e25031STed Kremenek svalBuilder.getRegionManager().getCXXTempObjectRegion(E, 10310e25031STed Kremenek Pred->getLocationContext()); 10410e25031STed Kremenek 10510e25031STed Kremenek // The callee stack frame context used to create the 'this' 10610e25031STed Kremenek // parameter region. 10710e25031STed Kremenek const StackFrameContext *SFC = 10810e25031STed Kremenek AMgr.getStackFrame(CD, Pred->getLocationContext(), 109e594034fSAnna Zaks E, currentBuilderContext->getBlock(), 110e594034fSAnna Zaks currentStmtIdx); 11110e25031STed Kremenek 11210e25031STed Kremenek // Create the 'this' region. 11310e25031STed Kremenek const CXXThisRegion *ThisR = 11410e25031STed Kremenek getCXXThisRegion(E->getConstructor()->getParent(), SFC); 11510e25031STed Kremenek 11610e25031STed Kremenek CallEnter Loc(E, SFC, Pred->getLocationContext()); 11710e25031STed Kremenek 118fe66dd62SErik Verbruggen StmtNodeBuilder Bldr(SrcNodes, TmpNodes, *currentBuilderContext); 119fe66dd62SErik Verbruggen for (ExplodedNodeSet::iterator NI = SrcNodes.begin(), 120fe66dd62SErik Verbruggen NE = SrcNodes.end(); NI != NE; ++NI) { 12149b1e38eSTed Kremenek ProgramStateRef state = (*NI)->getState(); 12210e25031STed Kremenek // Setup 'this' region, so that the ctor is evaluated on the object pointed 12310e25031STed Kremenek // by 'Dest'. 12410e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); 125e594034fSAnna Zaks Bldr.generateNode(Loc, *NI, state); 12610e25031STed Kremenek } 12710e25031STed Kremenek } 12810e25031STed Kremenek #endif 12910e25031STed Kremenek 13010e25031STed Kremenek // Default semantics: invalidate all regions passed as arguments. 13110e25031STed Kremenek ExplodedNodeSet destCall; 132e594034fSAnna Zaks { 133fe66dd62SErik Verbruggen StmtNodeBuilder Bldr(TmpNodes, destCall, *currentBuilderContext); 134fe66dd62SErik Verbruggen for (ExplodedNodeSet::iterator i = TmpNodes.begin(), e = TmpNodes.end(); 13510e25031STed Kremenek i != e; ++i) 13610e25031STed Kremenek { 13710e25031STed Kremenek ExplodedNode *Pred = *i; 138d188d66eSJordy Rose const LocationContext *LC = Pred->getLocationContext(); 13949b1e38eSTed Kremenek ProgramStateRef state = Pred->getState(); 14010e25031STed Kremenek 141632e3b7eSTed Kremenek state = invalidateArguments(state, CallOrObjCMessage(E, state, LC), LC); 142e594034fSAnna Zaks Bldr.generateNode(E, Pred, state); 14310e25031STed Kremenek } 144e594034fSAnna Zaks } 14510e25031STed Kremenek // Do the post visit. 14610e25031STed Kremenek getCheckerManager().runCheckersForPostStmt(destNodes, destCall, E, *this); 14710e25031STed Kremenek } 14810e25031STed Kremenek 14910e25031STed Kremenek void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD, 15010e25031STed Kremenek const MemRegion *Dest, 15110e25031STed Kremenek const Stmt *S, 15210e25031STed Kremenek ExplodedNode *Pred, 15310e25031STed Kremenek ExplodedNodeSet &Dst) { 154e4e5712cSAnna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 15510e25031STed Kremenek if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) 15610e25031STed Kremenek return; 157142adc49STed Kremenek 15810e25031STed Kremenek // Create the context for 'this' region. 159142adc49STed Kremenek const StackFrameContext *SFC = 16081ce1c8aSTed Kremenek AnalysisDeclContexts.getContext(DD)-> 161142adc49STed Kremenek getStackFrame(Pred->getLocationContext(), S, 162e594034fSAnna Zaks currentBuilderContext->getBlock(), currentStmtIdx); 16310e25031STed Kremenek 16410e25031STed Kremenek const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC); 16510e25031STed Kremenek 16610e25031STed Kremenek CallEnter PP(S, SFC, Pred->getLocationContext()); 16710e25031STed Kremenek 16849b1e38eSTed Kremenek ProgramStateRef state = Pred->getState(); 16910e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); 170e594034fSAnna Zaks Bldr.generateNode(PP, Pred, state); 17110e25031STed Kremenek } 17210e25031STed Kremenek 173*44320367SJordan Rose static bool isPointerToConst(const ParmVarDecl *ParamDecl) { 174*44320367SJordan Rose // FIXME: Copied from ExprEngineCallAndReturn.cpp 175*44320367SJordan Rose QualType PointeeTy = ParamDecl->getOriginalType()->getPointeeType(); 176*44320367SJordan Rose if (PointeeTy != QualType() && PointeeTy.isConstQualified() && 177*44320367SJordan Rose !PointeeTy->isAnyPointerType() && !PointeeTy->isReferenceType()) { 178*44320367SJordan Rose return true; 179*44320367SJordan Rose } 180*44320367SJordan Rose return false; 181*44320367SJordan Rose } 182*44320367SJordan Rose 18310e25031STed Kremenek void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 18410e25031STed Kremenek ExplodedNodeSet &Dst) { 185e4e5712cSAnna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 18610e25031STed Kremenek 187e594034fSAnna Zaks unsigned blockCount = currentBuilderContext->getCurrentBlockCount(); 188d519cae8STed Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 18910e25031STed Kremenek DefinedOrUnknownSVal symVal = 190d519cae8STed Kremenek svalBuilder.getConjuredSymbolVal(NULL, CNE, LCtx, CNE->getType(), blockCount); 19110e25031STed Kremenek const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion(); 19210e25031STed Kremenek QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 19310e25031STed Kremenek const ElementRegion *EleReg = 19410e25031STed Kremenek getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 195*44320367SJordan Rose ProgramStateRef State = Pred->getState(); 19610e25031STed Kremenek 19710e25031STed Kremenek if (CNE->isArray()) { 19810e25031STed Kremenek // FIXME: allocating an array requires simulating the constructors. 19910e25031STed Kremenek // For now, just return a symbolicated region. 200*44320367SJordan Rose State = State->BindExpr(CNE, Pred->getLocationContext(), 201632e3b7eSTed Kremenek loc::MemRegionVal(EleReg)); 202*44320367SJordan Rose Bldr.generateNode(CNE, Pred, State); 20310e25031STed Kremenek return; 20410e25031STed Kremenek } 20510e25031STed Kremenek 206*44320367SJordan Rose FunctionDecl *FD = CNE->getOperatorNew(); 207*44320367SJordan Rose if (FD && FD->isReservedGlobalPlacementOperator()) { 208*44320367SJordan Rose // Non-array placement new should always return the placement location. 209*44320367SJordan Rose SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 210*44320367SJordan Rose State = State->BindExpr(CNE, LCtx, PlacementLoc); 211*44320367SJordan Rose // FIXME: Once we have proper support for CXXConstructExprs inside 212*44320367SJordan Rose // CXXNewExpr, we need to make sure that the constructed object is not 213*44320367SJordan Rose // immediately invalidated here. (The placement call should happen before 214*44320367SJordan Rose // the constructor call anyway.) 215*44320367SJordan Rose } 216*44320367SJordan Rose 217*44320367SJordan Rose // Invalidate placement args. 218*44320367SJordan Rose 219*44320367SJordan Rose // FIXME: This is largely copied from invalidateArguments, because 220*44320367SJordan Rose // CallOrObjCMessage is not general enough to handle new-expressions yet. 221*44320367SJordan Rose SmallVector<const MemRegion *, 4> RegionsToInvalidate; 222*44320367SJordan Rose 223*44320367SJordan Rose unsigned Index = 0; 224*44320367SJordan Rose for (CXXNewExpr::const_arg_iterator I = CNE->placement_arg_begin(), 225*44320367SJordan Rose E = CNE->placement_arg_end(); 226*44320367SJordan Rose I != E; ++I) { 227*44320367SJordan Rose // Pre-increment the argument index to skip over the implicit size arg. 228*44320367SJordan Rose ++Index; 229*44320367SJordan Rose if (FD && Index < FD->getNumParams()) 230*44320367SJordan Rose if (isPointerToConst(FD->getParamDecl(Index))) 231*44320367SJordan Rose continue; 232*44320367SJordan Rose 233*44320367SJordan Rose SVal V = State->getSVal(*I, LCtx); 234*44320367SJordan Rose 235*44320367SJordan Rose // If we are passing a location wrapped as an integer, unwrap it and 236*44320367SJordan Rose // invalidate the values referred by the location. 237*44320367SJordan Rose if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V)) 238*44320367SJordan Rose V = Wrapped->getLoc(); 239*44320367SJordan Rose else if (!isa<Loc>(V)) 240*44320367SJordan Rose continue; 241*44320367SJordan Rose 242*44320367SJordan Rose if (const MemRegion *R = V.getAsRegion()) { 243*44320367SJordan Rose // Invalidate the value of the variable passed by reference. 244*44320367SJordan Rose 245*44320367SJordan Rose // Are we dealing with an ElementRegion? If the element type is 246*44320367SJordan Rose // a basic integer type (e.g., char, int) and the underlying region 247*44320367SJordan Rose // is a variable region then strip off the ElementRegion. 248*44320367SJordan Rose // FIXME: We really need to think about this for the general case 249*44320367SJordan Rose // as sometimes we are reasoning about arrays and other times 250*44320367SJordan Rose // about (char*), etc., is just a form of passing raw bytes. 251*44320367SJordan Rose // e.g., void *p = alloca(); foo((char*)p); 252*44320367SJordan Rose if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { 253*44320367SJordan Rose // Checking for 'integral type' is probably too promiscuous, but 254*44320367SJordan Rose // we'll leave it in for now until we have a systematic way of 255*44320367SJordan Rose // handling all of these cases. Eventually we need to come up 256*44320367SJordan Rose // with an interface to StoreManager so that this logic can be 257*44320367SJordan Rose // appropriately delegated to the respective StoreManagers while 258*44320367SJordan Rose // still allowing us to do checker-specific logic (e.g., 259*44320367SJordan Rose // invalidating reference counts), probably via callbacks. 260*44320367SJordan Rose if (ER->getElementType()->isIntegralOrEnumerationType()) { 261*44320367SJordan Rose const MemRegion *superReg = ER->getSuperRegion(); 262*44320367SJordan Rose if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) || 263*44320367SJordan Rose isa<ObjCIvarRegion>(superReg)) 264*44320367SJordan Rose R = cast<TypedRegion>(superReg); 265*44320367SJordan Rose } 266*44320367SJordan Rose // FIXME: What about layers of ElementRegions? 267*44320367SJordan Rose } 268*44320367SJordan Rose 269*44320367SJordan Rose // Mark this region for invalidation. We batch invalidate regions 270*44320367SJordan Rose // below for efficiency. 271*44320367SJordan Rose RegionsToInvalidate.push_back(R); 272*44320367SJordan Rose } else { 273*44320367SJordan Rose // Nuke all other arguments passed by reference. 274*44320367SJordan Rose // FIXME: is this necessary or correct? This handles the non-Region 275*44320367SJordan Rose // cases. Is it ever valid to store to these? 276*44320367SJordan Rose State = State->unbindLoc(cast<Loc>(V)); 277*44320367SJordan Rose } 278*44320367SJordan Rose } 279*44320367SJordan Rose 280*44320367SJordan Rose // Invalidate designated regions using the batch invalidation API. 281*44320367SJordan Rose 282*44320367SJordan Rose // FIXME: We can have collisions on the conjured symbol if the 283*44320367SJordan Rose // expression *I also creates conjured symbols. We probably want 284*44320367SJordan Rose // to identify conjured symbols by an expression pair: the enclosing 285*44320367SJordan Rose // expression (the context) and the expression itself. This should 286*44320367SJordan Rose // disambiguate conjured symbols. 287*44320367SJordan Rose unsigned Count = currentBuilderContext->getCurrentBlockCount(); 288*44320367SJordan Rose 289*44320367SJordan Rose // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate 290*44320367SJordan Rose // global variables. 291*44320367SJordan Rose State = State->invalidateRegions(RegionsToInvalidate, CNE, Count, LCtx); 292*44320367SJordan Rose Bldr.generateNode(CNE, Pred, State); 293*44320367SJordan Rose return; 294*44320367SJordan Rose 295*44320367SJordan Rose // FIXME: The below code is long-since dead. However, constructor handling 296*44320367SJordan Rose // in new-expressions is far from complete. See PR12014 for more details. 2976047f07eSSebastian Redl #if 0 29810e25031STed Kremenek // Evaluate constructor arguments. 29910e25031STed Kremenek const FunctionProtoType *FnType = NULL; 30010e25031STed Kremenek const CXXConstructorDecl *CD = CNE->getConstructor(); 30110e25031STed Kremenek if (CD) 30210e25031STed Kremenek FnType = CD->getType()->getAs<FunctionProtoType>(); 30310e25031STed Kremenek ExplodedNodeSet argsEvaluated; 304e594034fSAnna Zaks Bldr.takeNodes(Pred); 30510e25031STed Kremenek evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(), 30610e25031STed Kremenek FnType, Pred, argsEvaluated); 307e594034fSAnna Zaks Bldr.addNodes(argsEvaluated); 30810e25031STed Kremenek 30910e25031STed Kremenek // Initialize the object region and bind the 'new' expression. 31010e25031STed Kremenek for (ExplodedNodeSet::iterator I = argsEvaluated.begin(), 31110e25031STed Kremenek E = argsEvaluated.end(); I != E; ++I) { 31210e25031STed Kremenek 31349b1e38eSTed Kremenek ProgramStateRef state = (*I)->getState(); 31410e25031STed Kremenek 31510e25031STed Kremenek // Accumulate list of regions that are invalidated. 31610e25031STed Kremenek // FIXME: Eventually we should unify the logic for constructor 31710e25031STed Kremenek // processing in one place. 31810e25031STed Kremenek SmallVector<const MemRegion*, 10> regionsToInvalidate; 31910e25031STed Kremenek for (CXXNewExpr::const_arg_iterator 32010e25031STed Kremenek ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end(); 32110e25031STed Kremenek ai != ae; ++ai) 32210e25031STed Kremenek { 323632e3b7eSTed Kremenek SVal val = state->getSVal(*ai, (*I)->getLocationContext()); 32410e25031STed Kremenek if (const MemRegion *region = val.getAsRegion()) 32510e25031STed Kremenek regionsToInvalidate.push_back(region); 32610e25031STed Kremenek } 32710e25031STed Kremenek 32810e25031STed Kremenek if (ObjTy->isRecordType()) { 32910e25031STed Kremenek regionsToInvalidate.push_back(EleReg); 33010e25031STed Kremenek // Invalidate the regions. 3318158ef0dSAnna Zaks // TODO: Pass the call to new information as the last argument, to limit 3328158ef0dSAnna Zaks // the globals which will get invalidated. 3331fad6631SJordy Rose state = state->invalidateRegions(regionsToInvalidate, 3348158ef0dSAnna Zaks CNE, blockCount, 0, 0); 33510e25031STed Kremenek 33610e25031STed Kremenek } else { 33710e25031STed Kremenek // Invalidate the regions. 3388158ef0dSAnna Zaks // TODO: Pass the call to new information as the last argument, to limit 3398158ef0dSAnna Zaks // the globals which will get invalidated. 3401fad6631SJordy Rose state = state->invalidateRegions(regionsToInvalidate, 3418158ef0dSAnna Zaks CNE, blockCount, 0, 0); 34210e25031STed Kremenek 34310e25031STed Kremenek if (CNE->hasInitializer()) { 344632e3b7eSTed Kremenek SVal V = state->getSVal(*CNE->constructor_arg_begin(), 345632e3b7eSTed Kremenek (*I)->getLocationContext()); 34610e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(EleReg), V); 34710e25031STed Kremenek } else { 34810e25031STed Kremenek // Explicitly set to undefined, because currently we retrieve symbolic 34910e25031STed Kremenek // value from symbolic region. 35010e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal()); 35110e25031STed Kremenek } 35210e25031STed Kremenek } 353632e3b7eSTed Kremenek state = state->BindExpr(CNE, (*I)->getLocationContext(), 354632e3b7eSTed Kremenek loc::MemRegionVal(EleReg)); 355e594034fSAnna Zaks Bldr.generateNode(CNE, *I, state); 35610e25031STed Kremenek } 3576047f07eSSebastian Redl #endif 35810e25031STed Kremenek } 35910e25031STed Kremenek 36010e25031STed Kremenek void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 36110e25031STed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst) { 36264aea652SErik Verbruggen StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 36364aea652SErik Verbruggen ProgramStateRef state = Pred->getState(); 36464aea652SErik Verbruggen Bldr.generateNode(CDE, Pred, state); 36510e25031STed Kremenek } 36610e25031STed Kremenek 3678fdb59f9STed Kremenek void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 3688fdb59f9STed Kremenek ExplodedNode *Pred, 3698fdb59f9STed Kremenek ExplodedNodeSet &Dst) { 3708fdb59f9STed Kremenek const VarDecl *VD = CS->getExceptionDecl(); 371b1279b5cSTed Kremenek if (!VD) { 372b1279b5cSTed Kremenek Dst.Add(Pred); 373b1279b5cSTed Kremenek return; 374b1279b5cSTed Kremenek } 375b1279b5cSTed Kremenek 3768fdb59f9STed Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 3778fdb59f9STed Kremenek SVal V = svalBuilder.getConjuredSymbolVal(CS, LCtx, VD->getType(), 3788fdb59f9STed Kremenek currentBuilderContext->getCurrentBlockCount()); 3798fdb59f9STed Kremenek ProgramStateRef state = Pred->getState(); 3808fdb59f9STed Kremenek state = state->bindLoc(state->getLValue(VD, LCtx), V); 3818fdb59f9STed Kremenek 3828fdb59f9STed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 3838fdb59f9STed Kremenek Bldr.generateNode(CS, Pred, state); 3848fdb59f9STed Kremenek } 3858fdb59f9STed Kremenek 38610e25031STed Kremenek void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 38710e25031STed Kremenek ExplodedNodeSet &Dst) { 388e4e5712cSAnna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 389e594034fSAnna Zaks 39010e25031STed Kremenek // Get the this object region from StoreManager. 391632e3b7eSTed Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 39210e25031STed Kremenek const MemRegion *R = 39310e25031STed Kremenek svalBuilder.getRegionManager().getCXXThisRegion( 39410e25031STed Kremenek getContext().getCanonicalType(TE->getType()), 395632e3b7eSTed Kremenek LCtx); 39610e25031STed Kremenek 39749b1e38eSTed Kremenek ProgramStateRef state = Pred->getState(); 39810e25031STed Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 399632e3b7eSTed Kremenek Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 40010e25031STed Kremenek } 401