aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/CXXExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-04-12 05:12:39 +0000
committerTed Kremenek <kremenek@apple.com>2011-04-12 05:12:39 +0000
commit9d5d308c9be367ec41cc6a89f215d45f675b4617 (patch)
tree4f2e1bcd282d26020d2ff3cfbf74b31597121eca /lib/StaticAnalyzer/Core/CXXExprEngine.cpp
parent3bab50b802f402b7020aeb3ba6cec90bb149678c (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.cpp34
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);