diff options
| author | Artem Dergachev <artem.dergachev@gmail.com> | 2019-06-19 23:33:34 +0000 |
|---|---|---|
| committer | Artem Dergachev <artem.dergachev@gmail.com> | 2019-06-19 23:33:34 +0000 |
| commit | b03854f8e87e89051da5eae6c267020801fb39a0 (patch) | |
| tree | 35e2ebd990f6f549f4f84386d390e66226ec7e85 /clang/test/Analysis/osobject-retain-release.cpp | |
| parent | 24151619a00e7381dd3c3f96d623927c61f87e6c (diff) | |
| download | bcm5719-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.cpp | 21 |
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) { |

