diff options
author | Anna Zaks <ganna@apple.com> | 2013-11-20 00:11:42 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2013-11-20 00:11:42 +0000 |
commit | d2a807d8317c4782aafd9186852e9b7eed76a111 (patch) | |
tree | 057ec750a95d586071ac3f3b47f6a8f1abf5d435 /clang | |
parent | 0d3f7eca8e552621c61658a5f895e2716d5c0e74 (diff) | |
download | bcm5719-llvm-d2a807d8317c4782aafd9186852e9b7eed76a111.tar.gz bcm5719-llvm-d2a807d8317c4782aafd9186852e9b7eed76a111.zip |
[analyzer] Fix an infinite recursion in region invalidation by adding block count to the BlockDataRegion.
llvm-svn: 195174
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h | 10 | ||||
-rw-r--r-- | clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h | 3 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp | 3 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 18 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 6 | ||||
-rw-r--r-- | clang/test/Analysis/blocks.m | 16 |
6 files changed, 45 insertions, 11 deletions
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index a84dcb0df08..cc790c1b6b3 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -635,12 +635,14 @@ class BlockDataRegion : public TypedRegion { friend class MemRegionManager; const BlockTextRegion *BC; const LocationContext *LC; // Can be null */ + unsigned BlockCount; void *ReferencedVars; void *OriginalVars; BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc, - const MemRegion *sreg) + unsigned count, const MemRegion *sreg) : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), + BlockCount(count), ReferencedVars(0), OriginalVars(0) {} public: @@ -692,7 +694,8 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const; static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *, - const LocationContext *, const MemRegion *); + const LocationContext *, unsigned, + const MemRegion *); static bool classof(const MemRegion* R) { return R->getKind() == BlockDataRegionKind; @@ -1270,7 +1273,8 @@ public: /// argument is allowed to be NULL for cases where we have no known /// context. const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc, - const LocationContext *lc = NULL); + const LocationContext *lc, + unsigned blockCount); /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended /// by static references. This differs from getCXXTempObjectRegion in the diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index bbb56885af0..c5d0a92cabd 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -200,7 +200,8 @@ public: DefinedSVal getFunctionPointer(const FunctionDecl *func); DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, - const LocationContext *locContext); + const LocationContext *locContext, + unsigned blockCount); /// Returns the value of \p E, if it can be determined in a non-path-sensitive /// manner. diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index a2a1885f8b9..297754d6086 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -184,7 +184,8 @@ void ExprEngine::VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, // Get the value of the block itself. SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T, - Pred->getLocationContext()); + Pred->getLocationContext(), + currBldrCtx->blockCount()); ProgramStateRef State = Pred->getState(); diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 1be5840a20b..162cd332649 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -383,15 +383,17 @@ void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const { void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockTextRegion *BC, const LocationContext *LC, + unsigned BlkCount, const MemRegion *sReg) { ID.AddInteger(MemRegion::BlockDataRegionKind); ID.AddPointer(BC); ID.AddPointer(LC); + ID.AddInteger(BlkCount); ID.AddPointer(sReg); } void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const { - BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion()); + BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion()); } void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, @@ -464,7 +466,14 @@ void BlockTextRegion::dumpToStream(raw_ostream &os) const { } void BlockDataRegion::dumpToStream(raw_ostream &os) const { - os << "block_data{" << BC << '}'; + os << "block_data{" << BC; + os << "; "; + for (BlockDataRegion::referenced_vars_iterator + I = referenced_vars_begin(), + E = referenced_vars_end(); I != E; ++I) + os << "(" << I.getCapturedRegion() << "," << + I.getOriginalRegion() << ") "; + os << '}'; } void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const { @@ -839,7 +848,8 @@ const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D, const BlockDataRegion * MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC, - const LocationContext *LC) { + const LocationContext *LC, + unsigned blockCount) { const MemRegion *sReg = 0; const BlockDecl *BD = BC->getDecl(); if (!BD->hasCaptures()) { @@ -861,7 +871,7 @@ MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC, } } - return getSubRegion<BlockDataRegion>(BC, LC, sReg); + return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg); } const CXXTempObjectRegion * diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp index 2142f06fef5..adc54659911 100644 --- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -202,10 +202,12 @@ DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) { DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block, CanQualType locTy, - const LocationContext *locContext) { + const LocationContext *locContext, + unsigned blockCount) { const BlockTextRegion *BC = MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisDeclContext()); - const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext); + const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext, + blockCount); return loc::MemRegionVal(BD); } diff --git a/clang/test/Analysis/blocks.m b/clang/test/Analysis/blocks.m index 6d3495cd523..62d53607b53 100644 --- a/clang/test/Analysis/blocks.m +++ b/clang/test/Analysis/blocks.m @@ -146,3 +146,19 @@ void testReturnVariousSignatures() { return 42; }(); } + +// This test used to cause infinite loop in the region invalidation. +void blockCapturesItselfInTheLoop(int x, int m) { + void (^assignData)(int) = ^(int x){ + x++; + }; + while (m < 0) { + void (^loop)(int); + loop = ^(int x) { + assignData(x); + }; + assignData = loop; + m++; + } + assignData(x); +} |