ExprEngineCXX.cpp revision d1e5a89226da79f7e6f43d40facc46abda9e5245
17ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//===- ExprEngineCXX.cpp - ExprEngine support for C++ -----------*- C++ -*-===// 27ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 37ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// The LLVM Compiler Infrastructure 47ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 57ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// This file is distributed under the University of Illinois Open Source 67ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// License. See LICENSE.TXT for details. 77ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 87ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//===----------------------------------------------------------------------===// 97ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 107ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// This file defines the C++ expression evaluation engine. 117ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 127ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman//===----------------------------------------------------------------------===// 137ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 147ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/StaticAnalyzer/Core/CheckerManager.h" 157ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 167ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" 177ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" 187ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include "clang/AST/DeclCXX.h" 197ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 207ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanusing namespace clang; 217ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanusing namespace ento; 227ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 237ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmannamespace { 247ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanclass CallExprWLItem { 257ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanpublic: 267ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman CallExpr::const_arg_iterator I; 277ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman ExplodedNode *N; 287ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 297ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n) 307ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman : I(i), N(n) {} 317ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman}; 32b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad} 337ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 347ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanvoid ExprEngine::evalArguments(ConstExprIterator AI, ConstExprIterator AE, 357ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const FunctionProtoType *FnType, 367ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman ExplodedNode *Pred, ExplodedNodeSet &Dst, 37b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad bool FstArgAsLValue) { 387ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 39190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 40b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad SmallVector<CallExprWLItem, 20> WorkList; 41190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer WorkList.reserve(AE - AI); 42b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad WorkList.push_back(CallExprWLItem(AI, Pred)); 43b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad 44e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer while (!WorkList.empty()) { 45b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad CallExprWLItem Item = WorkList.back(); 46190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer WorkList.pop_back(); 47e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 48190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer if (Item.I == AE) { 49b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad Dst.insert(Item.N); 50b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad continue; 51b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad } 52190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 537ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Evaluate the argument. 54b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad ExplodedNodeSet Tmp; 55b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad if (FstArgAsLValue) { 56b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad FstArgAsLValue = false; 57b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad } 587ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 59e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Visit(*Item.I, Item.N, Tmp); 60e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ++(Item.I); 61e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI) 62e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer WorkList.push_back(CallExprWLItem(Item.I, *NI)); 63e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 64e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer} 65e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 66e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::evalCallee(const CallExpr *callExpr, 677ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const ExplodedNodeSet &src, 687ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman ExplodedNodeSet &dest) { 697ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 707ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const Expr *callee = 0; 71190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 72190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer switch (callExpr->getStmtClass()) { 7357240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer case Stmt::CXXMemberCallExprClass: { 74e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Evaluate the implicit object argument that is the recipient of the 75e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // call. 7657240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer callee = cast<CXXMemberCallExpr>(callExpr)->getImplicitObjectArgument(); 77e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 78190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer // FIXME: handle member pointers. 79190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer if (!callee) 80190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer return; 81190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 82190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer break; 83190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer } 84190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer default: { 85190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer callee = callExpr->getCallee()->IgnoreParens(); 86190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer break; 87190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer } 88190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer } 89190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 90190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer for (ExplodedNodeSet::iterator i = src.begin(), e = src.end(); i != e; ++i) 91190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer Visit(callee, *i, dest); 92190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer} 93190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 94190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramerconst CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXRecordDecl *D, 95190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer const StackFrameContext *SFC) { 96190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer const Type *T = D->getTypeForDecl(); 97190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer QualType PT = getContext().getPointerType(QualType(T, 0)); 98190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer return svalBuilder.getRegionManager().getCXXThisRegion(PT, SFC); 99190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer} 100190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 101190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramerconst CXXThisRegion *ExprEngine::getCXXThisRegion(const CXXMethodDecl *decl, 102190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer const StackFrameContext *frameCtx) { 103190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer return svalBuilder.getRegionManager(). 104190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer getCXXThisRegion(decl->getThisType(getContext()), frameCtx); 105190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer} 106190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 107190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramervoid ExprEngine::CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, 108190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer ExplodedNode *Pred, 109190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer ExplodedNodeSet &Dst) { 110e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNodeSet Tmp; 111e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Visit(ME->GetTemporaryExpr(), Pred, Tmp); 1127ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) { 1137ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const ProgramState *state = (*I)->getState(); 1147ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1157ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Bind the temporary object to the value of the expression. Then bind 11657240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // the expression to the location of the object. 11757240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer SVal V = state->getSVal(ME->GetTemporaryExpr()); 11857240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer 11957240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer const MemRegion *R = 12057240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer svalBuilder.getRegionManager().getCXXTempObjectRegion(ME, 12157240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer Pred->getLocationContext()); 12257240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer 12357240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer state = state->bindLoc(loc::MemRegionVal(R), V); 1247ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman MakeNode(Dst, ME, Pred, state->BindExpr(ME, loc::MemRegionVal(R))); 1257ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 1267ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman} 1277ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1287ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanvoid ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, 1297ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const MemRegion *Dest, 1307ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman ExplodedNode *Pred, 1317ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman ExplodedNodeSet &destNodes) { 1327ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1337ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const CXXConstructorDecl *CD = E->getConstructor(); 1347ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman assert(CD); 1357ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1367ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#if 0 1377ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman if (!(CD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) 1387ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // FIXME: invalidate the object. 1397ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman return; 1407ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#endif 1417ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1427ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Evaluate other arguments. 1437ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman ExplodedNodeSet argsEvaluated; 1447ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman const FunctionProtoType *FnType = CD->getType()->getAs<FunctionProtoType>(); 1457ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman evalArguments(E->arg_begin(), E->arg_end(), FnType, Pred, argsEvaluated); 146190f8ee25a6977ac6eb71b816498df42f17ad9a7Benjamin Kramer 1477ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#if 0 1487ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Is the constructor elidable? 1497ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman if (E->isElidable()) { 1507ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman VisitAggExpr(E->getArg(0), destNodes, Pred, Dst); 1517ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // FIXME: this is here to force propagation if VisitAggExpr doesn't 1527ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman if (destNodes.empty()) 1537ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman destNodes.Add(Pred); 1547ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman return; 1557ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 1567ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#endif 1577ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1587ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Perform the previsit of the constructor. 159e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNodeSet destPreVisit; 160e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer getCheckerManager().runCheckersForPreStmt(destPreVisit, argsEvaluated, E, 161e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer *this); 162e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 16357240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // Evaluate the constructor. Currently we don't now allow checker-specific 16457240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // implementations of specific constructors (as we do with ordinary 16557240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer // function calls. We can re-evaluate this in the future. 16657240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer 1677ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#if 0 1687ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Inlining currently isn't fully implemented. 1697ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 1707ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman if (AMgr.shouldInlineCall()) { 1717ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman if (!Dest) 1727ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman Dest = 1737ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman svalBuilder.getRegionManager().getCXXTempObjectRegion(E, 174e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Pred->getLocationContext()); 175e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 176e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // The callee stack frame context used to create the 'this' 177e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // parameter region. 178e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const StackFrameContext *SFC = 179e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer AMgr.getStackFrame(CD, Pred->getLocationContext(), 180e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer E, Builder->getBlock(), Builder->getIndex()); 181e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 182e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Create the 'this' region. 183e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const CXXThisRegion *ThisR = 184e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer getCXXThisRegion(E->getConstructor()->getParent(), SFC); 185b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad 186b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad CallEnter Loc(E, SFC, Pred->getLocationContext()); 187e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 188e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 189e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer for (ExplodedNodeSet::iterator NI = argsEvaluated.begin(), 190b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad NE = argsEvaluated.end(); NI != NE; ++NI) { 191b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad const ProgramState *state = (*NI)->getState(); 192e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Setup 'this' region, so that the ctor is evaluated on the object pointed 193e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // by 'Dest'. 194e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); 195e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer if (ExplodedNode *N = Builder->generateNode(Loc, state, *NI)) 196e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer destNodes.Add(N); 197e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 198b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad } 199e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer#endif 200e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 201e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Default semantics: invalidate all regions passed as arguments. 202e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNodeSet destCall; 203e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 204e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer for (ExplodedNodeSet::iterator 205e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer i = destPreVisit.begin(), e = destPreVisit.end(); 206b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad i != e; ++i) 207b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad { 208e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNode *Pred = *i; 209e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const LocationContext *LC = Pred->getLocationContext(); 210e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const ProgramState *state = Pred->getState(); 211b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad 212b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad state = invalidateArguments(state, CallOrObjCMessage(E, state), LC); 213e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Builder->MakeNode(destCall, E, Pred, state); 214e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 215b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad 216b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad // Do the post visit. 217e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer getCheckerManager().runCheckersForPostStmt(destNodes, destCall, E, *this); 218b33f8e3e55932d0e15a686ef0c598da8dbc37acdJay Foad} 219e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 220e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD, 221e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const MemRegion *Dest, 222e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const Stmt *S, 223e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNode *Pred, 224e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNodeSet &Dst) { 225e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer if (!(DD->doesThisDeclarationHaveABody() && AMgr.shouldInlineCall())) 226e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer return; 227e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Create the context for 'this' region. 228e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const StackFrameContext *SFC = AMgr.getStackFrame(DD, 229e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Pred->getLocationContext(), 230e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer S, Builder->getBlock(), 231e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Builder->getIndex()); 232e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 233e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const CXXThisRegion *ThisR = getCXXThisRegion(DD->getParent(), SFC); 234e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 235e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer CallEnter PP(S, SFC, Pred->getLocationContext()); 236e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 237e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const ProgramState *state = Pred->getState(); 238e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer state = state->bindLoc(loc::MemRegionVal(ThisR), loc::MemRegionVal(Dest)); 239e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNode *N = Builder->generateNode(PP, state, Pred); 240e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer if (N) 241e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Dst.Add(N); 242e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer} 243e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 244e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, 245e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNodeSet &Dst) { 246e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 247e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer unsigned blockCount = Builder->getCurrentBlockCount(); 248e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer DefinedOrUnknownSVal symVal = 249e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), blockCount); 250e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion(); 251e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); 252e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const ElementRegion *EleReg = 253e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer getStoreManager().GetElementZeroRegion(NewReg, ObjTy); 254e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 255e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer if (CNE->isArray()) { 256e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // FIXME: allocating an array requires simulating the constructors. 257e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // For now, just return a symbolicated region. 258e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const ProgramState *state = Pred->getState(); 259e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer state = state->BindExpr(CNE, loc::MemRegionVal(EleReg)); 260e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer MakeNode(Dst, CNE, Pred, state); 261e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer return; 262e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 263e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 264e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Evaluate constructor arguments. 265e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const FunctionProtoType *FnType = NULL; 266e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const CXXConstructorDecl *CD = CNE->getConstructor(); 267e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer if (CD) 268e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer FnType = CD->getType()->getAs<FunctionProtoType>(); 269e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNodeSet argsEvaluated; 270e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer evalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(), 271e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer FnType, Pred, argsEvaluated); 272e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 273e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Initialize the object region and bind the 'new' expression. 274e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer for (ExplodedNodeSet::iterator I = argsEvaluated.begin(), 275e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer E = argsEvaluated.end(); I != E; ++I) { 276e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 277e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const ProgramState *state = (*I)->getState(); 278e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 279e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Accumulate list of regions that are invalidated. 280e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // FIXME: Eventually we should unify the logic for constructor 281e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // processing in one place. 282e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer SmallVector<const MemRegion*, 10> regionsToInvalidate; 283e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer for (CXXNewExpr::const_arg_iterator 284e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end(); 285e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ai != ae; ++ai) 286e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer { 287e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer SVal val = state->getSVal(*ai); 288e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer if (const MemRegion *region = val.getAsRegion()) 289e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer regionsToInvalidate.push_back(region); 290e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 291e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 292e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer if (ObjTy->isRecordType()) { 293e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer regionsToInvalidate.push_back(EleReg); 294e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Invalidate the regions. 295e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer state = state->invalidateRegions(regionsToInvalidate, 296e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer CNE, blockCount, 0, 297e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer /* invalidateGlobals = */ true); 298e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 299e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } else { 300e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Invalidate the regions. 301e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer state = state->invalidateRegions(regionsToInvalidate, 302e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer CNE, blockCount, 0, 303e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer /* invalidateGlobals = */ true); 304e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 305e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer if (CNE->hasInitializer()) { 306e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer SVal V = state->getSVal(*CNE->constructor_arg_begin()); 307e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer state = state->bindLoc(loc::MemRegionVal(EleReg), V); 308e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } else { 309e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Explicitly set to undefined, because currently we retrieve symbolic 310e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // value from symbolic region. 311e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal()); 312e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 313e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 314e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer state = state->BindExpr(CNE, loc::MemRegionVal(EleReg)); 315e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer MakeNode(Dst, CNE, *I, state); 316e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 317e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer} 318e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 319e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, 320e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNode *Pred,ExplodedNodeSet &Dst) { 321e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Should do more checking. 322e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNodeSet Argevaluated; 323e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Visit(CDE->getArgument(), Pred, Argevaluated); 324e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer for (ExplodedNodeSet::iterator I = Argevaluated.begin(), 325e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer E = Argevaluated.end(); I != E; ++I) { 326e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const ProgramState *state = (*I)->getState(); 327e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer MakeNode(Dst, CDE, *I, state); 328e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer } 329e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer} 330e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 331e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramervoid ExprEngine::VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 332e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer ExplodedNodeSet &Dst) { 333e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer // Get the this object region from StoreManager. 334e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const MemRegion *R = 335e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer svalBuilder.getRegionManager().getCXXThisRegion( 336e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer getContext().getCanonicalType(TE->getType()), 337e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer Pred->getLocationContext()); 338e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer 339e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer const ProgramState *state = Pred->getState(); 340e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer SVal V = state->getSVal(loc::MemRegionVal(R)); 341e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer MakeNode(Dst, TE, Pred, state->BindExpr(TE, V)); 342e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer} 343e4b9c93fc1b531fe0cfe25a042f6b81c1e7c15c0Benjamin Kramer