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:
|
||||
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());
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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();
|
||||
}();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue