[cfe-commits] r93047 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h include/clang/Analysis/PathSensitive/MemRegion.h lib/Analysis/Environment.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/MemRegion.cpp test/Analysis/reference.cpp

Zhongxing Xu xuzhongxing at gmail.com
Sat Jan 9 01:16:47 PST 2010


Author: zhongxingxu
Date: Sat Jan  9 03:16:47 2010
New Revision: 93047

URL: http://llvm.org/viewvc/llvm-project?rev=93047&view=rev
Log:
When binding an rvalue to a reference, create a temporary object. Use 
CXXObjectRegion to represent it. 

In Environment, lookup a literal expression before make up a value for it.

Added:
    cfe/trunk/test/Analysis/reference.cpp
Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
    cfe/trunk/lib/Analysis/Environment.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/MemRegion.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=93047&r1=93046&r2=93047&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Sat Jan  9 03:16:47 2010
@@ -353,6 +353,10 @@
   void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred, 
                         ExplodedNodeSet & Dst);
 
+  /// Create a C++ temporary object for an rvalue.
+  void CreateCXXTemporaryObject(Expr *Ex, 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/include/clang/Analysis/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=93047&r1=93046&r2=93047&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Sat Jan  9 03:16:47 2010
@@ -752,21 +752,21 @@
   }
 };
 
+// C++ temporary object associated with an expression.
 class CXXObjectRegion : public TypedRegion {
   friend class MemRegionManager;
 
-  // T - The object type.
-  QualType T;
+  Expr const *Ex;
 
-  CXXObjectRegion(QualType t, const MemRegion *sReg) 
-    : TypedRegion(sReg, CXXObjectRegionKind), T(t) {}
+  CXXObjectRegion(Expr const *E, MemRegion const *sReg) 
+    : TypedRegion(sReg, CXXObjectRegionKind), Ex(E) {}
 
   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
-                            QualType T, const MemRegion *sReg);
+                            Expr const *E, const MemRegion *sReg);
   
 public:
   QualType getValueType(ASTContext& C) const {
-    return T;
+    return Ex->getType();
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) const;
@@ -901,7 +901,8 @@
   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd,
                                           const MemRegion* superRegion);
 
-  const CXXObjectRegion *getCXXObjectRegion(QualType T);
+  const CXXObjectRegion *getCXXObjectRegion(Expr const *Ex,
+                                            LocationContext const *LC);
 
   const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD);
   const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD,

Modified: cfe/trunk/lib/Analysis/Environment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Environment.cpp?rev=93047&r1=93046&r2=93047&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/Environment.cpp (original)
+++ cfe/trunk/lib/Analysis/Environment.cpp Sat Jan  9 03:16:47 2010
@@ -37,7 +37,12 @@
       }
 
       case Stmt::IntegerLiteralClass: {
-        return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
+        // In C++, this expression may have been bound to a temporary object.
+        SVal const *X = ExprBindings.lookup(E);
+        if (X)
+          return *X;
+        else
+          return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
       }
 
       // Casts where the source and target type are the same

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=93047&r1=93046&r2=93047&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Sat Jan  9 03:16:47 2010
@@ -887,6 +887,11 @@
     case Stmt::UnaryOperatorClass:
       VisitUnaryOperator(cast<UnaryOperator>(Ex), Pred, Dst, true);
       return;
+
+    // In C++, binding an rvalue to a reference requires to create an object.
+    case Stmt::IntegerLiteralClass:
+      CreateCXXTemporaryObject(Ex, Pred, Dst);
+      return;
       
     default:
       // Arbitrary subexpressions can return aggregate temporaries that
@@ -2992,6 +2997,26 @@
   CheckerVisit(B, Dst, Tmp3, false);
 }
 
+void GRExprEngine::CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred, 
+                                            ExplodedNodeSet &Dst) {
+  ExplodedNodeSet Tmp;
+  Visit(Ex, Pred, Tmp);
+  for (ExplodedNodeSet::iterator I = Tmp.begin(), E = Tmp.end(); I != E; ++I) {
+    const GRState *state = GetState(*I);
+    
+    // Bind the temporary object to the value of the expression. Then bind
+    // the expression to the location of the object.
+    SVal V = state->getSVal(Ex);
+
+    const MemRegion *R = 
+      ValMgr.getRegionManager().getCXXObjectRegion(Ex,
+                                                   Pred->getLocationContext());
+
+    state = state->bindLoc(loc::MemRegionVal(R), V);
+    MakeNode(Dst, Ex, Pred, state->BindExpr(Ex, loc::MemRegionVal(R)));
+  }  
+}
+
 //===----------------------------------------------------------------------===//
 // Checker registration/lookup.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=93047&r1=93046&r2=93047&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Sat Jan  9 03:16:47 2010
@@ -304,14 +304,14 @@
 }
 
 void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
-                                    QualType T, 
+                                    Expr const *Ex,
                                     const MemRegion *sReg) {
-  ID.AddPointer(T.getTypePtr());
+  ID.AddPointer(Ex);
   ID.AddPointer(sReg);
 }
 
 void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
-  ProfileRegion(ID, T, getSuperRegion());
+  ProfileRegion(ID, Ex, getSuperRegion());
 }
 
 //===----------------------------------------------------------------------===//
@@ -580,8 +580,11 @@
 }
 
 const CXXObjectRegion*
-MemRegionManager::getCXXObjectRegion(QualType T) {
-  return getSubRegion<CXXObjectRegion>(T, getUnknownRegion());
+MemRegionManager::getCXXObjectRegion(Expr const *E,
+                                     LocationContext const *LC) {
+  const StackFrameContext *SFC = LC->getCurrentStackFrame();
+  assert(SFC);
+  return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
 }
 
 const CXXThisRegion*

Added: cfe/trunk/test/Analysis/reference.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/reference.cpp?rev=93047&view=auto

==============================================================================
--- cfe/trunk/test/Analysis/reference.cpp (added)
+++ cfe/trunk/test/Analysis/reference.cpp Sat Jan  9 03:16:47 2010
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
+
+void f1() {
+  int const &i = 3;
+  int b = i;
+}





More information about the cfe-commits mailing list