diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2010-12-22 07:20:27 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2010-12-22 07:20:27 +0000 |
commit | 05e539175d9bac678fca8e77665e88b685729850 (patch) | |
tree | 3901c7460888e160f6520618892e9de02e6f69eb /lib/Checker/GRExprEngine.cpp | |
parent | a0e27f00158c9306d53b0003b94182e415380ea9 (diff) |
After inlining the CXXConstructExpr, bind the temporary object region to it.
This change is necessary when the variable is a const reference and we need
the l-value of the construct expr. After that, when binding the variable,
recover the lazy compound value when the variable is not a reference.
In Environment, use the value of a no-op cast expression when it has one.
Otherwise, blast-through it.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122388 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/GRExprEngine.cpp')
-rw-r--r-- | lib/Checker/GRExprEngine.cpp | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 2945de162a..a24a5df4fb 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -1475,15 +1475,8 @@ void GRExprEngine::ProcessCallExit(GRCallExitNodeBuilder &B) { getCXXThisRegion(CCE->getConstructor()->getParent(), calleeCtx); SVal ThisV = state->getSVal(ThisR); - - 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); - } + // Always bind the region to the CXXConstructExpr. + state = state->BindExpr(CCE, ThisV); } B.generateNode(state); @@ -2508,7 +2501,12 @@ void GRExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, if (InitEx) { if (VD->getType()->isReferenceType() && !InitEx->isLValue()) { - CreateCXXTemporaryObject(InitEx, Pred, Tmp); + // If the initializer is C++ record type, it should already has a + // temp object. + if (!InitEx->getType()->isRecordType()) + CreateCXXTemporaryObject(InitEx, Pred, Tmp); + else + Tmp.Add(Pred); } else Visit(InitEx, Pred, Tmp); } else @@ -2527,6 +2525,14 @@ void GRExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, if (InitEx) { SVal InitVal = state->getSVal(InitEx); + // We bound the temp obj region to the CXXConstructExpr. Now recover + // the lazy compound value when the variable is not a reference. + if (AMgr.getLangOptions().CPlusPlus && VD->getType()->isRecordType() && + !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){ + InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion()); + assert(isa<nonloc::LazyCompoundVal>(InitVal)); + } + // Recover some path-sensitivity if a scalar value evaluated to // UnknownVal. if ((InitVal.isUnknown() || |