diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-04-12 05:12:39 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-04-12 05:12:39 +0000 |
commit | 9d5d308c9be367ec41cc6a89f215d45f675b4617 (patch) | |
tree | 4f2e1bcd282d26020d2ff3cfbf74b31597121eca /lib/StaticAnalyzer/Core/CXXExprEngine.cpp | |
parent | 3bab50b802f402b7020aeb3ba6cec90bb149678c (diff) |
static analyzer: invalidate by-ref arguments passed to constructors in a 'new' expression.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129349 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/CXXExprEngine.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/CXXExprEngine.cpp | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/CXXExprEngine.cpp b/lib/StaticAnalyzer/Core/CXXExprEngine.cpp index 6365bce05f..e04ba758d8 100644 --- a/lib/StaticAnalyzer/Core/CXXExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/CXXExprEngine.cpp @@ -268,9 +268,9 @@ void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD, void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ExplodedNodeSet &Dst) { - unsigned Count = Builder->getCurrentBlockCount(); + unsigned blockCount = Builder->getCurrentBlockCount(); DefinedOrUnknownSVal symVal = - svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), Count); + svalBuilder.getConjuredSymbolVal(NULL, CNE, CNE->getType(), blockCount); const MemRegion *NewReg = cast<loc::MemRegionVal>(symVal).getRegion(); QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType(); const ElementRegion *EleReg = @@ -297,11 +297,39 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, // Initialize the object region and bind the 'new' expression. for (ExplodedNodeSet::iterator I = argsEvaluated.begin(), E = argsEvaluated.end(); I != E; ++I) { + const GRState *state = GetState(*I); + + // Accumulate list of regions that are invalidated. + // FIXME: Eventually we should unify the logic for constructor + // processing in one place. + llvm::SmallVector<const MemRegion*, 10> regionsToInvalidate; + for (CXXNewExpr::const_arg_iterator + ai = CNE->constructor_arg_begin(), ae = CNE->constructor_arg_end(); + ai != ae; ++ai) + { + SVal val = state->getSVal(*ai); + if (const MemRegion *region = val.getAsRegion()) + regionsToInvalidate.push_back(region); + } if (ObjTy->isRecordType()) { - state = state->invalidateRegion(EleReg, CNE, Count); + regionsToInvalidate.push_back(EleReg); + // Invalidate the regions. + state = state->invalidateRegions(regionsToInvalidate.data(), + regionsToInvalidate.data() + + regionsToInvalidate.size(), + CNE, blockCount, 0, + /* invalidateGlobals = */ true); + } else { + // Invalidate the regions. + state = state->invalidateRegions(regionsToInvalidate.data(), + regionsToInvalidate.data() + + regionsToInvalidate.size(), + CNE, blockCount, 0, + /* invalidateGlobals = */ true); + if (CNE->hasInitializer()) { SVal V = state->getSVal(*CNE->constructor_arg_begin()); state = state->bindLoc(loc::MemRegionVal(EleReg), V); |