зеркало из https://github.com/microsoft/clang-1.git
retain/release checker: Hook up attributes 'objc_ownership_retain' and
'objc_ownership_release' to the effects on receivers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70507 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
7b9a2ee5a4
Коммит
2cd1293ad3
|
@ -1139,14 +1139,14 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(const ObjCMethodDecl *MD){
|
|||
assert(ScratchArgs.empty());
|
||||
|
||||
// Determine if there is a special return effect for this method.
|
||||
bool hasRetEffect = false;
|
||||
bool hasEffect = false;
|
||||
RetEffect RE = RetEffect::MakeNoRet();
|
||||
|
||||
if (isTrackedObjectType(MD->getResultType())) {
|
||||
if (MD->getAttr<ObjCOwnershipReturnsAttr>()) {
|
||||
RE = isGCEnabled() ? RetEffect::MakeGCNotOwned()
|
||||
: RetEffect::MakeOwned(RetEffect::ObjC, true);
|
||||
hasRetEffect = true;
|
||||
hasEffect = true;
|
||||
}
|
||||
else {
|
||||
// Default to 'not owned'.
|
||||
|
@ -1155,36 +1155,46 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(const ObjCMethodDecl *MD){
|
|||
}
|
||||
|
||||
// Determine if there are any arguments with a specific ArgEffect.
|
||||
bool hasArgEffect = false;
|
||||
unsigned i = 0;
|
||||
for (ObjCMethodDecl::param_iterator I = MD->param_begin(),
|
||||
E = MD->param_end(); I != E; ++I, ++i) {
|
||||
if ((*I)->getAttr<ObjCOwnershipRetainAttr>()) {
|
||||
ScratchArgs.push_back(std::make_pair(i, IncRefMsg));
|
||||
hasArgEffect = true;
|
||||
hasEffect = true;
|
||||
}
|
||||
else if ((*I)->getAttr<ObjCOwnershipCFRetainAttr>()) {
|
||||
ScratchArgs.push_back(std::make_pair(i, IncRef));
|
||||
hasArgEffect = true;
|
||||
hasEffect = true;
|
||||
}
|
||||
else if ((*I)->getAttr<ObjCOwnershipReleaseAttr>()) {
|
||||
ScratchArgs.push_back(std::make_pair(i, DecRefMsg));
|
||||
hasArgEffect = true;
|
||||
hasEffect = true;
|
||||
}
|
||||
else if ((*I)->getAttr<ObjCOwnershipCFReleaseAttr>()) {
|
||||
ScratchArgs.push_back(std::make_pair(i, DecRef));
|
||||
hasArgEffect = true;
|
||||
hasEffect = true;
|
||||
}
|
||||
else if ((*I)->getAttr<ObjCOwnershipMakeCollectableAttr>()) {
|
||||
ScratchArgs.push_back(std::make_pair(i, MakeCollectable));
|
||||
hasArgEffect = true;
|
||||
hasEffect = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasRetEffect && !hasArgEffect)
|
||||
// Determine any effects on the receiver.
|
||||
ArgEffect ReceiverEff = DoNothing;
|
||||
if (MD->getAttr<ObjCOwnershipRetainAttr>()) {
|
||||
ReceiverEff = IncRefMsg;
|
||||
hasEffect = true;
|
||||
}
|
||||
else if (MD->getAttr<ObjCOwnershipReleaseAttr>()) {
|
||||
ReceiverEff = DecRefMsg;
|
||||
hasEffect = true;
|
||||
}
|
||||
|
||||
if (!hasEffect)
|
||||
return 0;
|
||||
|
||||
return getPersistentSummary(RE);
|
||||
return getPersistentSummary(RE, ReceiverEff);
|
||||
}
|
||||
|
||||
RetainSummary*
|
||||
|
|
|
@ -511,6 +511,21 @@ void test_attr_5c(TestOwnershipAttr *X) {
|
|||
[X myCFRelease:str];
|
||||
}
|
||||
|
||||
void test_attr_6a() {
|
||||
TestOwnershipAttr *X = [TestOwnershipAttr alloc]; // expected-warning{{leak}}
|
||||
}
|
||||
|
||||
void test_attr_6b() {
|
||||
TestOwnershipAttr *X = [TestOwnershipAttr alloc]; // no-warning
|
||||
[X myRelease];
|
||||
}
|
||||
|
||||
void test_attr_6c() {
|
||||
TestOwnershipAttr *X = [TestOwnershipAttr alloc]; // expected-warning{{leak}}
|
||||
[X myRetain];
|
||||
[X myRelease];
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// <rdar://problem/6833332>
|
||||
// One build of the analyzer accidentally stopped tracking the allocated
|
||||
|
|
Загрузка…
Ссылка в новой задаче