зеркало из https://github.com/microsoft/clang-1.git
Add variadic addInstMethSummary() and refactored addPanicSummary() to use this method. (code reduction).
Misc. cleanups. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54694 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
1fb57688d9
Коммит
9e476ded1d
|
@ -457,10 +457,6 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
|
||||||
/// NSPanelII - An IdentifierInfo* representing the identifier "NSPanel."
|
/// NSPanelII - An IdentifierInfo* representing the identifier "NSPanel."
|
||||||
IdentifierInfo* NSPanelII;
|
IdentifierInfo* NSPanelII;
|
||||||
|
|
||||||
/// NSAssertionHandlerII - An IdentifierInfo* representing the identifier
|
|
||||||
// "NSAssertionHandler".
|
|
||||||
IdentifierInfo* NSAssertionHandlerII;
|
|
||||||
|
|
||||||
/// CFDictionaryCreateII - An IdentifierInfo* representing the indentifier
|
/// CFDictionaryCreateII - An IdentifierInfo* representing the indentifier
|
||||||
/// "CFDictionaryCreate".
|
/// "CFDictionaryCreate".
|
||||||
IdentifierInfo* CFDictionaryCreateII;
|
IdentifierInfo* CFDictionaryCreateII;
|
||||||
|
@ -561,12 +557,26 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
|
||||||
ObjCMethodSummaries[ObjCSummaryKey(NSPanelII, S)] = Summ;
|
ObjCMethodSummaries[ObjCSummaryKey(NSPanelII, S)] = Summ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addPanicSummary(IdentifierInfo* ClsII, Selector S) {
|
void addInstMethSummary(RetainSummary* Summ, const char* Cls, va_list argp) {
|
||||||
RetainSummary* Summ = getPersistentSummary(0, RetEffect::MakeNoRet(),
|
|
||||||
DoNothing, DoNothing, true);
|
|
||||||
|
|
||||||
|
IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
|
||||||
|
llvm::SmallVector<IdentifierInfo*, 10> II;
|
||||||
|
|
||||||
|
while (const char* s = va_arg(argp, const char*))
|
||||||
|
II.push_back(&Ctx.Idents.get(s));
|
||||||
|
|
||||||
|
Selector S = Ctx.Selectors.getSelector(II.size(), &II[0]);
|
||||||
ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
|
ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addPanicSummary(const char* Cls, ...) {
|
||||||
|
RetainSummary* Summ = getPersistentSummary(0, RetEffect::MakeNoRet(),
|
||||||
|
DoNothing, DoNothing, true);
|
||||||
|
va_list argp;
|
||||||
|
va_start (argp, Cls);
|
||||||
|
addInstMethSummary(Summ, Cls, argp);
|
||||||
|
va_end(argp);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -574,7 +584,6 @@ public:
|
||||||
: Ctx(ctx),
|
: Ctx(ctx),
|
||||||
NSWindowII(&ctx.Idents.get("NSWindow")),
|
NSWindowII(&ctx.Idents.get("NSWindow")),
|
||||||
NSPanelII(&ctx.Idents.get("NSPanel")),
|
NSPanelII(&ctx.Idents.get("NSPanel")),
|
||||||
NSAssertionHandlerII(&ctx.Idents.get("NSAssertionHandler")),
|
|
||||||
CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
|
CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
|
||||||
GCEnabled(gcenabled), StopSummary(0) {
|
GCEnabled(gcenabled), StopSummary(0) {
|
||||||
|
|
||||||
|
@ -962,7 +971,7 @@ void RetainSummaryManager::InitializeClassMethodSummaries() {
|
||||||
addNSObjectClsMethSummary(GetUnarySelector("allocWithZone", Ctx), Summ);
|
addNSObjectClsMethSummary(GetUnarySelector("allocWithZone", Ctx), Summ);
|
||||||
|
|
||||||
// Create the [NSAssertionHandler currentHander] summary.
|
// Create the [NSAssertionHandler currentHander] summary.
|
||||||
addClsMethSummary(NSAssertionHandlerII,
|
addClsMethSummary(&Ctx.Idents.get("NSAssertionHandler"),
|
||||||
GetNullarySelector("currentHandler", Ctx),
|
GetNullarySelector("currentHandler", Ctx),
|
||||||
getPersistentSummary(RetEffect::MakeNotOwned()));
|
getPersistentSummary(RetEffect::MakeNotOwned()));
|
||||||
}
|
}
|
||||||
|
@ -1029,22 +1038,11 @@ void RetainSummaryManager::InitializeMethodSummaries() {
|
||||||
addNSPanelMethSummary(S, InitSumm);
|
addNSPanelMethSummary(S, InitSumm);
|
||||||
|
|
||||||
// Create NSAssertionHandler summaries.
|
// Create NSAssertionHandler summaries.
|
||||||
II.clear();
|
addPanicSummary("NSAssertionHandler", "handleFailureInFunction", "file",
|
||||||
II.push_back(&Ctx.Idents.get("handleFailureInFunction"));
|
"lineNumber", "description", NULL);
|
||||||
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();
|
addPanicSummary("NSAssertionHandler", "handleFailureInMethod", "object",
|
||||||
II.push_back(&Ctx.Idents.get("handleFailureInMethod"));
|
"file", "lineNumber", "description", NULL);
|
||||||
II.push_back(&Ctx.Idents.get("object"));
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -1243,21 +1241,13 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Instance variables.
|
|
||||||
|
|
||||||
RetainSummaryManager Summaries;
|
RetainSummaryManager Summaries;
|
||||||
const LangOptions& LOpts;
|
const LangOptions& LOpts;
|
||||||
RefBFactoryTy RefBFactory;
|
RefBFactoryTy RefBFactory;
|
||||||
|
UseAfterReleasesTy UseAfterReleases;
|
||||||
UseAfterReleasesTy UseAfterReleases;
|
ReleasesNotOwnedTy ReleasesNotOwned;
|
||||||
ReleasesNotOwnedTy ReleasesNotOwned;
|
LeaksTy Leaks;
|
||||||
LeaksTy Leaks;
|
BindingsPrinter Printer;
|
||||||
|
|
||||||
BindingsPrinter Printer;
|
|
||||||
|
|
||||||
Selector RetainSelector;
|
|
||||||
Selector ReleaseSelector;
|
|
||||||
Selector AutoreleaseSelector;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -1296,10 +1286,7 @@ public:
|
||||||
|
|
||||||
CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
|
CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
|
||||||
: Summaries(Ctx, gcenabled),
|
: Summaries(Ctx, gcenabled),
|
||||||
LOpts(lopts),
|
LOpts(lopts) {}
|
||||||
RetainSelector(GetNullarySelector("retain", Ctx)),
|
|
||||||
ReleaseSelector(GetNullarySelector("release", Ctx)),
|
|
||||||
AutoreleaseSelector(GetNullarySelector("autorelease", Ctx)) {}
|
|
||||||
|
|
||||||
virtual ~CFRefCount() {
|
virtual ~CFRefCount() {
|
||||||
for (LeaksTy::iterator I = Leaks.begin(), E = Leaks.end(); I!=E; ++I)
|
for (LeaksTy::iterator I = Leaks.begin(), E = Leaks.end(); I!=E; ++I)
|
||||||
|
@ -1697,29 +1684,19 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
|
||||||
GRStmtNodeBuilder<ValueState>& Builder,
|
GRStmtNodeBuilder<ValueState>& Builder,
|
||||||
CallExpr* CE, RVal L,
|
CallExpr* CE, RVal L,
|
||||||
ExplodedNode<ValueState>* Pred) {
|
ExplodedNode<ValueState>* Pred) {
|
||||||
|
|
||||||
|
|
||||||
RetainSummary* Summ = NULL;
|
|
||||||
|
|
||||||
// Get the summary.
|
|
||||||
|
|
||||||
if (isa<lval::FuncVal>(L)) {
|
RetainSummary* Summ = !isa<lval::FuncVal>(L) ? 0
|
||||||
lval::FuncVal FV = cast<lval::FuncVal>(L);
|
: Summaries.getSummary(cast<lval::FuncVal>(L).getDecl());
|
||||||
FunctionDecl* FD = FV.getDecl();
|
|
||||||
Summ = Summaries.getSummary(FD);
|
|
||||||
}
|
|
||||||
|
|
||||||
EvalSummary(Dst, Eng, Builder, CE, 0, Summ,
|
EvalSummary(Dst, Eng, Builder, CE, 0, Summ,
|
||||||
CE->arg_begin(), CE->arg_end(), Pred);
|
CE->arg_begin(), CE->arg_end(), Pred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
|
void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
|
||||||
GRExprEngine& Eng,
|
GRExprEngine& Eng,
|
||||||
GRStmtNodeBuilder<ValueState>& Builder,
|
GRStmtNodeBuilder<ValueState>& Builder,
|
||||||
ObjCMessageExpr* ME,
|
ObjCMessageExpr* ME,
|
||||||
ExplodedNode<ValueState>* Pred) {
|
ExplodedNode<ValueState>* Pred) {
|
||||||
|
|
||||||
RetainSummary* Summ;
|
RetainSummary* Summ;
|
||||||
|
|
||||||
if (Expr* Receiver = ME->getReceiver()) {
|
if (Expr* Receiver = ME->getReceiver()) {
|
||||||
|
@ -1976,7 +1953,6 @@ const ValueState* CFRefCount::EvalAssume(ValueStateManager& VMgr,
|
||||||
// too bad since the number of symbols we will track in practice are
|
// too bad since the number of symbols we will track in practice are
|
||||||
// probably small and EvalAssume is only called at branches and a few
|
// probably small and EvalAssume is only called at branches and a few
|
||||||
// other places.
|
// other places.
|
||||||
|
|
||||||
RefBindings B = GetRefBindings(*St);
|
RefBindings B = GetRefBindings(*St);
|
||||||
|
|
||||||
if (B.isEmpty())
|
if (B.isEmpty())
|
||||||
|
@ -1985,10 +1961,8 @@ const ValueState* CFRefCount::EvalAssume(ValueStateManager& VMgr,
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
|
for (RefBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I) {
|
||||||
|
|
||||||
// Check if the symbol is null (or equal to any constant).
|
// Check if the symbol is null (or equal to any constant).
|
||||||
// If this is the case, stop tracking the symbol.
|
// If this is the case, stop tracking the symbol.
|
||||||
|
|
||||||
if (St->getSymVal(I.getKey())) {
|
if (St->getSymVal(I.getKey())) {
|
||||||
changed = true;
|
changed = true;
|
||||||
B = RefBFactory.Remove(B, I.getKey());
|
B = RefBFactory.Remove(B, I.getKey());
|
||||||
|
@ -2019,23 +1993,20 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
|
||||||
V = V ^ RefVal::NotOwned;
|
V = V ^ RefVal::NotOwned;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall-through.
|
// Fall-through.
|
||||||
|
|
||||||
case DoNothingByRef:
|
case DoNothingByRef:
|
||||||
case DoNothing:
|
case DoNothing:
|
||||||
if (!isGCEnabled() && V.getKind() == RefVal::Released) {
|
if (!isGCEnabled() && V.getKind() == RefVal::Released) {
|
||||||
V = V ^ RefVal::ErrorUseAfterRelease;
|
V = V ^ RefVal::ErrorUseAfterRelease;
|
||||||
hasErr = V.getKind();
|
hasErr = V.getKind();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B;
|
return B;
|
||||||
|
|
||||||
case Autorelease:
|
case Autorelease:
|
||||||
case StopTracking:
|
case StopTracking:
|
||||||
return RefBFactory.Remove(B, sym);
|
return RefBFactory.Remove(B, sym);
|
||||||
|
|
||||||
case IncRef:
|
case IncRef:
|
||||||
switch (V.getKind()) {
|
switch (V.getKind()) {
|
||||||
default:
|
default:
|
||||||
|
@ -2044,8 +2015,7 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
|
||||||
case RefVal::Owned:
|
case RefVal::Owned:
|
||||||
case RefVal::NotOwned:
|
case RefVal::NotOwned:
|
||||||
V = V + 1;
|
V = V + 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RefVal::Released:
|
case RefVal::Released:
|
||||||
if (isGCEnabled())
|
if (isGCEnabled())
|
||||||
V = V ^ RefVal::Owned;
|
V = V ^ RefVal::Owned;
|
||||||
|
@ -2053,20 +2023,18 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
|
||||||
V = V ^ RefVal::ErrorUseAfterRelease;
|
V = V ^ RefVal::ErrorUseAfterRelease;
|
||||||
hasErr = V.getKind();
|
hasErr = V.getKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelfOwn:
|
case SelfOwn:
|
||||||
V = V ^ RefVal::NotOwned;
|
V = V ^ RefVal::NotOwned;
|
||||||
|
// Fall-through.
|
||||||
case DecRef:
|
case DecRef:
|
||||||
switch (V.getKind()) {
|
switch (V.getKind()) {
|
||||||
default:
|
default:
|
||||||
assert (false);
|
assert (false);
|
||||||
|
|
||||||
case RefVal::Owned:
|
case RefVal::Owned:
|
||||||
V = V.getCount() > 1 ? V - 1 : V ^ RefVal::Released;
|
V = V.getCount() > 1 ? V - 1 : V ^ RefVal::Released;
|
||||||
break;
|
break;
|
||||||
|
@ -2077,23 +2045,19 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
|
||||||
else {
|
else {
|
||||||
V = V ^ RefVal::ErrorReleaseNotOwned;
|
V = V ^ RefVal::ErrorReleaseNotOwned;
|
||||||
hasErr = V.getKind();
|
hasErr = V.getKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RefVal::Released:
|
case RefVal::Released:
|
||||||
V = V ^ RefVal::ErrorUseAfterRelease;
|
V = V ^ RefVal::ErrorUseAfterRelease;
|
||||||
hasErr = V.getKind();
|
hasErr = V.getKind();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RefBFactory.Add(B, sym, V);
|
return RefBFactory.Add(B, sym, V);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Error reporting.
|
// Error reporting.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -2125,8 +2089,7 @@ namespace {
|
||||||
return "Use-After-Release";
|
return "Use-After-Release";
|
||||||
}
|
}
|
||||||
virtual const char* getDescription() const {
|
virtual const char* getDescription() const {
|
||||||
return "Reference-counted object is used"
|
return "Reference-counted object is used after it is released.";
|
||||||
" after it is released.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void EmitWarnings(BugReporter& BR);
|
virtual void EmitWarnings(BugReporter& BR);
|
||||||
|
@ -2165,7 +2128,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* getDescription() const {
|
virtual const char* getDescription() const {
|
||||||
return "Object leaked.";
|
return "Object leaked";
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void EmitWarnings(BugReporter& BR);
|
virtual void EmitWarnings(BugReporter& BR);
|
||||||
|
@ -2198,10 +2161,8 @@ namespace {
|
||||||
|
|
||||||
if (!getBugType().isLeak())
|
if (!getBugType().isLeak())
|
||||||
RangedBugReport::getRanges(BR, beg, end);
|
RangedBugReport::getRanges(BR, beg, end);
|
||||||
else {
|
else
|
||||||
beg = 0;
|
beg = end = 0;
|
||||||
end = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolID getSymbol() const { return Sym; }
|
SymbolID getSymbol() const { return Sym; }
|
||||||
|
@ -2249,8 +2210,8 @@ std::pair<const char**,const char**> CFRefReport::getExtraDescriptiveText() {
|
||||||
|
|
||||||
case LangOptions::GCOnly:
|
case LangOptions::GCOnly:
|
||||||
assert (TF.isGCEnabled());
|
assert (TF.isGCEnabled());
|
||||||
return std::make_pair(&Msgs[0], &Msgs[0]+1);
|
return std::make_pair(&Msgs[0], &Msgs[0]+1);
|
||||||
|
|
||||||
case LangOptions::NonGC:
|
case LangOptions::NonGC:
|
||||||
assert (!TF.isGCEnabled());
|
assert (!TF.isGCEnabled());
|
||||||
return std::make_pair(&Msgs[1], &Msgs[1]+1);
|
return std::make_pair(&Msgs[1], &Msgs[1]+1);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче