summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2019-01-29 19:29:07 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2019-01-29 19:29:07 +0000
commit0f3bbbaec98c891b33409ce27e8bf550b0d60d85 (patch)
tree6867e66663043bd8a1a1579575023f8ebd98dff7
parentd79a4b7ad719ce57ccf5b691060a0a07cd082567 (diff)
downloadbcm5719-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.cpp4
-rw-r--r--clang/test/Analysis/os_object_base.h4
-rw-r--r--clang/test/Analysis/os_smart_ptr.h3
-rw-r--r--clang/test/Analysis/osobject-retain-release.cpp20
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();
+}
+
OpenPOWER on IntegriCloud