aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp10
-rw-r--r--test/Analysis/retain-release.m6
2 files changed, 12 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index b38894ccfa..b57c6e2b4f 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1306,13 +1306,14 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
else if (FD->getAttr<CFReturnsRetainedAttr>()) {
Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
- else if (FD->getAttr<NSReturnsNotRetainedAttr>()) {
+ else if (FD->getAttr<NSReturnsNotRetainedAttr>() ||
+ FD->getAttr<NSReturnsAutoreleasedAttr>()) {
Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
}
- else if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
+ else if (FD->getAttr<CFReturnsNotRetainedAttr>())
Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::CF));
}
- } else if (RetTy->getAs<PointerType>()) {
+ else if (RetTy->getAs<PointerType>()) {
if (FD->getAttr<CFReturnsRetainedAttr>()) {
Template->setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
@@ -1359,7 +1360,8 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,
Template->setRetEffect(ObjCAllocRetE);
return;
}
- if (MD->getAttr<NSReturnsNotRetainedAttr>()) {
+ if (MD->getAttr<NSReturnsNotRetainedAttr>() ||
+ MD->getAttr<NSReturnsAutoreleasedAttr>()) {
Template->setRetEffect(RetEffect::MakeNotOwned(RetEffect::ObjC));
return;
}
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index ef2566b961..2b5a4adced 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -25,6 +25,9 @@
#if __has_feature(attribute_cf_consumed)
#define CF_CONSUMED __attribute__((cf_consumed))
#endif
+#if __has_attribute(ns_returns_autoreleased)
+#define NS_RETURNS_AUTORELEASED __attribute__((ns_returns_autoreleased))
+#endif
//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from Mac OS X headers:
@@ -1300,6 +1303,7 @@ typedef NSString* MyStringTy;
- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning
- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning
- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning
+- (NSString*) newString_auto NS_RETURNS_AUTORELEASED; // no-warning
- (NSString*) newStringNoAttr;
- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to methods that return an Objective-C object}}
- (id) pseudoInit NS_CONSUMES_SELF NS_RETURNS_RETAINED;
@@ -1320,6 +1324,8 @@ void test_attr_1b(TestOwnershipAttr *X) {
void test_attr1c(TestOwnershipAttr *X) {
NSString *str = [X newString]; // no-warning
NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}}
+ NSString *str3 = [X newString_auto]; // no-warning
+ NSString *str4 = [[X newString_auto] retain]; // expected-warning {{leak}}
}
void testattr2_a() {