aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2018-10-23 23:11:50 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2018-10-23 23:11:50 +0000
commita193197ff62995641b30b411deaa1208b72d29dd (patch)
tree4548309fde6eb1b603d83bb3bcac00c5ef909b22 /test
parentfc259e8f5fba8243c5f66d0e603354a2cb88464e (diff)
[analyzer] Do not stop tracking CXX methods touching OSObject.
Trust generalized annotations for OSObject. Differential Revision: https://reviews.llvm.org/D53550 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@345100 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/Analysis/osobject-retain-release.cpp49
1 files changed, 44 insertions, 5 deletions
diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp
index e9c9f698da..23e92ecaf6 100644
--- a/test/Analysis/osobject-retain-release.cpp
+++ b/test/Analysis/osobject-retain-release.cpp
@@ -2,6 +2,11 @@
struct OSMetaClass;
+#define TRUSTED __attribute__((annotate("rc_ownership_trusted_implementation")))
+#define OS_CONSUME TRUSTED __attribute__((annotate("rc_ownership_consumed")))
+#define OS_RETURNS_RETAINED TRUSTED __attribute__((annotate("rc_ownership_returns_retained")))
+#define OS_RETURNS_NOT_RETAINED TRUSTED __attribute__((annotate("rc_ownership_returns_not_retained")))
+
#define OSTypeID(type) (type::metaClass)
#define OSDynamicCast(type, inst) \
@@ -21,14 +26,53 @@ struct OSArray : public OSObject {
unsigned int getCount();
static OSArray *withCapacity(unsigned int capacity);
+ static void consumeArray(OS_CONSUME OSArray * array);
+
+ static OSArray* consumeArrayHasCode(OS_CONSUME OSArray * array) {
+ return nullptr;
+ }
+
+ static OS_RETURNS_NOT_RETAINED OSArray *MaskedGetter();
+ static OS_RETURNS_RETAINED OSArray *getOoopsActuallyCreate();
+
static const OSMetaClass * const metaClass;
};
+struct OtherStruct {
+ static void doNothingToArray(OSArray *array);
+};
+
struct OSMetaClassBase {
static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
};
+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);
+} // expected-warning{{Potential leak of an object stored into 'arr'}}
+ // expected-note@-1{{Object leaked}}
+
+void check_rc_consumed() {
+ OSArray *arr = OSArray::withCapacity(10);
+ OSArray::consumeArray(arr);
+}
+
+void check_rc_consume_temporary() {
+ OSArray::consumeArray(OSArray::withCapacity(10));
+}
+
+void check_rc_getter() {
+ OSArray *arr = OSArray::MaskedGetter();
+ (void)arr;
+}
+
+void check_rc_create() {
+ OSArray *arr = OSArray::getOoopsActuallyCreate();
+ arr->release();
+}
+
+
void check_dynamic_cast() {
OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1));
arr->release();
@@ -80,11 +124,6 @@ struct ArrayOwner {
OSArray *getArraySourceUnknown();
};
-//unsigned int leak_on_create_no_release(ArrayOwner *owner) {
- //OSArray *myArray =
-
-//}
-
unsigned int no_warning_on_getter(ArrayOwner *owner) {
OSArray *arr = owner->getArray();
return arr->getCount();