r205328 - [analyzer] Extract a helper for finding the target region for a C++ constructor.

Jordan Rose jordan_rose at apple.com
Tue Apr 1 09:40:06 PDT 2014


Author: jrose
Date: Tue Apr  1 11:40:06 2014
New Revision: 205328

URL: http://llvm.org/viewvc/llvm-project?rev=205328&view=rev
Log:
[analyzer] Extract a helper for finding the target region for a C++ constructor.

No functionality change.

Patch by Alex McCarthy!

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=205328&r1=205327&r2=205328&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Tue Apr  1 11:40:06 2014
@@ -102,6 +102,70 @@ static SVal makeZeroElementRegion(Progra
   return LValue;
 }
 
+
+static const MemRegion *getRegionForConstructedObject(
+    const CXXConstructExpr *CE, ExplodedNode *Pred, ExprEngine &Eng,
+    unsigned int CurrStmtIdx) {
+  const LocationContext *LCtx = Pred->getLocationContext();
+  ProgramStateRef State = Pred->getState();
+  const NodeBuilderContext &CurrBldrCtx = Eng.getBuilderContext();
+
+  // See if we're constructing an existing region by looking at the next
+  // element in the CFG.
+  const CFGBlock *B = CurrBldrCtx.getBlock();
+  if (CurrStmtIdx + 1 < B->size()) {
+    CFGElement Next = (*B)[CurrStmtIdx+1];
+
+    // Is this a constructor for a local variable?
+    if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
+      if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
+        if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
+          if (Var->getInit()->IgnoreImplicit() == CE) {
+            SVal LValue = State->getLValue(Var, LCtx);
+            QualType Ty = Var->getType();
+            LValue = makeZeroElementRegion(State, LValue, Ty);
+            return LValue.getAsRegion();
+          }
+        }
+      }
+    }
+
+    // Is this a constructor for a member?
+    if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
+      const CXXCtorInitializer *Init = InitElem->getInitializer();
+      assert(Init->isAnyMemberInitializer());
+
+      const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
+      Loc ThisPtr = Eng.getSValBuilder().getCXXThis(CurCtor,
+          LCtx->getCurrentStackFrame());
+      SVal ThisVal = State->getSVal(ThisPtr);
+
+      const ValueDecl *Field;
+      SVal FieldVal;
+      if (Init->isIndirectMemberInitializer()) {
+        Field = Init->getIndirectMember();
+        FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
+      } else {
+        Field = Init->getMember();
+        FieldVal = State->getLValue(Init->getMember(), ThisVal);
+      }
+
+      QualType Ty = Field->getType();
+      FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
+      return FieldVal.getAsRegion();
+    }
+
+    // FIXME: This will eventually need to handle new-expressions as well.
+    // Don't forget to update the pre-constructor initialization code in
+    // ExprEngine::VisitCXXConstructExpr.
+  }
+
+  // If we couldn't find an existing region to construct into, assume we're
+  // constructing a temporary.
+  MemRegionManager &MRMgr = Eng.getSValBuilder().getRegionManager();
+  return MRMgr.getCXXTempObjectRegion(CE, LCtx);
+}
+
 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
                                        ExplodedNode *Pred,
                                        ExplodedNodeSet &destNodes) {
@@ -116,62 +180,7 @@ void ExprEngine::VisitCXXConstructExpr(c
 
   switch (CE->getConstructionKind()) {
   case CXXConstructExpr::CK_Complete: {
-    // See if we're constructing an existing region by looking at the next
-    // element in the CFG.
-    const CFGBlock *B = currBldrCtx->getBlock();
-    if (currStmtIdx + 1 < B->size()) {
-      CFGElement Next = (*B)[currStmtIdx+1];
-
-      // Is this a constructor for a local variable?
-      if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
-        if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
-          if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
-            if (Var->getInit()->IgnoreImplicit() == CE) {
-              SVal LValue = State->getLValue(Var, LCtx);
-              QualType Ty = Var->getType();
-              LValue = makeZeroElementRegion(State, LValue, Ty);
-              Target = LValue.getAsRegion();
-            }
-          }
-        }
-      }
-      
-      // Is this a constructor for a member?
-      if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
-        const CXXCtorInitializer *Init = InitElem->getInitializer();
-        assert(Init->isAnyMemberInitializer());
-
-        const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
-        Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
-                                                  LCtx->getCurrentStackFrame());
-        SVal ThisVal = State->getSVal(ThisPtr);
-
-        const ValueDecl *Field;
-        SVal FieldVal;
-        if (Init->isIndirectMemberInitializer()) {
-          Field = Init->getIndirectMember();
-          FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
-        } else {
-          Field = Init->getMember();
-          FieldVal = State->getLValue(Init->getMember(), ThisVal);
-        }
-
-        QualType Ty = Field->getType();
-        FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
-        Target = FieldVal.getAsRegion();
-      }
-
-      // FIXME: This will eventually need to handle new-expressions as well.
-      // Don't forget to update the pre-constructor initialization code below.
-    }
-
-    // If we couldn't find an existing region to construct into, assume we're
-    // constructing a temporary.
-    if (!Target) {
-      MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
-      Target = MRMgr.getCXXTempObjectRegion(CE, LCtx);
-    }
-
+    Target = getRegionForConstructedObject(CE, Pred, *this, currStmtIdx);
     break;
   }
   case CXXConstructExpr::CK_VirtualBase:





More information about the cfe-commits mailing list