зеркало из https://github.com/microsoft/clang-1.git
Remove experimental ownership attributes from Clang.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71216 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2572eda552
Коммит
008fc73ac9
|
@ -59,13 +59,6 @@ public:
|
|||
NonNull,
|
||||
ObjCException,
|
||||
ObjCNSObject,
|
||||
CFOwnershipRelease, // Clang/Checker-specific.
|
||||
CFOwnershipRetain, // Clang/Checker-specific.
|
||||
CFOwnershipReturns, // Clang/Checker-specific.
|
||||
NSOwnershipAutorelease, // Clang/Checker-specific.
|
||||
NSOwnershipRelease, // Clang/Checker-specific.
|
||||
NSOwnershipRetain, // Clang/Checker-specific.
|
||||
NSOwnershipReturns, // Clang/Checker-specific.
|
||||
Overloadable, // Clang-specific
|
||||
Packed,
|
||||
Pure,
|
||||
|
@ -466,15 +459,6 @@ public:
|
|||
static bool classof(const RegparmAttr *A) { return true; }
|
||||
};
|
||||
|
||||
// Checker-specific attributes.
|
||||
DEF_SIMPLE_ATTR(CFOwnershipRelease);
|
||||
DEF_SIMPLE_ATTR(CFOwnershipRetain);
|
||||
DEF_SIMPLE_ATTR(CFOwnershipReturns);
|
||||
DEF_SIMPLE_ATTR(NSOwnershipRelease);
|
||||
DEF_SIMPLE_ATTR(NSOwnershipRetain);
|
||||
DEF_SIMPLE_ATTR(NSOwnershipAutorelease);
|
||||
DEF_SIMPLE_ATTR(NSOwnershipReturns);
|
||||
|
||||
#undef DEF_SIMPLE_ATTR
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -76,13 +76,6 @@ public:
|
|||
AT_nothrow,
|
||||
AT_nsobject,
|
||||
AT_objc_exception,
|
||||
AT_cf_releases, // Clang-specific.
|
||||
AT_cf_retains, // Clang-specific.
|
||||
AT_cf_returns_retained, // Clang-specific.
|
||||
AT_ns_autoreleases, // Clang-specific.
|
||||
AT_ns_releases, // Clang-specific.
|
||||
AT_ns_retains, // Clang-specific.
|
||||
AT_ns_returns_retained, // Clang-specific.
|
||||
AT_objc_gc,
|
||||
AT_overloadable, // Clang-specific.
|
||||
AT_packed,
|
||||
|
|
|
@ -785,15 +785,6 @@ public:
|
|||
RetainSummary* getCommonMethodSummary(const ObjCMethodDecl* MD,
|
||||
Selector S, QualType RetTy);
|
||||
|
||||
void updateSummaryArgEffFromAnnotations(RetainSummary &Summ, const Decl *D,
|
||||
unsigned argIdx = 0);
|
||||
|
||||
void updateSummaryFromAnnotations(RetainSummary &Summ,
|
||||
const ObjCMethodDecl *MD);
|
||||
|
||||
void updateSummaryFromAnnotations(RetainSummary &Summ,
|
||||
const FunctionDecl *FD);
|
||||
|
||||
bool isGCEnabled() const { return GCEnabled; }
|
||||
|
||||
RetainSummary *copySummary(RetainSummary *OldSumm) {
|
||||
|
@ -1018,10 +1009,6 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
|
|||
if (!S)
|
||||
S = getDefaultSummary();
|
||||
|
||||
// Annotations override defaults.
|
||||
assert(S);
|
||||
updateSummaryFromAnnotations(*S, FD);
|
||||
|
||||
FuncSummaries[FD] = S;
|
||||
return S;
|
||||
}
|
||||
|
@ -1105,81 +1092,7 @@ RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
|
|||
? RetEffect::MakeReceiverAlias()
|
||||
: RetEffect::MakeNoRet());
|
||||
}
|
||||
|
||||
void
|
||||
RetainSummaryManager::updateSummaryArgEffFromAnnotations(RetainSummary &Summ,
|
||||
const Decl *D,
|
||||
unsigned i) {
|
||||
ArgEffect E = DoNothing;
|
||||
|
||||
if (D->getAttr<NSOwnershipRetainAttr>())
|
||||
E = IncRefMsg;
|
||||
else if (D->getAttr<CFOwnershipRetainAttr>())
|
||||
E = IncRef;
|
||||
else if (D->getAttr<NSOwnershipReleaseAttr>())
|
||||
E = DecRefMsg;
|
||||
else if (D->getAttr<CFOwnershipReleaseAttr>())
|
||||
E = DecRef;
|
||||
else if (D->getAttr<NSOwnershipAutoreleaseAttr>())
|
||||
E = Autorelease;
|
||||
else
|
||||
return;
|
||||
|
||||
if (isa<ParmVarDecl>(D))
|
||||
Summ.setArgEffect(AF, i, E);
|
||||
else
|
||||
Summ.setReceiverEffect(E);
|
||||
}
|
||||
|
||||
void
|
||||
RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
|
||||
const FunctionDecl *FD) {
|
||||
if (!FD)
|
||||
return;
|
||||
|
||||
// Determine if there is a special return effect for this method.
|
||||
if (isTrackedObjCObjectType(FD->getResultType())) {
|
||||
if (FD->getAttr<NSOwnershipReturnsAttr>()) {
|
||||
Summ.setRetEffect(ObjCAllocRetE);
|
||||
}
|
||||
else if (FD->getAttr<CFOwnershipReturnsAttr>()) {
|
||||
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if there are any arguments with a specific ArgEffect.
|
||||
unsigned i = 0;
|
||||
for (FunctionDecl::param_const_iterator I = FD->param_begin(),
|
||||
E = FD->param_end(); I != E; ++I, ++i)
|
||||
updateSummaryArgEffFromAnnotations(Summ, *I, i);
|
||||
}
|
||||
|
||||
void
|
||||
RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
|
||||
const ObjCMethodDecl *MD) {
|
||||
if (!MD)
|
||||
return;
|
||||
|
||||
// Determine if there is a special return effect for this method.
|
||||
if (isTrackedObjCObjectType(MD->getResultType())) {
|
||||
if (MD->getAttr<NSOwnershipReturnsAttr>()) {
|
||||
Summ.setRetEffect(ObjCAllocRetE);
|
||||
}
|
||||
else if (MD->getAttr<CFOwnershipReturnsAttr>()) {
|
||||
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if there are any arguments with a specific ArgEffect.
|
||||
unsigned i = 0;
|
||||
for (ObjCMethodDecl::param_iterator I = MD->param_begin(),
|
||||
E = MD->param_end(); I != E; ++I, ++i)
|
||||
updateSummaryArgEffFromAnnotations(Summ, *I, i);
|
||||
|
||||
// Determine any effects on the receiver.
|
||||
updateSummaryArgEffFromAnnotations(Summ, MD);
|
||||
}
|
||||
|
||||
RetainSummary*
|
||||
RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD,
|
||||
Selector S, QualType RetTy) {
|
||||
|
@ -1262,9 +1175,6 @@ RetainSummaryManager::getInstanceMethodSummary(Selector S,
|
|||
else
|
||||
Summ = getCommonMethodSummary(MD, S, RetTy);
|
||||
|
||||
// Annotations override defaults.
|
||||
updateSummaryFromAnnotations(*Summ, MD);
|
||||
|
||||
// Memoize the summary.
|
||||
ObjCMethodSummaries[ObjCSummaryKey(ClsName, S)] = Summ;
|
||||
return Summ;
|
||||
|
@ -1285,9 +1195,6 @@ RetainSummaryManager::getClassMethodSummary(Selector S, IdentifierInfo *ClsName,
|
|||
|
||||
RetainSummary *Summ = getCommonMethodSummary(MD, S, RetTy);
|
||||
|
||||
// Annotations override defaults.
|
||||
updateSummaryFromAnnotations(*Summ, MD);
|
||||
|
||||
// Memoize the summary.
|
||||
ObjCClassMethodSummaries[ObjCSummaryKey(ClsName, S)] = Summ;
|
||||
return Summ;
|
||||
|
|
|
@ -475,13 +475,6 @@ Attr *PCHReader::ReadAttributes() {
|
|||
|
||||
SIMPLE_ATTR(ObjCException);
|
||||
SIMPLE_ATTR(ObjCNSObject);
|
||||
SIMPLE_ATTR(CFOwnershipRelease);
|
||||
SIMPLE_ATTR(CFOwnershipRetain);
|
||||
SIMPLE_ATTR(CFOwnershipReturns);
|
||||
SIMPLE_ATTR(NSOwnershipAutorelease);
|
||||
SIMPLE_ATTR(NSOwnershipRelease);
|
||||
SIMPLE_ATTR(NSOwnershipRetain);
|
||||
SIMPLE_ATTR(NSOwnershipReturns);
|
||||
SIMPLE_ATTR(Overloadable);
|
||||
UNSIGNED_ATTR(Packed);
|
||||
SIMPLE_ATTR(Pure);
|
||||
|
|
|
@ -1544,13 +1544,6 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
|
|||
|
||||
case Attr::ObjCException:
|
||||
case Attr::ObjCNSObject:
|
||||
case Attr::CFOwnershipRelease:
|
||||
case Attr::CFOwnershipRetain:
|
||||
case Attr::CFOwnershipReturns:
|
||||
case Attr::NSOwnershipAutorelease:
|
||||
case Attr::NSOwnershipRelease:
|
||||
case Attr::NSOwnershipRetain:
|
||||
case Attr::NSOwnershipReturns:
|
||||
case Attr::Overloadable:
|
||||
break;
|
||||
|
||||
|
|
|
@ -106,16 +106,12 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
|||
if (!memcmp(Str, "format_arg", 10))
|
||||
return IgnoredAttribute; // FIXME: printf format string checking.
|
||||
if (!memcmp(Str, "gnu_inline", 10)) return AT_gnu_inline;
|
||||
if (!memcmp(Str, "cf_retains", 10)) return AT_cf_retains;
|
||||
if (!memcmp(Str, "ns_retains", 10)) return AT_ns_retains;
|
||||
break;
|
||||
case 11:
|
||||
if (!memcmp(Str, "weak_import", 11)) return AT_weak_import;
|
||||
if (!memcmp(Str, "vector_size", 11)) return AT_vector_size;
|
||||
if (!memcmp(Str, "constructor", 11)) return AT_constructor;
|
||||
if (!memcmp(Str, "unavailable", 11)) return AT_unavailable;
|
||||
if (!memcmp(Str, "cf_releases", 11)) return AT_cf_releases;
|
||||
if (!memcmp(Str, "ns_releases", 11)) return AT_ns_releases;
|
||||
break;
|
||||
case 12:
|
||||
if (!memcmp(Str, "overloadable", 12)) return AT_overloadable;
|
||||
|
@ -129,7 +125,6 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
|||
break;
|
||||
case 15:
|
||||
if (!memcmp(Str, "ext_vector_type", 15)) return AT_ext_vector_type;
|
||||
if (!memcmp(Str, "ns_autoreleases", 15)) return AT_ns_autoreleases;
|
||||
break;
|
||||
case 17:
|
||||
if (!memcmp(Str, "transparent_union", 17)) return AT_transparent_union;
|
||||
|
@ -138,10 +133,6 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
|||
case 18:
|
||||
if (!memcmp(Str, "warn_unused_result", 18)) return AT_warn_unused_result;
|
||||
break;
|
||||
case 19:
|
||||
if (!memcmp(Str, "ns_returns_retained", 19)) return AT_ns_returns_retained;
|
||||
if (!memcmp(Str, "cf_returns_retained", 19)) return AT_cf_returns_retained;
|
||||
break;
|
||||
case 22:
|
||||
if (!memcmp(Str, "no_instrument_function", 22))
|
||||
return AT_no_instrument_function;
|
||||
|
|
|
@ -1543,94 +1543,6 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
|||
d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Checker-specific attribute handlers.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void HandleNSOwnershipReturnsAttr(Decl *d, const AttributeList &Attr,
|
||||
Sema &S) {
|
||||
|
||||
if (!isa<ObjCMethodDecl>(d) && !isa<FunctionDecl>(d)) {
|
||||
const char *name;
|
||||
|
||||
switch (Attr.getKind()) {
|
||||
default:
|
||||
assert(0 && "invalid ownership attribute");
|
||||
return;
|
||||
case AttributeList::AT_cf_returns_retained:
|
||||
name = "cf_returns_retained"; break;
|
||||
case AttributeList::AT_ns_returns_retained:
|
||||
name = "ns_returns_retained"; break;
|
||||
};
|
||||
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
|
||||
name << 3 /* function or method */;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Attr.getKind()) {
|
||||
default:
|
||||
assert(0 && "invalid ownership attribute");
|
||||
return;
|
||||
case AttributeList::AT_cf_returns_retained:
|
||||
d->addAttr(::new (S.Context) CFOwnershipReturnsAttr());
|
||||
return;
|
||||
case AttributeList::AT_ns_returns_retained:
|
||||
d->addAttr(::new (S.Context) NSOwnershipReturnsAttr());
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
static void HandleNSOwnershipAttr(Decl *d, const AttributeList &Attr,
|
||||
Sema &S, bool attachToMethodDecl = false) {
|
||||
|
||||
if (!isa<ParmVarDecl>(d) && (!attachToMethodDecl || !isa<ObjCMethodDecl>(d))){
|
||||
const char *name;
|
||||
|
||||
switch (Attr.getKind()) {
|
||||
default:
|
||||
assert(0 && "invalid ownership attribute");
|
||||
return;
|
||||
case AttributeList::AT_cf_releases:
|
||||
name = "cf_releases"; break;
|
||||
case AttributeList::AT_cf_retains:
|
||||
name = "cf_retains"; break;
|
||||
case AttributeList::AT_ns_autoreleases:
|
||||
name = "ns_autoreleases"; break;
|
||||
case AttributeList::AT_ns_releases:
|
||||
name = "ns_releases"; break;
|
||||
case AttributeList::AT_ns_retains:
|
||||
name = "ns_retains"; break;
|
||||
};
|
||||
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
|
||||
name << (attachToMethodDecl ? 5 /* parameter or method decl */
|
||||
: 4 /* parameter */);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Attr.getKind()) {
|
||||
default:
|
||||
assert(0 && "invalid ownership attribute");
|
||||
return;
|
||||
case AttributeList::AT_cf_releases:
|
||||
d->addAttr(::new (S.Context) CFOwnershipReleaseAttr());
|
||||
return;
|
||||
case AttributeList::AT_cf_retains:
|
||||
d->addAttr(::new (S.Context) CFOwnershipRetainAttr());
|
||||
return;
|
||||
case AttributeList::AT_ns_autoreleases:
|
||||
d->addAttr(::new (S.Context) NSOwnershipAutoreleaseAttr());
|
||||
return;
|
||||
case AttributeList::AT_ns_releases:
|
||||
d->addAttr(::new (S.Context) NSOwnershipReleaseAttr());
|
||||
return;
|
||||
case AttributeList::AT_ns_retains:
|
||||
d->addAttr(::new (S.Context) NSOwnershipRetainAttr());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Top Level Sema Entry Points
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1667,19 +1579,6 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
|
|||
case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
|
||||
|
||||
// Checker-specific.
|
||||
case AttributeList::AT_cf_releases:
|
||||
case AttributeList::AT_cf_retains:
|
||||
HandleNSOwnershipAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_ns_autoreleases:
|
||||
case AttributeList::AT_ns_releases:
|
||||
case AttributeList::AT_ns_retains:
|
||||
HandleNSOwnershipAttr(D, Attr, S, true); break;
|
||||
case AttributeList::AT_ns_returns_retained:
|
||||
case AttributeList::AT_cf_returns_retained:
|
||||
HandleNSOwnershipReturnsAttr(D, Attr, S); break;
|
||||
|
||||
case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
|
||||
|
|
|
@ -124,82 +124,3 @@ void f3() {
|
|||
CFRetain(A);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Tests of ownership attributes.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@interface TestOwnershipAttr : NSObject
|
||||
- (NSString*) returnsAnOwnedString __attribute__((ns_returns_retained));
|
||||
- (NSString*) returnsAnOwnedCFString __attribute__((cf_returns_retained));
|
||||
- (void) myRetain:(id)__attribute__((ns_retains))obj;
|
||||
- (void) myCFRetain:(id)__attribute__((cf_retains))obj;
|
||||
- (void) myRelease:(id)__attribute__((ns_releases))obj;
|
||||
- (void) myCFRelease:(id)__attribute__((cf_releases))obj;
|
||||
@end
|
||||
|
||||
void test_attr_1(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
}
|
||||
|
||||
void test_attr_1b(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
|
||||
}
|
||||
|
||||
void test_attr_2(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
[X myRetain:str];
|
||||
[str release];
|
||||
}
|
||||
|
||||
void test_attr_2b(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
|
||||
[X myRetain:str];
|
||||
[str release];
|
||||
}
|
||||
|
||||
void test_attr_3(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
[X myCFRetain:str];
|
||||
[str release];
|
||||
}
|
||||
|
||||
void test_attr_4a(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
}
|
||||
|
||||
void test_attr_4b(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
[X myRelease:str];
|
||||
}
|
||||
|
||||
void test_attr_4c(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
[X myRetain:str];
|
||||
[X myRelease:str];
|
||||
}
|
||||
|
||||
void test_attr_5a(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-waring
|
||||
}
|
||||
|
||||
void test_attr_5b(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString];
|
||||
[X myCFRelease:str]; // expected-warning{{Incorrect decrement of the reference count of an object is not owned at this point by the caller}}
|
||||
}
|
||||
|
||||
void test_attr_5c(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
[X myCFRetain:str];
|
||||
[X myCFRelease:str];
|
||||
}
|
||||
|
||||
void test_attr_6a(TestOwnershipAttr *X) {
|
||||
CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // expected-warning{{leak}}
|
||||
}
|
||||
|
||||
void test_attr_6b(TestOwnershipAttr *X) {
|
||||
CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); // no-warning
|
||||
CFMakeCollectable(A);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -426,139 +426,6 @@ void rdar6704930(unsigned char *s, unsigned int length) {
|
|||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Tests of ownership attributes.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@interface TestOwnershipAttr : NSObject
|
||||
- (NSString*) returnsAnOwnedString __attribute__((ns_returns_retained));
|
||||
- (NSString*) returnsAnOwnedCFString __attribute__((cf_returns_retained));
|
||||
- (void) myRetain:(id)__attribute__((ns_retains))obj;
|
||||
- (void) myCFRetain:(id)__attribute__((cf_retains))obj;
|
||||
- (void) myRelease:(id)__attribute__((ns_releases))obj;
|
||||
- (void) myCFRelease:(id)__attribute__((cf_releases))obj;
|
||||
- (void) myRetain __attribute__((ns_retains));
|
||||
- (void) myRelease __attribute__((ns_releases));
|
||||
- (void) myAutorelease __attribute__((ns_autoreleases));
|
||||
- (void) myAutorelease:(id)__attribute__((ns_autoreleases))obj;
|
||||
@end
|
||||
|
||||
@interface TestAttrHelper : NSObject
|
||||
- (NSString*) createString:(TestOwnershipAttr*)X;
|
||||
- (NSString*) createStringAttr:(TestOwnershipAttr*)X __attribute__((ns_returns_retained));
|
||||
@end
|
||||
|
||||
@implementation TestAttrHelper
|
||||
- (NSString*) createString:(TestOwnershipAttr*)X {
|
||||
return [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
}
|
||||
- (NSString*) createStringAttr:(TestOwnershipAttr*)X {
|
||||
return [X returnsAnOwnedString]; // no-warning
|
||||
}
|
||||
@end
|
||||
|
||||
void test_attr_1(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
}
|
||||
|
||||
void test_attr_1b(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
|
||||
}
|
||||
|
||||
__attribute__((ns_returns_retained))
|
||||
NSString* test_attr_1c(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
return str;
|
||||
}
|
||||
|
||||
void test_attr_1d_helper(NSString* str __attribute__((ns_retains)));
|
||||
|
||||
__attribute__((ns_returns_retained))
|
||||
NSString* test_attr_1d(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
test_attr_1d_helper(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
void test_attr_1e(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
[X myAutorelease:str];
|
||||
}
|
||||
|
||||
void test_attr_2(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
[X myRetain:str];
|
||||
[str release];
|
||||
}
|
||||
|
||||
void test_attr_2b(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
|
||||
[X myRetain:str];
|
||||
[str release];
|
||||
}
|
||||
|
||||
void test_attr_3(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
[X myCFRetain:str];
|
||||
[str release];
|
||||
}
|
||||
|
||||
void test_attr_4a(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
}
|
||||
|
||||
void test_attr_4b(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
[X myRelease:str];
|
||||
}
|
||||
|
||||
void test_attr_4c(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
[X myRetain:str];
|
||||
[X myRelease:str];
|
||||
}
|
||||
|
||||
void test_attr_4d(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString];
|
||||
[X myRelease:str];
|
||||
[X myRelease:str]; // expected-warning{{Reference-counted object is used after it is released}}
|
||||
}
|
||||
|
||||
void test_attr_5a(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
}
|
||||
|
||||
void test_attr_5b(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // no-warning
|
||||
[X myCFRelease:str];
|
||||
}
|
||||
|
||||
void test_attr_5c(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
|
||||
[X myCFRetain:str];
|
||||
[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];
|
||||
}
|
||||
|
||||
void test_attr_6d() {
|
||||
TestOwnershipAttr *X = [TestOwnershipAttr alloc]; // no-warning
|
||||
[X myAutorelease];
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// <rdar://problem/6833332>
|
||||
// One build of the analyzer accidentally stopped tracking the allocated
|
||||
|
|
Загрузка…
Ссылка в новой задаче