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" 17742920c8SJordan Rose #include "clang/StaticAnalyzer/Core/PathSensitive/Calls.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 void ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 2510e25031STed Kremenek ExplodedNode *Pred, 2610e25031STed Kremenek ExplodedNodeSet &Dst) { 27e4e5712cSAnna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 282a14c695STed Kremenek const Expr *tempExpr = ME->GetTemporaryExpr()->IgnoreParens(); 2949b1e38eSTed Kremenek ProgramStateRef state = Pred->getState(); 30632e3b7eSTed Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 3110e25031STed Kremenek 3210e25031STed Kremenek // Bind the temporary object to the value of the expression. Then bind 3310e25031STed Kremenek // the expression to the location of the object. 34632e3b7eSTed Kremenek SVal V = state->getSVal(tempExpr, Pred->getLocationContext()); 3510e25031STed Kremenek 3610e25031STed Kremenek const MemRegion *R = 37632e3b7eSTed Kremenek svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, LCtx); 3810e25031STed Kremenek 3910e25031STed Kremenek state = state->bindLoc(loc::MemRegionVal(R), V); 40632e3b7eSTed Kremenek Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, loc::MemRegionVal(R))); 4110e25031STed Kremenek } 4210e25031STed Kremenek 4311764ab4SBenjamin Kramer void ExprEngine::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *expr, 4411764ab4SBenjamin Kramer ExplodedNode *Pred, 4511764ab4SBenjamin Kramer ExplodedNodeSet &Dst) { 4611764ab4SBenjamin Kramer VisitCXXConstructExpr(expr, 0, Pred, Dst); 4711764ab4SBenjamin Kramer } 4811764ab4SBenjamin Kramer 49f3c12ac3SJordan Rose void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE, 5010e25031STed Kremenek const MemRegion *Dest, 5110e25031STed Kremenek ExplodedNode *Pred, 5210e25031STed Kremenek ExplodedNodeSet &destNodes) { 53f3c12ac3SJordan Rose CXXConstructorCall Call(CE, Dest, Pred->getState(), 5410e25031STed Kremenek Pred->getLocationContext()); 5510e25031STed Kremenek 56f3c12ac3SJordan Rose ExplodedNodeSet DstPreVisit; 57f3c12ac3SJordan Rose getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this); 58afe7c2c2SJordan Rose ExplodedNodeSet DstPreCall; 59afe7c2c2SJordan Rose getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit, 60afe7c2c2SJordan Rose Call, *this); 6110e25031STed Kremenek 62f3c12ac3SJordan Rose ExplodedNodeSet DstInvalidated; 63afe7c2c2SJordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 64f3c12ac3SJordan Rose I != E; ++I) 65f3c12ac3SJordan Rose defaultEvalCall(DstInvalidated, *I, Call); 6610e25031STed Kremenek 67afe7c2c2SJordan Rose ExplodedNodeSet DstPostCall; 68afe7c2c2SJordan Rose getCheckerManager().runCheckersForPostCall(DstPostCall, DstInvalidated, 69afe7c2c2SJordan Rose Call, *this); 70afe7c2c2SJordan Rose getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this); 7110e25031STed Kremenek } 7210e25031STed Kremenek 7310e25031STed Kremenek void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD, 7410e25031STed Kremenek const MemRegion *Dest, 7510e25031STed Kremenek const Stmt *S, 7610e25031STed Kremenek ExplodedNode *Pred, 7710e25031STed Kremenek ExplodedNodeSet &Dst) { 78*4ee71b8aSJordan Rose CXXDestructorCall Call(DD, S, Dest, Pred->getState(), 79*4ee71b8aSJordan Rose Pred->getLocationContext()); 80142adc49STed Kremenek 81*4ee71b8aSJordan Rose ExplodedNodeSet DstPreCall; 82*4ee71b8aSJordan Rose getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, 83*4ee71b8aSJordan Rose Call, *this); 8410e25031STed Kremenek 85*4ee71b8aSJordan Rose ExplodedNodeSet DstInvalidated; 86*4ee71b8aSJordan Rose for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end(); 87*4ee71b8aSJordan Rose I != E; ++I) 88*4ee71b8aSJordan Rose defaultEvalCall(DstInvalidated, *I, Call); 89*4ee71b8aSJordan Rose 90*4ee71b8aSJordan Rose ExplodedNodeSet DstPostCall; 91*4ee71b8aSJordan Rose getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated, 92*4ee71b8aSJordan Rose Call, *this); 9310e25031STed Kremenek } 9410e25031STed Kremenek 9510e25031STed Kremenek void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 9610e25031STed Kremenek ExplodedNodeSet &Dst) { 97a4ee064cSJordan Rose // FIXME: Much of this should eventually migrate to CXXAllocatorCall. 98a4ee064cSJordan Rose // Also, we need to decide how allocators actually work -- they're not 99a4ee064cSJordan Rose // really part of the CXXNewExpr because they happen BEFORE the 100a4ee064cSJordan Rose // CXXConstructExpr subexpression. See PR12014 for some discussion. 101e4e5712cSAnna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 10210e25031STed Kremenek 103e594034fSAnna Zaks unsigned blockCount = currentBuilderContext->getCurrentBlockCount(); 104d519cae8STed Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 10510e25031STed Kremenek DefinedOrUnknownSVal symVal = 106a4ee064cSJordan Rose svalBuilder.getConjuredSymbolVal(0, CNE, LCtx, CNE->getType(), blockCount); 10744320367SJordan Rose ProgramStateRef State = Pred->getState(); 10810e25031STed Kremenek 109a4ee064cSJordan Rose // Invalidate placement args. 110a4ee064cSJordan Rose CXXAllocatorCall Call(CNE, State, LCtx); 111a4ee064cSJordan Rose State = Call.invalidateRegions(blockCount); 112a4ee064cSJordan Rose 11310e25031STed Kremenek if (CNE->isArray()) { 11410e25031STed Kremenek // FIXME: allocating an array requires simulating the constructors. 11510e25031STed Kremenek // For now, just return a symbolicated region. 116a4ee064cSJordan Rose const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion(); 117a4ee064cSJordan Rose QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 118a4ee064cSJordan Rose const ElementRegion *EleReg = 119a4ee064cSJordan Rose getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 12044320367SJordan Rose State = State->BindExpr(CNE, Pred->getLocationContext(), 121632e3b7eSTed Kremenek loc::MemRegionVal(EleReg)); 12244320367SJordan Rose Bldr.generateNode(CNE, Pred, State); 12310e25031STed Kremenek return; 12410e25031STed Kremenek } 12510e25031STed Kremenek 126a4ee064cSJordan Rose // FIXME: Once we have proper support for CXXConstructExprs inside 127a4ee064cSJordan Rose // CXXNewExpr, we need to make sure that the constructed object is not 128a4ee064cSJordan Rose // immediately invalidated here. (The placement call should happen before 129a4ee064cSJordan Rose // the constructor call anyway.) 13044320367SJordan Rose FunctionDecl *FD = CNE->getOperatorNew(); 13144320367SJordan Rose if (FD && FD->isReservedGlobalPlacementOperator()) { 13244320367SJordan Rose // Non-array placement new should always return the placement location. 13344320367SJordan Rose SVal PlacementLoc = State->getSVal(CNE->getPlacementArg(0), LCtx); 13444320367SJordan Rose State = State->BindExpr(CNE, LCtx, PlacementLoc); 13544320367SJordan Rose } else { 136a4ee064cSJordan Rose State = State->BindExpr(CNE, LCtx, symVal); 13744320367SJordan Rose } 13844320367SJordan Rose 13944320367SJordan Rose Bldr.generateNode(CNE, Pred, State); 14010e25031STed Kremenek } 14110e25031STed Kremenek 14210e25031STed Kremenek void ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 14310e25031STed Kremenek ExplodedNode *Pred, ExplodedNodeSet &Dst) { 14464aea652SErik Verbruggen StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 14564aea652SErik Verbruggen ProgramStateRef state = Pred->getState(); 14664aea652SErik Verbruggen Bldr.generateNode(CDE, Pred, state); 14710e25031STed Kremenek } 14810e25031STed Kremenek 1498fdb59f9STed Kremenek void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, 1508fdb59f9STed Kremenek ExplodedNode *Pred, 1518fdb59f9STed Kremenek ExplodedNodeSet &Dst) { 1528fdb59f9STed Kremenek const VarDecl *VD = CS->getExceptionDecl(); 153b1279b5cSTed Kremenek if (!VD) { 154b1279b5cSTed Kremenek Dst.Add(Pred); 155b1279b5cSTed Kremenek return; 156b1279b5cSTed Kremenek } 157b1279b5cSTed Kremenek 1588fdb59f9STed Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 1598fdb59f9STed Kremenek SVal V = svalBuilder.getConjuredSymbolVal(CS, LCtx, VD->getType(), 1608fdb59f9STed Kremenek currentBuilderContext->getCurrentBlockCount()); 1618fdb59f9STed Kremenek ProgramStateRef state = Pred->getState(); 1628fdb59f9STed Kremenek state = state->bindLoc(state->getLValue(VD, LCtx), V); 1638fdb59f9STed Kremenek 1648fdb59f9STed Kremenek StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 1658fdb59f9STed Kremenek Bldr.generateNode(CS, Pred, state); 1668fdb59f9STed Kremenek } 1678fdb59f9STed Kremenek 16810e25031STed Kremenek void ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 16910e25031STed Kremenek ExplodedNodeSet &Dst) { 170e4e5712cSAnna Zaks StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext); 171e594034fSAnna Zaks 17210e25031STed Kremenek // Get the this object region from StoreManager. 173632e3b7eSTed Kremenek const LocationContext *LCtx = Pred->getLocationContext(); 17410e25031STed Kremenek const MemRegion *R = 17510e25031STed Kremenek svalBuilder.getRegionManager().getCXXThisRegion( 17610e25031STed Kremenek getContext().getCanonicalType(TE->getType()), 177632e3b7eSTed Kremenek LCtx); 17810e25031STed Kremenek 17949b1e38eSTed Kremenek ProgramStateRef state = Pred->getState(); 18010e25031STed Kremenek SVal V = state->getSVal(loc::MemRegionVal(R)); 181632e3b7eSTed Kremenek Bldr.generateNode(TE, Pred, state->BindExpr(TE, LCtx, V)); 18210e25031STed Kremenek } 183