]> granicus.if.org Git - clang/commitdiff
[analyzer] Re-add custom OSIterator rule for RetainCountChecker
authorGeorge Karpenkov <ekarpenkov@apple.com>
Wed, 31 Oct 2018 17:38:46 +0000 (17:38 +0000)
committerGeorge Karpenkov <ekarpenkov@apple.com>
Wed, 31 Oct 2018 17:38:46 +0000 (17:38 +0000)
Turns out the rule is quite ubiquitous.

Revert of https://reviews.llvm.org/D53628

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@345747 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
test/Analysis/osobject-retain-release.cpp

index b0e26bae961e1c93a774a143ceac1688c38075f8..2fb0d754d970e904eeb1b52a47ad67abdddce5ac 100644 (file)
@@ -69,6 +69,10 @@ static bool isOSObjectDynamicCast(StringRef S) {
   return S == "safeMetaCast";
 }
 
+static bool isOSIteratorSubclass(const Decl *D) {
+  return isSubclass(D, "OSIterator");
+}
+
 static bool hasRCAnnotation(const Decl *D, StringRef rcAnnotation) {
   for (const auto *Ann : D->specific_attrs<AnnotateAttr>()) {
     if (Ann->getAnnotation() == rcAnnotation)
@@ -235,11 +239,12 @@ RetainSummaryManager::generateSummary(const FunctionDecl *FD,
         if (isOSObjectDynamicCast(II->getName()))
           return getDefaultSummary();
 
-        // All objects returned with functions starting with "get" are getters.
-        if (II->getName().startswith("get")) {
-          return getOSSummaryGetRule(FD);
-        } else {
+        // All objects returned with functions *not* starting with
+        // get, or iterators, are returned at +1.
+        if (!II->getName().startswith("get") || isOSIteratorSubclass(PD)) {
           return getOSSummaryCreateRule(FD);
+        } else {
+          return getOSSummaryGetRule(FD);
         }
       }
     }
index 47601b0bada3e162176f6148d7ddd7a2240004be..71f912961d3b5a61a00fae61cb11d0b26389c3bd 100644 (file)
@@ -23,6 +23,9 @@ struct OSObject {
   static const OSMetaClass * const metaClass;
 };
 
+struct OSIterator : public OSObject {
+};
+
 struct OSArray : public OSObject {
   unsigned int getCount();
 
@@ -33,6 +36,8 @@ struct OSArray : public OSObject {
     return nullptr;
   }
 
+  OSIterator * getIterator();
+
   static OS_RETURNS_NOT_RETAINED OSArray *MaskedGetter();
   static OS_RETURNS_RETAINED OSArray *getOoopsActuallyCreate();
 
@@ -49,6 +54,11 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+void check_custom_iterator_rule(OSArray *arr) {
+  OSIterator *it = arr->getIterator();
+  it->release();
+}
+
 void check_no_invalidation() {
   OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}}
   OtherStruct::doNothingToArray(arr);