summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/osobject-retain-release.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2019-06-19 23:33:34 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2019-06-19 23:33:34 +0000
commitb03854f8e87e89051da5eae6c267020801fb39a0 (patch)
tree35e2ebd990f6f549f4f84386d390e66226ec7e85 /clang/test/Analysis/osobject-retain-release.cpp
parent24151619a00e7381dd3c3f96d623927c61f87e6c (diff)
downloadbcm5719-llvm-b03854f8e87e89051da5eae6c267020801fb39a0.tar.gz
bcm5719-llvm-b03854f8e87e89051da5eae6c267020801fb39a0.zip
[analyzer] RetainCount: Add support for OSRequiredCast().
It's a new API for custom RTTI in Apple IOKit/DriverKit framework that is similar to OSDynamicCast() that's already supported, but crashes instead of returning null (and therefore causing UB when the cast fails unexpectedly). Kind of like cast_or_null<> as opposed to dyn_cast_or_null<> in LLVM's RTTI. Historically, RetainCountChecker was responsible for modeling OSDynamicCast. This is simply an extension of the same functionality. Differential Revision: https://reviews.llvm.org/D63117 llvm-svn: 363891
Diffstat (limited to 'clang/test/Analysis/osobject-retain-release.cpp')
-rw-r--r--clang/test/Analysis/osobject-retain-release.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/clang/test/Analysis/osobject-retain-release.cpp b/clang/test/Analysis/osobject-retain-release.cpp
index 10ef144bf36..afcc2425835 100644
--- a/clang/test/Analysis/osobject-retain-release.cpp
+++ b/clang/test/Analysis/osobject-retain-release.cpp
@@ -1,9 +1,11 @@
// RUN: %clang_analyze_cc1 -fblocks -analyze -analyzer-output=text\
-// RUN: -analyzer-checker=core,osx -verify %s
+// RUN: -analyzer-checker=core,osx,debug.ExprInspection -verify %s
#include "os_object_base.h"
#include "os_smart_ptr.h"
+void clang_analyzer_eval(bool);
+
struct OSIterator : public OSObject {
static const OSMetaClass * const metaClass;
};
@@ -483,6 +485,23 @@ void check_dynamic_cast() {
arr->release();
}
+void check_required_cast() {
+ OSArray *arr = OSRequiredCast(OSArray, OSObject::generateObject(1));
+ arr->release(); // no-warning
+}
+
+void check_cast_behavior(OSObject *obj) {
+ OSArray *arr1 = OSDynamicCast(OSArray, obj);
+ clang_analyzer_eval(arr1 == obj); // expected-warning{{TRUE}}
+ // expected-note@-1{{TRUE}}
+ // expected-note@-2{{Assuming 'arr1' is not equal to 'obj'}}
+ // expected-warning@-3{{FALSE}}
+ // expected-note@-4 {{FALSE}}
+ OSArray *arr2 = OSRequiredCast(OSArray, obj);
+ clang_analyzer_eval(arr2 == obj); // expected-warning{{TRUE}}
+ // expected-note@-1{{TRUE}}
+}
+
unsigned int check_dynamic_cast_no_null_on_orig(OSObject *obj) {
OSArray *arr = OSDynamicCast(OSArray, obj);
if (arr) {
OpenPOWER on IntegriCloud