diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2019-01-29 19:29:07 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2019-01-29 19:29:07 +0000 |
commit | 0f3bbbaec98c891b33409ce27e8bf550b0d60d85 (patch) | |
tree | 6867e66663043bd8a1a1579575023f8ebd98dff7 | |
parent | d79a4b7ad719ce57ccf5b691060a0a07cd082567 (diff) | |
download | bcm5719-llvm-0f3bbbaec98c891b33409ce27e8bf550b0d60d85.tar.gz bcm5719-llvm-0f3bbbaec98c891b33409ce27e8bf550b0d60d85.zip |
[analyzer] [RetainCountChecker] Support 'taggedRetain' and 'taggedRelease'
Differential Revision: https://reviews.llvm.org/D57211
llvm-svn: 352530
-rw-r--r-- | clang/lib/Analysis/RetainSummaryManager.cpp | 4 | ||||
-rw-r--r-- | clang/test/Analysis/os_object_base.h | 4 | ||||
-rw-r--r-- | clang/test/Analysis/os_smart_ptr.h | 3 | ||||
-rw-r--r-- | clang/test/Analysis/osobject-retain-release.cpp | 20 |
4 files changed, 23 insertions, 8 deletions
diff --git a/clang/lib/Analysis/RetainSummaryManager.cpp b/clang/lib/Analysis/RetainSummaryManager.cpp index e43faf0f330..d8b3f818c24 100644 --- a/clang/lib/Analysis/RetainSummaryManager.cpp +++ b/clang/lib/Analysis/RetainSummaryManager.cpp @@ -242,10 +242,10 @@ RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD, if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) { const CXXRecordDecl *Parent = MD->getParent(); if (TrackOSObjects && Parent && isOSObjectSubclass(Parent)) { - if (FName == "release") + if (FName == "release" || FName == "taggedRelease") return getOSSummaryReleaseRule(FD); - if (FName == "retain") + if (FName == "retain" || FName == "taggedRetain") return getOSSummaryRetainRule(FD); if (FName == "free") diff --git a/clang/test/Analysis/os_object_base.h b/clang/test/Analysis/os_object_base.h index 2c69c9acdcf..cd59e4f0bca 100644 --- a/clang/test/Analysis/os_object_base.h +++ b/clang/test/Analysis/os_object_base.h @@ -27,6 +27,10 @@ struct OSMetaClassBase { virtual void retain() const; virtual void release() const; + + virtual void taggedRetain(const void * tag = nullptr) const; + virtual void taggedRelease(const void * tag = nullptr) const; + virtual void free(); virtual ~OSMetaClassBase(){}; }; diff --git a/clang/test/Analysis/os_smart_ptr.h b/clang/test/Analysis/os_smart_ptr.h index 8faf294f751..48a5ef3df04 100644 --- a/clang/test/Analysis/os_smart_ptr.h +++ b/clang/test/Analysis/os_smart_ptr.h @@ -51,7 +51,6 @@ struct smart_ptr { } T * operator->() const { - OSPTR_LOG("Dereference smart_ptr with %p\n", pointer); return pointer; } @@ -84,6 +83,6 @@ struct smart_ptr { T *pointer; }; -} +} // namespace os #endif /* _OS_SMART_POINTER_H */ diff --git a/clang/test/Analysis/osobject-retain-release.cpp b/clang/test/Analysis/osobject-retain-release.cpp index 467b6434100..6cd7eb6d9af 100644 --- a/clang/test/Analysis/osobject-retain-release.cpp +++ b/clang/test/Analysis/osobject-retain-release.cpp @@ -593,12 +593,12 @@ void test_smart_ptr_uaf() { // expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}} // expected-note@os_smart_ptr.h:13{{Taking true branch}} // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}} - // expected-note@os_smart_ptr.h:72{{Reference count incremented. The object now has a +2 retain count}} + // expected-note@os_smart_ptr.h:71{{Reference count incremented. The object now has a +2 retain count}} // expected-note@os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}} } // expected-note{{Calling '~smart_ptr'}} // expected-note@os_smart_ptr.h:35{{Taking true branch}} // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}} - // expected-note@os_smart_ptr.h:77{{Reference count decremented. The object now has a +1 retain count}} + // expected-note@os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}} // expected-note@os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}} // expected-note@-5{{Returning from '~smart_ptr'}} obj->release(); // expected-note{{Object released}} @@ -613,12 +613,12 @@ void test_smart_ptr_leak() { // expected-note@-1{{Returning from constructor for 'smart_ptr<OSObject>'}} // expected-note@os_smart_ptr.h:13{{Taking true branch}} // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}} - // expected-note@os_smart_ptr.h:72{{Reference count incremented. The object now has a +2 retain count}} + // expected-note@os_smart_ptr.h:71{{Reference count incremented. The object now has a +2 retain count}} // expected-note@os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}} } // expected-note{{Calling '~smart_ptr'}} // expected-note@os_smart_ptr.h:35{{Taking true branch}} // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}} - // expected-note@os_smart_ptr.h:77{{Reference count decremented. The object now has a +1 retain count}} + // expected-note@os_smart_ptr.h:76{{Reference count decremented. The object now has a +1 retain count}} // expected-note@os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}} // expected-note@-5{{Returning from '~smart_ptr'}} } // expected-warning{{Potential leak of an object stored into 'obj'}} @@ -648,3 +648,15 @@ void test_free_on_escaped_object_diagnostics() { // expected-warning@-1{{'free' called on an object that may be referenced elsewhere}} } +void test_tagged_retain_no_leak() { + OSObject *obj = new OSObject; + obj->taggedRelease(); +} + +void test_tagged_retain_no_uaf() { + OSObject *obj = new OSObject; + obj->taggedRetain(); + obj->release(); + obj->release(); +} + |