aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/GRExprEngine.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-11-24 13:08:51 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-11-24 13:08:51 +0000
commitd706434b0231c76fd9acf30060646a7aa8f69aef (patch)
tree84ea6bde3550736b956941dfe3ed50fb377cf1ee /lib/Checker/GRExprEngine.cpp
parent13cf5e2e223ebfc8ec0459913b2fc9ec1e5fa760 (diff)
Let StackFrameContext represent if the call expr is evaluated as lvalue.
This is required for supporting const reference to temporary objects. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120093 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/GRExprEngine.cpp')
-rw-r--r--lib/Checker/GRExprEngine.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp
index f0aa38b07c..2181b705f7 100644
--- a/lib/Checker/GRExprEngine.cpp
+++ b/lib/Checker/GRExprEngine.cpp
@@ -918,7 +918,7 @@ void GRExprEngine::Visit(const Stmt* S, ExplodedNode* Pred,
const CXXConstructExpr *C = cast<CXXConstructExpr>(S);
// For block-level CXXConstructExpr, we don't have a destination region.
// Let VisitCXXConstructExpr() create one.
- VisitCXXConstructExpr(C, 0, Pred, Dst);
+ VisitCXXConstructExpr(C, 0, Pred, Dst, false);
break;
}
@@ -1117,7 +1117,6 @@ void GRExprEngine::VisitLValue(const Expr* Ex, ExplodedNode* Pred,
switch (Ex->getStmtClass()) {
// C++ stuff we don't support yet.
- case Stmt::CXXExprWithTemporariesClass:
case Stmt::CXXMemberCallExprClass:
case Stmt::CXXScalarValueInitExprClass: {
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
@@ -1147,6 +1146,24 @@ void GRExprEngine::VisitLValue(const Expr* Ex, ExplodedNode* Pred,
break;
}
+ case Stmt::CXXExprWithTemporariesClass: {
+ const CXXExprWithTemporaries *expr = cast<CXXExprWithTemporaries>(Ex);
+ VisitLValue(expr->getSubExpr(), Pred, Dst);
+ break;
+ }
+
+ case Stmt::CXXBindTemporaryExprClass: {
+ const CXXBindTemporaryExpr *expr = cast<CXXBindTemporaryExpr>(Ex);
+ VisitLValue(expr->getSubExpr(), Pred, Dst);
+ break;
+ }
+
+ case Stmt::CXXTemporaryObjectExprClass: {
+ const CXXTemporaryObjectExpr *expr = cast<CXXTemporaryObjectExpr>(Ex);
+ VisitCXXTemporaryObjectExpr(expr, Pred, Dst, true);
+ break;
+ }
+
case Stmt::CompoundLiteralExprClass:
VisitCompoundLiteralExpr(cast<CompoundLiteralExpr>(Ex), Pred, Dst, true);
return;
@@ -1643,11 +1660,13 @@ void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) {
if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
const CXXThisRegion *ThisR =
getCXXThisRegion(CCE->getConstructor()->getParent(), calleeCtx);
- // We might not have 'this' region in the binding if we didn't inline
- // the ctor call.
+
SVal ThisV = state->getSVal(ThisR);
- loc::MemRegionVal *V = dyn_cast<loc::MemRegionVal>(&ThisV);
- if (V) {
+
+ if (calleeCtx->evalAsLValue()) {
+ state = state->BindExpr(CCE, ThisV);
+ } else {
+ loc::MemRegionVal *V = cast<loc::MemRegionVal>(&ThisV);
SVal ObjVal = state->getSVal(V->getRegion());
assert(isa<nonloc::LazyCompoundVal>(ObjVal));
state = state->BindExpr(CCE, ObjVal);
@@ -2073,7 +2092,7 @@ bool GRExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE,
const StackFrameContext *stackFrame =
AMgr.getStackFrame(AMgr.getAnalysisContext(FD),
Pred->getLocationContext(),
- CE, Builder->getBlock(), Builder->getIndex());
+ CE, false, Builder->getBlock(), Builder->getIndex());
// Now we have the definition of the callee, create a CallEnter node.
CallEnter Loc(CE, stackFrame, Pred->getLocationContext());
@@ -2089,7 +2108,7 @@ bool GRExprEngine::InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE,
return false;
const StackFrameContext *stackFrame =
AMgr.getStackFrame(C, Pred->getLocationContext(),
- CE, Builder->getBlock(), Builder->getIndex());
+ CE, false, Builder->getBlock(), Builder->getIndex());
CallEnter Loc(CE, stackFrame, Pred->getLocationContext());
ExplodedNode *N = Builder->generateNode(Loc, state, Pred);
Dst.Add(N);