Fix long-lurking bug in ObjCSummaryCache revealed by Torok's recent memory
poisoning changes to DenseMap. We were using an iterator after it had been invalidated by an insertion into the DenseMap. llvm-svn: 76677
This commit is contained in:
parent
3666c34db8
commit
8be513822c
|
|
@ -496,24 +496,22 @@ class VISIBILITY_HIDDEN ObjCSummaryCache {
|
||||||
MapTy M;
|
MapTy M;
|
||||||
public:
|
public:
|
||||||
ObjCSummaryCache() {}
|
ObjCSummaryCache() {}
|
||||||
|
|
||||||
typedef MapTy::iterator iterator;
|
RetainSummary* find(const ObjCInterfaceDecl* D, IdentifierInfo *ClsName,
|
||||||
|
|
||||||
iterator find(const ObjCInterfaceDecl* D, IdentifierInfo *ClsName,
|
|
||||||
Selector S) {
|
Selector S) {
|
||||||
// Lookup the method using the decl for the class @interface. If we
|
// Lookup the method using the decl for the class @interface. If we
|
||||||
// have no decl, lookup using the class name.
|
// have no decl, lookup using the class name.
|
||||||
return D ? find(D, S) : find(ClsName, S);
|
return D ? find(D, S) : find(ClsName, S);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator find(const ObjCInterfaceDecl* D, Selector S) {
|
RetainSummary* find(const 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
|
||||||
// the iterator.
|
// the iterator.
|
||||||
ObjCSummaryKey K(D, S);
|
ObjCSummaryKey K(D, S);
|
||||||
MapTy::iterator I = M.find(K);
|
MapTy::iterator I = M.find(K);
|
||||||
|
|
||||||
if (I != M.end() || !D)
|
if (I != M.end() || !D)
|
||||||
return I;
|
return I->second;
|
||||||
|
|
||||||
// Walk the super chain. If we find a hit with a parent, we'll end
|
// Walk the super chain. If we find a hit with a parent, we'll end
|
||||||
// up returning that summary. We actually allow that key (null,S), as
|
// up returning that summary. We actually allow that key (null,S), as
|
||||||
|
|
@ -526,25 +524,30 @@ public:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!C)
|
if (!C)
|
||||||
return I;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the summary with original key to make the next lookup faster
|
// Cache the summary with original key to make the next lookup faster
|
||||||
// and return the iterator.
|
// and return the iterator.
|
||||||
M[K] = I->second;
|
RetainSummary *Summ = I->second;
|
||||||
return I;
|
M[K] = Summ;
|
||||||
|
return Summ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
iterator find(Expr* Receiver, Selector S) {
|
RetainSummary* find(Expr* Receiver, Selector S) {
|
||||||
return find(getReceiverDecl(Receiver), S);
|
return find(getReceiverDecl(Receiver), S);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator find(IdentifierInfo* II, Selector S) {
|
RetainSummary* find(IdentifierInfo* II, Selector S) {
|
||||||
// FIXME: Class method lookup. Right now we dont' have a good way
|
// FIXME: Class method lookup. Right now we dont' have a good way
|
||||||
// of going between IdentifierInfo* and the class hierarchy.
|
// of going between IdentifierInfo* and the class hierarchy.
|
||||||
iterator I = M.find(ObjCSummaryKey(II, S));
|
MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
|
||||||
return I == M.end() ? M.find(ObjCSummaryKey(S)) : I;
|
|
||||||
|
if (I == M.end())
|
||||||
|
I = M.find(ObjCSummaryKey(S));
|
||||||
|
|
||||||
|
return I == M.end() ? NULL : I->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ObjCInterfaceDecl* getReceiverDecl(Expr* E) {
|
const ObjCInterfaceDecl* getReceiverDecl(Expr* E) {
|
||||||
|
|
@ -555,8 +558,6 @@ public:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator end() { return M.end(); }
|
|
||||||
|
|
||||||
RetainSummary*& operator[](ObjCMessageExpr* ME) {
|
RetainSummary*& operator[](ObjCMessageExpr* ME) {
|
||||||
|
|
||||||
Selector S = ME->getSelector();
|
Selector S = ME->getSelector();
|
||||||
|
|
@ -1347,25 +1348,24 @@ RetainSummaryManager::getInstanceMethodSummary(Selector S,
|
||||||
QualType RetTy) {
|
QualType RetTy) {
|
||||||
|
|
||||||
// Look up a summary in our summary cache.
|
// Look up a summary in our summary cache.
|
||||||
ObjCMethodSummariesTy::iterator I = ObjCMethodSummaries.find(ID, ClsName, S);
|
RetainSummary *Summ = ObjCMethodSummaries.find(ID, ClsName, S);
|
||||||
|
|
||||||
if (I != ObjCMethodSummaries.end())
|
if (!Summ) {
|
||||||
return I->second;
|
assert(ScratchArgs.isEmpty());
|
||||||
|
|
||||||
assert(ScratchArgs.isEmpty());
|
|
||||||
RetainSummary *Summ = 0;
|
|
||||||
|
|
||||||
// "initXXX": pass-through for receiver.
|
// "initXXX": pass-through for receiver.
|
||||||
if (deriveNamingConvention(S) == InitRule)
|
if (deriveNamingConvention(S) == InitRule)
|
||||||
Summ = getInitMethodSummary(RetTy);
|
Summ = getInitMethodSummary(RetTy);
|
||||||
else
|
else
|
||||||
Summ = getCommonMethodSummary(MD, S, RetTy);
|
Summ = getCommonMethodSummary(MD, S, RetTy);
|
||||||
|
|
||||||
// Annotations override defaults.
|
// Annotations override defaults.
|
||||||
updateSummaryFromAnnotations(*Summ, MD);
|
updateSummaryFromAnnotations(*Summ, MD);
|
||||||
|
|
||||||
|
// Memoize the summary.
|
||||||
|
ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
|
||||||
|
}
|
||||||
|
|
||||||
// Memoize the summary.
|
|
||||||
ObjCMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
|
|
||||||
return Summ;
|
return Summ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1376,19 +1376,16 @@ RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
|
||||||
QualType RetTy) {
|
QualType RetTy) {
|
||||||
|
|
||||||
assert(ClsName && "Class name must be specified.");
|
assert(ClsName && "Class name must be specified.");
|
||||||
ObjCMethodSummariesTy::iterator I =
|
RetainSummary *Summ = ObjCClassMethodSummaries.find(ID, ClsName, S);
|
||||||
ObjCClassMethodSummaries.find(ID, ClsName, S);
|
|
||||||
|
|
||||||
if (I != ObjCClassMethodSummaries.end())
|
if (!Summ) {
|
||||||
return I->second;
|
Summ = getCommonMethodSummary(MD, S, RetTy);
|
||||||
|
// Annotations override defaults.
|
||||||
RetainSummary *Summ = getCommonMethodSummary(MD, S, RetTy);
|
updateSummaryFromAnnotations(*Summ, MD);
|
||||||
|
// Memoize the summary.
|
||||||
|
ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
|
||||||
|
}
|
||||||
|
|
||||||
// Annotations override defaults.
|
|
||||||
updateSummaryFromAnnotations(*Summ, MD);
|
|
||||||
|
|
||||||
// Memoize the summary.
|
|
||||||
ObjCClassMethodSummaries[ObjCSummaryKey(ID, ClsName, S)] = Summ;
|
|
||||||
return Summ;
|
return Summ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue