Add panic support for NSAssertionHandler.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53758 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2008-07-18 17:24:20 +00:00
Родитель c8aeb655c3
Коммит 70a733e64e
2 изменённых файлов: 75 добавлений и 8 удалений

Просмотреть файл

@ -254,6 +254,15 @@ public:
return N;
}
NodeTy* MakeSinkNode(ExplodedNodeSet<StateTy>& Dst, Stmt* S,
NodeTy* Pred, const StateTy* St) {
bool Tmp = BuildSinks;
BuildSinks = true;
NodeTy* N = MakeNode(Dst, S, Pred, St);
BuildSinks = Tmp;
return N;
}
bool PurgingDeadSymbols;
bool BuildSinks;
bool HasGeneratedNode;

Просмотреть файл

@ -208,11 +208,16 @@ class VISIBILITY_HIDDEN RetainSummary : public llvm::FoldingSetNode {
/// alias of one of the arguments in the call, and so on.
RetEffect Ret;
/// EndPath - Indicates that execution of this method/function should
/// terminate the simulation of a path.
bool EndPath;
public:
RetainSummary(ArgEffects* A, RetEffect R, ArgEffect defaultEff,
ArgEffect ReceiverEff)
: Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R) {}
ArgEffect ReceiverEff, bool endpath = false)
: Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R),
EndPath(endpath) {}
/// getArg - Return the argument effect on the argument specified by
/// idx (starting from 0).
@ -243,6 +248,10 @@ public:
return Ret;
}
/// isEndPath - Returns true if executing the given method/function should
/// terminate the path.
bool isEndPath() const { return EndPath; }
/// getReceiverEffect - Returns the effect on the receiver of the call.
/// This is only meaningful if the summary applies to an ObjCMessageExpr*.
ArgEffect getReceiverEffect() const {
@ -446,6 +455,10 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
/// NSPanelII - An IdentifierInfo* representing the identifier "NSPanel."
IdentifierInfo* NSPanelII;
/// NSAssertionHandlerII - An IdentifierInfo* representing the identifier
// "NSAssertionHandler".
IdentifierInfo* NSAssertionHandlerII;
/// CFDictionaryCreateII - An IdentifierInfo* representing the indentifier
/// "CFDictionaryCreate".
IdentifierInfo* CFDictionaryCreateII;
@ -499,7 +512,8 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
RetainSummary* getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
ArgEffect ReceiverEff = DoNothing,
ArgEffect DefaultEff = MayEscape);
ArgEffect DefaultEff = MayEscape,
bool isEndPath = false);
RetainSummary* getPersistentSummary(RetEffect RE,
@ -523,7 +537,12 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
void InitializeClassMethodSummaries();
void InitializeMethodSummaries();
void addClsMethSummary(IdentifierInfo* ClsII, Selector S,
RetainSummary* Summ) {
ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
}
void addNSObjectClsMethSummary(Selector S, RetainSummary *Summ) {
ObjCClassMethodSummaries[S] = Summ;
}
@ -540,12 +559,20 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
ObjCMethodSummaries[ObjCSummaryKey(NSPanelII, S)] = Summ;
}
void addPanicSummary(IdentifierInfo* ClsII, Selector S) {
RetainSummary* Summ = getPersistentSummary(0, RetEffect::MakeNoRet(),
DoNothing, DoNothing, true);
ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
}
public:
RetainSummaryManager(ASTContext& ctx, bool gcenabled)
: Ctx(ctx),
NSWindowII(&ctx.Idents.get("NSWindow")),
NSPanelII(&ctx.Idents.get("NSPanel")),
NSAssertionHandlerII(&ctx.Idents.get("NSAssertionHandler")),
CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
GCEnabled(gcenabled), StopSummary(0) {
@ -611,7 +638,8 @@ ArgEffects* RetainSummaryManager::getArgEffects() {
RetainSummary*
RetainSummaryManager::getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
ArgEffect ReceiverEff,
ArgEffect DefaultEff) {
ArgEffect DefaultEff,
bool isEndPath) {
// Generate a profile for the summary.
llvm::FoldingSetNodeID profile;
@ -626,7 +654,7 @@ RetainSummaryManager::getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
// Create the summary and return it.
Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
new (Summ) RetainSummary(AE, RetEff, DefaultEff, ReceiverEff);
new (Summ) RetainSummary(AE, RetEff, DefaultEff, ReceiverEff, isEndPath);
SummarySet.InsertNode(Summ, InsertPos);
return Summ;
@ -929,6 +957,11 @@ void RetainSummaryManager::InitializeClassMethodSummaries() {
addNSObjectClsMethSummary(GetNullarySelector("alloc", Ctx), Summ);
addNSObjectClsMethSummary(GetNullarySelector("new", Ctx), Summ);
addNSObjectClsMethSummary(GetUnarySelector("allocWithZone", Ctx), Summ);
// Create the [NSAssertionHandler currentHander] summary.
addClsMethSummary(NSAssertionHandlerII,
GetUnarySelector("currentHandler", Ctx),
getPersistentSummary(RetEffect::MakeNotOwned()));
}
void RetainSummaryManager::InitializeMethodSummaries() {
@ -991,6 +1024,23 @@ void RetainSummaryManager::InitializeMethodSummaries() {
S = Ctx.Selectors.getSelector(II.size(), &II[0]);
addNSWindowMethSummary(S, NSWindowSumm);
addNSPanelMethSummary(S, InitSumm);
// Create NSAssertionHandler summaries.
II.clear();
II.push_back(&Ctx.Idents.get("handleFailureInFunction"));
II.push_back(&Ctx.Idents.get("file"));
II.push_back(&Ctx.Idents.get("lineNumber"));
II.push_back(&Ctx.Idents.get("description"));
S = Ctx.Selectors.getSelector(II.size(), &II[0]);
addPanicSummary(NSAssertionHandlerII, S);
II.clear();
II.push_back(&Ctx.Idents.get("handleFailureInMethod"));
II.push_back(&Ctx.Idents.get("file"));
II.push_back(&Ctx.Idents.get("lineNumber"));
II.push_back(&Ctx.Idents.get("description"));
S = Ctx.Selectors.getSelector(II.size(), &II[0]);
addPanicSummary(NSAssertionHandlerII, S);
}
//===----------------------------------------------------------------------===//
@ -1375,6 +1425,10 @@ static inline ArgEffect GetReceiverE(RetainSummary* Summ) {
return Summ ? Summ->getReceiverEffect() : DoNothing;
}
static inline bool IsEndPath(RetainSummary* Summ) {
return Summ ? Summ->isEndPath() : false;
}
void CFRefCount::ProcessNonLeakError(ExplodedNodeSet<ValueState>& Dst,
GRStmtNodeBuilder<ValueState>& Builder,
Expr* NodeExpr, Expr* ErrorExpr,
@ -1549,7 +1603,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<ValueState>& Dst,
return;
}
// Finally, consult the summary for the return value.
// Consult the summary for the return value.
RetEffect RE = GetRetEffect(Summ);
switch (RE.getKind()) {
@ -1630,7 +1684,11 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<ValueState>& Dst,
}
}
Builder.MakeNode(Dst, Ex, Pred, St);
// Is this a sink?
if (IsEndPath(Summ))
Builder.MakeSinkNode(Dst, Ex, Pred, St);
else
Builder.MakeNode(Dst, Ex, Pred, St);
}