diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/Environment.cpp | 7 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 25 | ||||
-rw-r--r-- | lib/Analysis/MemRegion.cpp | 13 |
3 files changed, 39 insertions, 6 deletions
diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp index dd2f08b48f..f04cf7b05f 100644 --- a/lib/Analysis/Environment.cpp +++ b/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/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 0336ae5ada..ed3dc8abac 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/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/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index 5be882ad54..c17e4e83ee 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/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* |