diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2018-10-23 23:11:50 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2018-10-23 23:11:50 +0000 |
commit | a193197ff62995641b30b411deaa1208b72d29dd (patch) | |
tree | 4548309fde6eb1b603d83bb3bcac00c5ef909b22 /test | |
parent | fc259e8f5fba8243c5f66d0e603354a2cb88464e (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.cpp | 49 |
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(); |