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.

llvm-svn: 93047
diff --git a/clang/lib/Analysis/Environment.cpp b/clang/lib/Analysis/Environment.cpp
index dd2f08b..f04cf7b 100644
--- a/clang/lib/Analysis/Environment.cpp
+++ b/clang/lib/Analysis/Environment.cpp
@@ -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
diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp
index 0336ae5..ed3dc8a 100644
--- a/clang/lib/Analysis/GRExprEngine.cpp
+++ b/clang/lib/Analysis/GRExprEngine.cpp
@@ -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.
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp
index 5be882a..c17e4e8 100644
--- a/clang/lib/Analysis/MemRegion.cpp
+++ b/clang/lib/Analysis/MemRegion.cpp
@@ -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*