diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-12-14 22:15:06 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-12-14 22:15:06 +0000 |
commit | 5348f94abd0e9d3945da8d059b55b156967e8ff9 (patch) | |
tree | 2ef529fcecfbcec96490c4939169aad38f74961d | |
parent | 750c85ea8efd0f899cdf7ba9060d1286ba14be9a (diff) |
Fix: <rdar://problem/7468209> SymbolManager::isLive() should not crash on captured block variables that are passed by reference
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91348 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Analysis/PathSensitive/MemRegion.h | 2 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/SymbolManager.h | 8 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 5 | ||||
-rw-r--r-- | lib/Analysis/MemRegion.cpp | 9 | ||||
-rw-r--r-- | lib/Analysis/SymbolManager.cpp | 3 | ||||
-rw-r--r-- | test/Analysis/misc-ps-region-store.m | 18 |
6 files changed, 40 insertions, 5 deletions
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index 45dab1ec84..2fe5ea0cf3 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -621,6 +621,8 @@ class VarRegion : public DeclRegion { public: const VarDecl *getDecl() const { return cast<VarDecl>(D); } + const StackFrameContext *getStackFrame() const; + QualType getValueType(ASTContext& C) const { // FIXME: We can cache this if needed. return C.getCanonicalType(getDecl()->getType()); diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index 8dbbaace4f..8eb3196479 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -33,6 +33,7 @@ namespace clang { class MemRegion; class TypedRegion; class VarRegion; + class StackFrameContext; } namespace clang { @@ -333,10 +334,13 @@ class SymbolReaper { SetTy TheDead; LiveVariables& Liveness; SymbolManager& SymMgr; + const StackFrameContext *CurrentStackFrame; public: - SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr) - : Liveness(liveness), SymMgr(symmgr) {} + SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr, + const StackFrameContext *currentStackFrame) + : Liveness(liveness), SymMgr(symmgr), CurrentStackFrame(currentStackFrame) + {} ~SymbolReaper() {} diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 4e88f18d0c..033d105a93 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -394,8 +394,9 @@ void GRExprEngine::ProcessStmt(Stmt* S, GRStmtNodeBuilder& builder) { Builder->setAuditor(BatchAuditor.get()); // Create the cleaned state. - SymbolReaper SymReaper(Builder->getBasePredecessor()->getLiveVariables(), - SymMgr); + const ExplodedNode *BasePred = Builder->getBasePredecessor(); + SymbolReaper SymReaper(BasePred->getLiveVariables(), SymMgr, + BasePred->getLocationContext()->getCurrentStackFrame()); CleanedState = AMgr.shouldPurgeDead() ? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, SymReaper) : EntryNode->getState(); diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index da45c4dfee..bc3a5b7045 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -165,6 +165,15 @@ MemRegionManager* SubRegion::getMemRegionManager() const { } while (1); } +const StackFrameContext *VarRegion::getStackFrame() const { + const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace()); + return SSR ? SSR->getStackFrame() : NULL; +} + +//===----------------------------------------------------------------------===// +// FoldingSet profiling. +//===----------------------------------------------------------------------===// + void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const { ID.AddInteger((unsigned)getKind()); } diff --git a/lib/Analysis/SymbolManager.cpp b/lib/Analysis/SymbolManager.cpp index da91f55bc0..3fe36b064e 100644 --- a/lib/Analysis/SymbolManager.cpp +++ b/lib/Analysis/SymbolManager.cpp @@ -221,7 +221,8 @@ bool SymbolReaper::isLive(SymbolRef sym) { } bool SymbolReaper::isLive(const Stmt *Loc, const VarRegion *VR) const { - return Liveness.isLive(Loc, VR->getDecl()); + const StackFrameContext *SFC = VR->getStackFrame(); + return SFC == CurrentStackFrame ? Liveness.isLive(Loc, VR->getDecl()) : true; } SymbolVisitor::~SymbolVisitor() {} diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index d1906778e2..e736e0f37c 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -618,3 +618,21 @@ typedef void (^RDar_7462324_Callback)(id obj); } @end +//===----------------------------------------------------------------------===// +// <rdar://problem/7468209> - Scanning for live variables within a block should +// not crash on variables passed by reference via __block. +//===----------------------------------------------------------------------===// + +int rdar7468209_aux(); +void rdar7468209_aux2(); + +void rdar7468209() { + __block int x = 0; + ^{ + x = rdar7468209_aux(); + // We need a second statement so that 'x' would be removed from the store if it wasn't + // passed by reference. + rdar7468209_aux_2(); + }(); +} + |