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:
Ted Kremenek 2008-08-12 18:30:56 +00:00
Родитель 1fb57688d9
Коммит 9e476ded1d
1 изменённых файлов: 45 добавлений и 84 удалений

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

@ -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);