[analyzer] Only allocate retain summaries for interesting functions/messages. This is a minor saving of memory but doesn't seem to cost any performance.

llvm-svn: 138320
This commit is contained in:
Jordy Rose 2011-08-23 04:27:15 +00:00
parent fd6cb64c48
commit 212e459164
1 changed files with 74 additions and 46 deletions

View File

@ -160,6 +160,10 @@ public:
K == OwnedWhenTrackedReceiver;
}
bool operator==(const RetEffect &Other) const {
return K == Other.K && O == Other.O;
}
static RetEffect MakeOwnedWhenTrackedReceiver() {
return RetEffect(OwnedWhenTrackedReceiver, ObjC);
}
@ -452,6 +456,14 @@ public:
/// getReceiverEffect - Returns the effect on the receiver of the call.
/// This is only meaningful if the summary applies to an ObjCMessageExpr*.
ArgEffect getReceiverEffect() const { return Receiver; }
/// Test if two retain summaries are identical. Note that merely equivalent
/// summaries are not necessarily identical (for example, if an explicit
/// argument effect matches the default effect).
bool operator==(const RetainSummary &Other) const {
return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
Receiver == Other.Receiver && Ret == Other.Ret;
}
};
} // end anonymous namespace
@ -654,11 +666,6 @@ class RetainSummaryManager {
public:
RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
RetainSummary *getDefaultSummary() {
RetainSummary *Summ = (RetainSummary*) BPAlloc.Allocate<RetainSummary>();
return new (Summ) RetainSummary(DefaultSummary);
}
RetainSummary* getUnarySummary(const FunctionType* FT, UnaryFuncKind func);
RetainSummary* getCFSummaryCreateRule(const FunctionDecl *FD);
@ -828,10 +835,10 @@ public:
RetainSummary* getCommonMethodSummary(const ObjCMethodDecl *MD,
Selector S, QualType RetTy);
void updateSummaryFromAnnotations(RetainSummary &Summ,
void updateSummaryFromAnnotations(RetainSummary *&Summ,
const ObjCMethodDecl *MD);
void updateSummaryFromAnnotations(RetainSummary &Summ,
void updateSummaryFromAnnotations(RetainSummary *&Summ,
const FunctionDecl *FD);
bool isGCEnabled() const { return GCEnabled; }
@ -1078,12 +1085,8 @@ RetainSummary* RetainSummaryManager::getSummary(const FunctionDecl *FD) {
}
while (0);
if (!S)
S = getDefaultSummary();
// Annotations override defaults.
assert(S);
updateSummaryFromAnnotations(*S, FD);
updateSummaryFromAnnotations(S, FD);
FuncSummaries[FD] = S;
return S;
@ -1154,26 +1157,30 @@ RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
coreFoundation::isCFObjectRef(RetTy))
return getPersistentSummary(ObjCInitRetE, DecRefMsg);
return getDefaultSummary();
return 0;
}
void
RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
const FunctionDecl *FD) {
if (!FD)
return;
RetainSummary BasedOnDefault(DefaultSummary);
if (!Summ)
Summ = &BasedOnDefault;
// Effects on the parameters.
unsigned parm_idx = 0;
for (FunctionDecl::param_const_iterator pi = FD->param_begin(),
pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
const ParmVarDecl *pd = *pi;
if (pd->getAttr<NSConsumedAttr>()) {
if (!GCEnabled)
Summ.addArg(AF, parm_idx, DecRef);
}
else if(pd->getAttr<CFConsumedAttr>()) {
Summ.addArg(AF, parm_idx, DecRef);
if (!GCEnabled) {
Summ->addArg(AF, parm_idx, DecRef);
}
} else if (pd->getAttr<CFConsumedAttr>()) {
Summ->addArg(AF, parm_idx, DecRef);
}
}
@ -1182,40 +1189,50 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
// Determine if there is a special return effect for this method.
if (cocoa::isCocoaObjectRef(RetTy)) {
if (FD->getAttr<NSReturnsRetainedAttr>()) {
Summ.setRetEffect(ObjCAllocRetE);
Summ->setRetEffect(ObjCAllocRetE);
}
else if (FD->getAttr<CFReturnsRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
else if (FD->getAttr<NSReturnsNotRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
}
else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
}
} else if (RetTy->getAs<PointerType>()) {
if (FD->getAttr<CFReturnsRetainedAttr>()) {
Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
}
}
else if (RetTy->getAs<PointerType>()) {
if (FD->getAttr<CFReturnsRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
}
if (Summ == &BasedOnDefault) {
if (!(*Summ == DefaultSummary))
Summ = copySummary(Summ);
else
Summ = 0;
}
}
void
RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary *&Summ,
const ObjCMethodDecl *MD) {
if (!MD)
return;
RetainSummary BasedOnDefault = DefaultSummary;
if (!Summ)
Summ = &BasedOnDefault;
bool isTrackedLoc = false;
// Effects on the receiver.
if (MD->getAttr<NSConsumesSelfAttr>()) {
if (!GCEnabled)
Summ.setReceiverEffect(DecRefMsg);
Summ->setReceiverEffect(DecRefMsg);
}
// Effects on the parameters.
@ -1225,21 +1242,21 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
const ParmVarDecl *pd = *pi;
if (pd->getAttr<NSConsumedAttr>()) {
if (!GCEnabled)
Summ.addArg(AF, parm_idx, DecRef);
Summ->addArg(AF, parm_idx, DecRef);
}
else if(pd->getAttr<CFConsumedAttr>()) {
Summ.addArg(AF, parm_idx, DecRef);
Summ->addArg(AF, parm_idx, DecRef);
}
}
// Determine if there is a special return effect for this method.
if (cocoa::isCocoaObjectRef(MD->getResultType())) {
if (MD->getAttr<NSReturnsRetainedAttr>()) {
Summ.setRetEffect(ObjCAllocRetE);
Summ->setRetEffect(ObjCAllocRetE);
return;
}
if (MD->getAttr<NSReturnsNotRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
return;
}
@ -1251,9 +1268,16 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
if (isTrackedLoc) {
if (MD->getAttr<CFReturnsRetainedAttr>())
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
Summ->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
else if (MD->getAttr<CFReturnsNotRetainedAttr>())
Summ.setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
Summ->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
}
if (Summ == &BasedOnDefault) {
if (!(*Summ == DefaultSummary))
Summ = copySummary(Summ);
else
Summ = 0;
}
}
@ -1310,7 +1334,7 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl *MD,
}
if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
return getDefaultSummary();
return 0;
return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff, MayEscape);
}
@ -1355,8 +1379,7 @@ RetainSummaryManager::getInstanceMethodSummary(const ObjCMessage &msg,
// FIXME: The receiver could be a reference to a class, meaning that
// we should use the class method.
RetainSummary *Summ = getInstanceMethodSummary(msg, ID);
return Summ ? Summ : getDefaultSummary();
return getInstanceMethodSummary(msg, ID);
}
RetainSummary*
@ -1379,7 +1402,7 @@ RetainSummaryManager::getInstanceMethodSummary(Selector S,
Summ = getCommonMethodSummary(MD, S, RetTy);
// Annotations override defaults.
updateSummaryFromAnnotations(*Summ, MD);
updateSummaryFromAnnotations(Summ, MD);
// Memoize the summary.
ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
@ -1399,8 +1422,10 @@ RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
if (!Summ) {
Summ = getCommonMethodSummary(MD, S, RetTy);
// Annotations override defaults.
updateSummaryFromAnnotations(*Summ, MD);
updateSummaryFromAnnotations(Summ, MD);
// Memoize the summary.
ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
}
@ -2743,10 +2768,13 @@ void CFRefCount::evalReturn(ExplodedNodeSet &Dst,
Decl const *CD = &Pred->getCodeDecl();
if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CD)) {
const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
// Unlike regular functions, /all/ ObjC methods are assumed to always
// follow Cocoa retain-count conventions, not just those with special
// names or attributes.
const RetainSummary *Summ = Summaries.getMethodSummary(MD);
RetEffect RE = Summ ? Summ->getRetEffect() : RetEffect::MakeNoRet();
return evalReturnWithRetEffect(Dst, Eng, Builder, S,
Pred, Summ.getRetEffect(), X,
Sym, state);
Pred, RE, X, Sym, state);
}
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CD)) {