retain/release checker: Refactor getMethodSummary() to not depend on ObjCMessageExpr.
llvm-svn: 70369
This commit is contained in:
parent
cc5d1c2e4e
commit
0b50fb1de1
|
|
@ -452,6 +452,12 @@ public:
|
||||||
|
|
||||||
typedef MapTy::iterator iterator;
|
typedef MapTy::iterator iterator;
|
||||||
|
|
||||||
|
iterator find(ObjCInterfaceDecl* D, IdentifierInfo *ClsName, Selector S) {
|
||||||
|
// Lookup the method using the decl for the class @interface. If we
|
||||||
|
// have no decl, lookup using the class name.
|
||||||
|
return D ? find(D, S) : find(ClsName, S);
|
||||||
|
}
|
||||||
|
|
||||||
iterator find(ObjCInterfaceDecl* D, Selector S) {
|
iterator find(ObjCInterfaceDecl* D, Selector S) {
|
||||||
|
|
||||||
// Do a lookup with the (D,S) pair. If we find a match return
|
// Do a lookup with the (D,S) pair. If we find a match return
|
||||||
|
|
@ -618,7 +624,7 @@ public:
|
||||||
return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff);
|
return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff);
|
||||||
}
|
}
|
||||||
|
|
||||||
RetainSummary* getPersistentStopSummary() {
|
RetainSummary *getPersistentStopSummary() {
|
||||||
if (StopSummary)
|
if (StopSummary)
|
||||||
return StopSummary;
|
return StopSummary;
|
||||||
|
|
||||||
|
|
@ -628,7 +634,7 @@ public:
|
||||||
return StopSummary;
|
return StopSummary;
|
||||||
}
|
}
|
||||||
|
|
||||||
RetainSummary* getInitMethodSummary(ObjCMessageExpr* ME);
|
RetainSummary *getInitMethodSummary(QualType RetTy);
|
||||||
|
|
||||||
void InitializeClassMethodSummaries();
|
void InitializeClassMethodSummaries();
|
||||||
void InitializeMethodSummaries();
|
void InitializeMethodSummaries();
|
||||||
|
|
@ -723,7 +729,15 @@ public:
|
||||||
~RetainSummaryManager();
|
~RetainSummaryManager();
|
||||||
|
|
||||||
RetainSummary* getSummary(FunctionDecl* FD);
|
RetainSummary* getSummary(FunctionDecl* FD);
|
||||||
RetainSummary* getMethodSummary(ObjCMessageExpr* ME, ObjCInterfaceDecl* ID);
|
|
||||||
|
RetainSummary* getMethodSummary(ObjCMessageExpr* ME, ObjCInterfaceDecl* ID) {
|
||||||
|
return getMethodSummary(ME->getSelector(), ME->getClassName(),
|
||||||
|
ID, ME->getMethodDecl(), ME->getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
RetainSummary* getMethodSummary(Selector S, IdentifierInfo *ClsName,
|
||||||
|
ObjCInterfaceDecl* ID,
|
||||||
|
ObjCMethodDecl *MD, QualType RetTy);
|
||||||
|
|
||||||
RetainSummary *getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
|
RetainSummary *getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
|
||||||
ObjCInterfaceDecl *ID,
|
ObjCInterfaceDecl *ID,
|
||||||
|
|
@ -1075,17 +1089,13 @@ RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
RetainSummary*
|
RetainSummary*
|
||||||
RetainSummaryManager::getInitMethodSummary(ObjCMessageExpr* ME) {
|
RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
|
||||||
assert(ScratchArgs.empty());
|
assert(ScratchArgs.empty());
|
||||||
|
|
||||||
// 'init' methods only return an alias if the return type is a location type.
|
// 'init' methods only return an alias if the return type is a location type.
|
||||||
QualType T = ME->getType();
|
return getPersistentSummary(Loc::IsLocType(RetTy)
|
||||||
RetainSummary* Summ =
|
? RetEffect::MakeReceiverAlias()
|
||||||
getPersistentSummary(Loc::IsLocType(T) ? RetEffect::MakeReceiverAlias()
|
|
||||||
: RetEffect::MakeNoRet());
|
: RetEffect::MakeNoRet());
|
||||||
|
|
||||||
ObjCMethodSummaries[ME] = Summ;
|
|
||||||
return Summ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RetainSummary*
|
RetainSummary*
|
||||||
|
|
@ -1198,13 +1208,12 @@ RetainSummaryManager::getCommonMethodSummary(ObjCMethodDecl* MD, Selector S,
|
||||||
}
|
}
|
||||||
|
|
||||||
RetainSummary*
|
RetainSummary*
|
||||||
RetainSummaryManager::getMethodSummary(ObjCMessageExpr* ME,
|
RetainSummaryManager::getMethodSummary(Selector S, IdentifierInfo *ClsName,
|
||||||
ObjCInterfaceDecl* ID) {
|
ObjCInterfaceDecl* ID,
|
||||||
|
ObjCMethodDecl *MD, QualType RetTy) {
|
||||||
Selector S = ME->getSelector();
|
|
||||||
|
|
||||||
// Look up a summary in our summary cache.
|
// Look up a summary in our summary cache.
|
||||||
ObjCMethodSummariesTy::iterator I = ObjCMethodSummaries.find(ID, S);
|
ObjCMethodSummariesTy::iterator I = ObjCMethodSummaries.find(ID, ClsName, S);
|
||||||
|
|
||||||
if (I != ObjCMethodSummaries.end())
|
if (I != ObjCMethodSummaries.end())
|
||||||
return I->second;
|
return I->second;
|
||||||
|
|
@ -1213,18 +1222,18 @@ RetainSummaryManager::getMethodSummary(ObjCMessageExpr* ME,
|
||||||
|
|
||||||
// Annotations take precedence over all other ways to derive
|
// Annotations take precedence over all other ways to derive
|
||||||
// summaries.
|
// summaries.
|
||||||
RetainSummary *Summ = getMethodSummaryFromAnnotations(ME->getMethodDecl());
|
RetainSummary *Summ = getMethodSummaryFromAnnotations(MD);
|
||||||
|
|
||||||
if (!Summ) {
|
if (!Summ) {
|
||||||
// "initXXX": pass-through for receiver.
|
// "initXXX": pass-through for receiver.
|
||||||
if (deriveNamingConvention(S.getIdentifierInfoForSlot(0)->getName())
|
if (deriveNamingConvention(S.getIdentifierInfoForSlot(0)->getName())
|
||||||
== InitRule)
|
== InitRule)
|
||||||
return getInitMethodSummary(ME);
|
Summ = getInitMethodSummary(RetTy);
|
||||||
|
else
|
||||||
Summ = getCommonMethodSummary(ME->getMethodDecl(), S, ME->getType());
|
Summ = getCommonMethodSummary(MD, S, RetTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjCMethodSummaries[ME] = Summ;
|
ObjCMethodSummaries[ObjCSummaryKey(ClsName, S)] = Summ;
|
||||||
return Summ;
|
return Summ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1234,17 +1243,8 @@ RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
|
||||||
ObjCMethodDecl *MD, QualType RetTy){
|
ObjCMethodDecl *MD, QualType RetTy){
|
||||||
|
|
||||||
assert(ClsName && "Class name must be specified.");
|
assert(ClsName && "Class name must be specified.");
|
||||||
ObjCMethodSummariesTy::iterator I;
|
ObjCMethodSummariesTy::iterator I =
|
||||||
|
ObjCClassMethodSummaries.find(ID, ClsName, S);
|
||||||
if (ID) {
|
|
||||||
// Lookup the method using the decl for the class @interface.
|
|
||||||
I = ObjCClassMethodSummaries.find(ID, S);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Fallback to using the class name.
|
|
||||||
// Look up a summary in our cache of Selectors -> Summaries.
|
|
||||||
I = ObjCClassMethodSummaries.find(ClsName, S);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (I != ObjCClassMethodSummaries.end())
|
if (I != ObjCClassMethodSummaries.end())
|
||||||
return I->second;
|
return I->second;
|
||||||
|
|
@ -2126,6 +2126,8 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
|
||||||
|
|
||||||
// FIXME: Wouldn't it be great if this code could be reduced? It's just
|
// FIXME: Wouldn't it be great if this code could be reduced? It's just
|
||||||
// a chain of lookups.
|
// a chain of lookups.
|
||||||
|
// FIXME: Is this really working as expected? There are cases where
|
||||||
|
// we just use the 'ID' from the message expression.
|
||||||
const GRState* St = Builder.GetState(Pred);
|
const GRState* St = Builder.GetState(Pred);
|
||||||
SVal V = Eng.getStateManager().GetSValAsScalarOrLoc(St, Receiver);
|
SVal V = Eng.getStateManager().GetSValAsScalarOrLoc(St, Receiver);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue