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

Zhongxing Xu xuzhongxing at gmail.com
Tue Mar 16 06:14:16 PDT 2010


Author: zhongxingxu
Date: Tue Mar 16 08:14:16 2010
New Revision: 98629

URL: http://llvm.org/viewvc/llvm-project?rev=98629&view=rev
Log:
Add VisitCXXContructExpr logic to the analyzer. This still has not fully worked
since RemoveDeadBinding mistakenly remove the binding to CXXThisRegion. 

Modified:
    cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
    cfe/trunk/lib/Checker/GRExprEngine.cpp
    cfe/trunk/lib/Checker/RegionStore.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=98629&r1=98628&r2=98629&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h Tue Mar 16 08:14:16 2010
@@ -347,7 +347,10 @@
 
   void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred, 
                         ExplodedNodeSet & Dst);
-
+  
+  void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
+                             ExplodedNode *Pred,
+                             ExplodedNodeSet &Dst);
   /// Create a C++ temporary object for an rvalue.
   void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred, 
                                 ExplodedNodeSet &Dst);

Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=98629&r1=98628&r2=98629&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Tue Mar 16 08:14:16 2010
@@ -19,6 +19,7 @@
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/StmtObjC.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManager.h"
@@ -2335,7 +2336,11 @@
   ExplodedNodeSet Tmp;
 
   if (InitEx) {
-    if (VD->getType()->isReferenceType())
+    if (const CXXConstructExpr *E = dyn_cast<CXXConstructExpr>(InitEx)) {
+      VisitCXXConstructExpr(E, GetState(Pred)->getLValue(VD,
+                                       Pred->getLocationContext()), Pred, Dst);
+      return;
+    } else if (VD->getType()->isReferenceType())
       VisitLValue(InitEx, Pred, Tmp);
     else
       Visit(InitEx, Pred, Tmp);
@@ -2826,7 +2831,8 @@
                                     ExplodedNodeSet & Dst) {
   // Get the this object region from StoreManager.
   const MemRegion *R =
-    ValMgr.getRegionManager().getCXXThisRegion(TE->getType(),
+    ValMgr.getRegionManager().getCXXThisRegion(
+                                  getContext().getCanonicalType(TE->getType()),
                                                Pred->getLocationContext());
 
   const GRState *state = GetState(Pred);
@@ -3126,6 +3132,78 @@
   }
 }
 
+void GRExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
+                                         ExplodedNode *Pred,
+                                         ExplodedNodeSet &Dst) {
+
+  const CXXConstructorDecl *CD = E->getConstructor();
+  assert(CD);
+
+  if (!CD->isThisDeclarationADefinition())
+    // FIXME: invalidate the object.
+    return;
+
+  
+  // Evaluate other arguments.
+  CXXConstructExpr::arg_iterator AB 
+    = const_cast<CXXConstructExpr*>(E)->arg_begin();
+  CXXConstructExpr::arg_iterator AE 
+    = const_cast<CXXConstructExpr*>(E)->arg_end();
+  llvm::SmallVector<CallExprWLItem, 20> WorkList;
+  WorkList.reserve(AE - AB);
+  WorkList.push_back(CallExprWLItem(AB, Pred));
+  ExplodedNodeSet ArgsEvaluated;
+  const FunctionProtoType *Proto = CD->getType()->getAs<FunctionProtoType>();
+
+  while (!WorkList.empty()) {
+    CallExprWLItem Item = WorkList.back();
+    WorkList.pop_back();
+
+    if (Item.I == AE) {
+      ArgsEvaluated.insert(Item.N);
+      continue;
+    }
+
+    // Evaluate the argument.
+    ExplodedNodeSet Tmp;
+    const unsigned ParamIdx = Item.I - AB;
+
+    bool VisitAsLvalue = false;
+
+    if (ParamIdx < Proto->getNumArgs())
+      VisitAsLvalue = Proto->getArgType(ParamIdx)->isReferenceType();
+
+    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));
+  }
+  // The callee stack frame context used to create the 'this' parameter region.
+  const StackFrameContext *SFC = AMgr.getStackFrame(CD, 
+                                                    Pred->getLocationContext(),
+                                   E, Builder->getBlock(), Builder->getIndex());
+
+  Type *T = CD->getParent()->getTypeForDecl();
+  QualType PT = getContext().getPointerType(QualType(T,0));
+  const CXXThisRegion *ThisR = ValMgr.getRegionManager().getCXXThisRegion(PT,
+                                                                          SFC);
+
+  CallEnter Loc(E, CD, Pred->getLocationContext());
+  for (ExplodedNodeSet::iterator NI = ArgsEvaluated.begin(),
+                                 NE = ArgsEvaluated.end(); NI != NE; ++NI) {
+    const GRState *state = GetState(*NI);
+    // Setup 'this' region.
+    state = state->bindLoc(loc::MemRegionVal(ThisR), Dest);
+    ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
+    if (N)
+      Dst.Add(N);
+  }
+}
 //===----------------------------------------------------------------------===//
 // Checker registration/lookup.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Checker/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/RegionStore.cpp?rev=98629&r1=98628&r2=98629&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/RegionStore.cpp (original)
+++ cfe/trunk/lib/Checker/RegionStore.cpp Tue Mar 16 08:14:16 2010
@@ -22,6 +22,8 @@
 #include "clang/Analysis/Support/Optional.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
 
 #include "llvm/ADT/ImmutableMap.h"
 #include "llvm/ADT/ImmutableList.h"
@@ -1841,18 +1843,29 @@
 GRState const *RegionStoreManager::EnterStackFrame(GRState const *state,
                                                StackFrameContext const *frame) {
   FunctionDecl const *FD = cast<FunctionDecl>(frame->getDecl());
-  CallExpr const *CE = cast<CallExpr>(frame->getCallSite());
-
   FunctionDecl::param_const_iterator PI = FD->param_begin();
+  Store store = state->getStore();
 
-  CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
+  if (CallExpr const *CE = dyn_cast<CallExpr>(frame->getCallSite())) {
+    CallExpr::const_arg_iterator AI = CE->arg_begin(), AE = CE->arg_end();
 
-  // Copy the arg expression value to the arg variables.
-  Store store = state->getStore();
-  for (; AI != AE; ++AI, ++PI) {
-    SVal ArgVal = state->getSVal(*AI);
-    store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI, frame)), ArgVal);
-  }
+    // Copy the arg expression value to the arg variables.
+    for (; AI != AE; ++AI, ++PI) {
+      SVal ArgVal = state->getSVal(*AI);
+      store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal);
+    }
+  } else if (const CXXConstructExpr *CE = 
+               dyn_cast<CXXConstructExpr>(frame->getCallSite())) {
+    CXXConstructExpr::const_arg_iterator AI = CE->arg_begin(), 
+      AE = CE->arg_end();
+
+    // Copy the arg expression value to the arg variables.
+    for (; AI != AE; ++AI, ++PI) {
+      SVal ArgVal = state->getSVal(*AI);
+      store = Bind(store, ValMgr.makeLoc(MRMgr.getVarRegion(*PI,frame)),ArgVal);
+    }
+  } else
+    assert(0 && "Unhandled call expression.");
 
   return state->makeWithStore(store);
 }





More information about the cfe-commits mailing list