summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2018-10-25 23:38:07 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2018-10-25 23:38:07 +0000
commit3c2ed8f3386eebae956267998c2d9aaec9105181 (patch)
tree267893d5d34bec7e9ddb5247e277c6988ccb64a2 /clang/test
parentf0923f16f88519a8eed863c93bbf5086e4420a3a (diff)
downloadbcm5719-llvm-3c2ed8f3386eebae956267998c2d9aaec9105181.tar.gz
bcm5719-llvm-3c2ed8f3386eebae956267998c2d9aaec9105181.zip
[analyzer] Correct modelling of OSDynamicCast: eagerly state split
Previously, OSDynamicCast was modeled as an identity. This is not correct: the output of OSDynamicCast may be zero even if the input was not zero (if the class is not of desired type), and thus the modeling led to false positives. Instead, we are doing eager state split: in one branch, the returned value is identical to the input parameter, and in the other branch, the returned value is zero. This patch required a substantial refactoring of canEval infrastructure, as now it can return different function summaries, and not just true/false. rdar://45497400 Differential Revision: https://reviews.llvm.org/D53624 llvm-svn: 345338
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Analysis/osobject-retain-release.cpp27
1 files changed, 26 insertions, 1 deletions
diff --git a/clang/test/Analysis/osobject-retain-release.cpp b/clang/test/Analysis/osobject-retain-release.cpp
index 23e92ecaf6b..4e26c03bc26 100644
--- a/clang/test/Analysis/osobject-retain-release.cpp
+++ b/clang/test/Analysis/osobject-retain-release.cpp
@@ -17,6 +17,8 @@ struct OSObject {
virtual void release() {};
virtual ~OSObject(){}
+ unsigned int foo() { return 42; }
+
static OSObject *generateObject(int);
static const OSMetaClass * const metaClass;
@@ -78,8 +80,31 @@ void check_dynamic_cast() {
arr->release();
}
+unsigned int check_dynamic_cast_no_null_on_orig(OSObject *obj) {
+ OSArray *arr = OSDynamicCast(OSArray, obj);
+ if (arr) {
+ return arr->getCount();
+ } else {
+
+ // The fact that dynamic cast has failed should not imply that
+ // the input object was null.
+ return obj->foo(); // no-warning
+ }
+}
+
+void check_dynamic_cast_null_branch(OSObject *obj) {
+ OSArray *arr1 = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject}}
+ OSArray *arr = OSDynamicCast(OSArray, obj);
+ if (!arr) // expected-note{{Taking true branch}}
+ return; // expected-warning{{Potential leak}}
+ // expected-note@-1{{Object leaked}}
+ arr1->release();
+}
+
void check_dynamic_cast_null_check() {
- OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1));
+ OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1)); // expected-note{{Call to function 'generateObject' returns an OSObject}}
+ // expected-warning@-1{{Potential leak of an object}}
+ // expected-note@-2{{Object leaked}}
if (!arr)
return;
arr->release();
OpenPOWER on IntegriCloud