forked from OSchip/llvm-project
Fix: <rdar://problem/7468209> SymbolManager::isLive() should not crash on captured block variables that are passed by reference
llvm-svn: 91348
This commit is contained in:
parent
590d18f103
commit
814c416636
|
@ -621,6 +621,8 @@ class VarRegion : public DeclRegion {
|
||||||
public:
|
public:
|
||||||
const VarDecl *getDecl() const { return cast<VarDecl>(D); }
|
const VarDecl *getDecl() const { return cast<VarDecl>(D); }
|
||||||
|
|
||||||
|
const StackFrameContext *getStackFrame() const;
|
||||||
|
|
||||||
QualType getValueType(ASTContext& C) const {
|
QualType getValueType(ASTContext& C) const {
|
||||||
// FIXME: We can cache this if needed.
|
// FIXME: We can cache this if needed.
|
||||||
return C.getCanonicalType(getDecl()->getType());
|
return C.getCanonicalType(getDecl()->getType());
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace clang {
|
||||||
class MemRegion;
|
class MemRegion;
|
||||||
class TypedRegion;
|
class TypedRegion;
|
||||||
class VarRegion;
|
class VarRegion;
|
||||||
|
class StackFrameContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
@ -333,10 +334,13 @@ class SymbolReaper {
|
||||||
SetTy TheDead;
|
SetTy TheDead;
|
||||||
LiveVariables& Liveness;
|
LiveVariables& Liveness;
|
||||||
SymbolManager& SymMgr;
|
SymbolManager& SymMgr;
|
||||||
|
const StackFrameContext *CurrentStackFrame;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr)
|
SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr,
|
||||||
: Liveness(liveness), SymMgr(symmgr) {}
|
const StackFrameContext *currentStackFrame)
|
||||||
|
: Liveness(liveness), SymMgr(symmgr), CurrentStackFrame(currentStackFrame)
|
||||||
|
{}
|
||||||
|
|
||||||
~SymbolReaper() {}
|
~SymbolReaper() {}
|
||||||
|
|
||||||
|
|
|
@ -394,8 +394,9 @@ void GRExprEngine::ProcessStmt(Stmt* S, GRStmtNodeBuilder& builder) {
|
||||||
Builder->setAuditor(BatchAuditor.get());
|
Builder->setAuditor(BatchAuditor.get());
|
||||||
|
|
||||||
// Create the cleaned state.
|
// Create the cleaned state.
|
||||||
SymbolReaper SymReaper(Builder->getBasePredecessor()->getLiveVariables(),
|
const ExplodedNode *BasePred = Builder->getBasePredecessor();
|
||||||
SymMgr);
|
SymbolReaper SymReaper(BasePred->getLiveVariables(), SymMgr,
|
||||||
|
BasePred->getLocationContext()->getCurrentStackFrame());
|
||||||
CleanedState = AMgr.shouldPurgeDead()
|
CleanedState = AMgr.shouldPurgeDead()
|
||||||
? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, SymReaper)
|
? StateMgr.RemoveDeadBindings(EntryNode->getState(), CurrentStmt, SymReaper)
|
||||||
: EntryNode->getState();
|
: EntryNode->getState();
|
||||||
|
|
|
@ -165,6 +165,15 @@ MemRegionManager* SubRegion::getMemRegionManager() const {
|
||||||
} while (1);
|
} 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 {
|
void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
|
||||||
ID.AddInteger((unsigned)getKind());
|
ID.AddInteger((unsigned)getKind());
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,8 @@ bool SymbolReaper::isLive(SymbolRef sym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SymbolReaper::isLive(const Stmt *Loc, const VarRegion *VR) const {
|
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() {}
|
SymbolVisitor::~SymbolVisitor() {}
|
||||||
|
|
|
@ -618,3 +618,21 @@ typedef void (^RDar_7462324_Callback)(id obj);
|
||||||
}
|
}
|
||||||
@end
|
@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();
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue