[cfe-commits] r101862 - in /cfe/trunk: include/clang/Checker/PathSensitive/GRExprEngine.h lib/Checker/GRCXXExprEngine.cpp

Zhongxing Xu xuzhongxing at gmail.com
Mon Apr 19 20:37:34 PDT 2010


Author: zhongxingxu
Date: Mon Apr 19 22:37:34 2010
New Revision: 101862

URL: http://llvm.org/viewvc/llvm-project?rev=101862&view=rev
Log:
Improve handling of CXXNewExpr.

Modified:
    cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
    cfe/trunk/lib/Checker/GRCXXExprEngine.cpp

Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h?rev=101862&r1=101861&r2=101862&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h Mon Apr 19 22:37:34 2010
@@ -375,6 +375,11 @@
   const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *MD,
                                         const StackFrameContext *SFC);
 
+  /// Evaluate arguments with a work list algorithm.
+  void EvalArguments(ExprIterator AI, ExprIterator AE,
+                     const FunctionProtoType *FnType, 
+                     ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
   /// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
   ///  expressions of the form 'x != 0' and generate new nodes (stored in Dst)
   ///  with those assumptions.

Modified: cfe/trunk/lib/Checker/GRCXXExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRCXXExprEngine.cpp?rev=101862&r1=101861&r2=101862&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRCXXExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRCXXExprEngine.cpp Mon Apr 19 22:37:34 2010
@@ -17,6 +17,37 @@
 
 using namespace clang;
 
+void GRExprEngine::EvalArguments(ExprIterator AI, ExprIterator AE,
+                                 const FunctionProtoType *FnType, 
+                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
+  llvm::SmallVector<CallExprWLItem, 20> WorkList;
+  WorkList.reserve(AE - AI);
+  WorkList.push_back(CallExprWLItem(AI, Pred));
+
+  while (!WorkList.empty()) {
+    CallExprWLItem Item = WorkList.back();
+    WorkList.pop_back();
+
+    if (Item.I == AE) {
+      Dst.insert(Item.N);
+      continue;
+    }
+
+    ExplodedNodeSet Tmp;
+    const unsigned ParamIdx = Item.I - AI;
+    bool VisitAsLvalue = FnType? FnType->getArgType(ParamIdx)->isReferenceType()
+                               : false;
+    if (VisitAsLvalue)
+      VisitLValue(*Item.I, Item.N, Tmp);
+    else
+      Visit(*Item.I, Item.N, Tmp);
+
+    ++(Item.I);
+    for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI != NE; ++NI)
+      WorkList.push_back(CallExprWLItem(Item.I, *NI));
+  }
+}
+
 const CXXThisRegion *GRExprEngine::getCXXThisRegion(const CXXMethodDecl *D,
                                                  const StackFrameContext *SFC) {
   Type *T = D->getParent()->getTypeForDecl();
@@ -212,14 +243,38 @@
   const ElementRegion *EleReg = 
                          getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
 
-  const GRState *state = Pred->getState();
+  // Evaluate constructor arguments.
+  const FunctionProtoType *FnType = NULL;
+  const CXXConstructorDecl *CD = CNE->getConstructor();
+  if (CD)
+    FnType = CD->getType()->getAs<FunctionProtoType>();
+  ExplodedNodeSet ArgsEvaluated;
+  EvalArguments(CNE->constructor_arg_begin(), CNE->constructor_arg_end(),
+                FnType, Pred, ArgsEvaluated);
 
-  Store store = state->getStore();
-  StoreManager::InvalidatedSymbols IS;
-  store = getStoreManager().InvalidateRegion(store, EleReg, CNE, Count, &IS);
-  state = state->makeWithStore(store);
-  state = state->BindExpr(CNE, loc::MemRegionVal(EleReg));
-  MakeNode(Dst, CNE, Pred, state);
+  // Initialize the object region and bind the 'new' expression.
+  for (ExplodedNodeSet::iterator I = ArgsEvaluated.begin(), 
+                                 E = ArgsEvaluated.end(); I != E; ++I) {
+    const GRState *state = GetState(*I);
+
+    if (ObjTy->isRecordType()) {
+      Store store = state->getStore();
+      StoreManager::InvalidatedSymbols IS;
+      store = getStoreManager().InvalidateRegion(store, EleReg, CNE, Count, &IS);
+      state = state->makeWithStore(store);
+    } else {
+      if (CNE->hasInitializer()) {
+        SVal V = state->getSVal(*CNE->constructor_arg_begin());
+        state = state->bindLoc(loc::MemRegionVal(EleReg), V);
+      } else {
+        // Explicitly set to undefined, because currently we retrieve symbolic
+        // value from symbolic region.
+        state = state->bindLoc(loc::MemRegionVal(EleReg), UndefinedVal());
+      }
+    }
+    state = state->BindExpr(CNE, loc::MemRegionVal(EleReg));
+    MakeNode(Dst, CNE, Pred, state);
+  }
 }
 
 





More information about the cfe-commits mailing list