summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-01-09 09:16:47 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-01-09 09:16:47 +0000
commitf1eeb78ffc1cdd625a819b3e8d8ab44ae825c38e (patch)
treeb2d2a8daed2d92aac2a0119977dabac477e0ef34 /clang/lib/Analysis
parenta230552b94b9df0b98d504f9c90491e9ddd5eccc (diff)
downloadbcm5719-llvm-f1eeb78ffc1cdd625a819b3e8d8ab44ae825c38e.tar.gz
bcm5719-llvm-f1eeb78ffc1cdd625a819b3e8d8ab44ae825c38e.zip
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
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r--clang/lib/Analysis/Environment.cpp7
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp25
-rw-r--r--clang/lib/Analysis/MemRegion.cpp13
3 files changed, 39 insertions, 6 deletions
diff --git a/clang/lib/Analysis/Environment.cpp b/clang/lib/Analysis/Environment.cpp
index dd2f08b48f7..f04cf7b05fe 100644
--- a/clang/lib/Analysis/Environment.cpp
+++ b/clang/lib/Analysis/Environment.cpp
@@ -37,7 +37,12 @@ SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
}
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 0336ae5ada3..ed3dc8abac1 100644
--- a/clang/lib/Analysis/GRExprEngine.cpp
+++ b/clang/lib/Analysis/GRExprEngine.cpp
@@ -887,6 +887,11 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
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 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
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 5be882ad549..c17e4e83eee 100644
--- a/clang/lib/Analysis/MemRegion.cpp
+++ b/clang/lib/Analysis/MemRegion.cpp
@@ -304,14 +304,14 @@ void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
}
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 @@ MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
}
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*
OpenPOWER on IntegriCloud