ExprEngineCXX.cpp 20 KB

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