From: Bill Wendling Date: Wed, 20 Nov 2013 06:47:04 +0000 (+0000) Subject: Merging r195174: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3eb52bb5d791630f926ff2226dae25012315ad9a;p=clang Merging r195174: ------------------------------------------------------------------------ r195174 | zaks | 2013-11-19 16:11:42 -0800 (Tue, 19 Nov 2013) | 1 line [analyzer] Fix an infinite recursion in region invalidation by adding block count to the BlockDataRegion. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_34@195228 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index a84dcb0df0..cc790c1b6b 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/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/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index bbb56885af..c5d0a92cab 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/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/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index a2a1885f8b..297754d608 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/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/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp index 1be5840a20..162cd33264 100644 --- a/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/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(BC, LC, sReg); + return getSubRegion(BC, LC, blockCount, sReg); } const CXXTempObjectRegion * diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp index 2142f06fef..adc5465991 100644 --- a/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/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/test/Analysis/blocks.m b/test/Analysis/blocks.m index 6d3495cd52..62d53607b5 100644 --- a/test/Analysis/blocks.m +++ b/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); +}