[PATCH] D53156: [analyzer] Retain count checker for OSObject: recognize OSDynamicCast
George Karpenkov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 11 16:01:10 PDT 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rL344311: [analyzer] Retain count checker for OSObject: recognize OSDynamicCast (authored by george.karpenkov, committed by ).
Herald added a subscriber: llvm-commits.
Changed prior to commit:
https://reviews.llvm.org/D53156?vs=169263&id=169333#toc
Repository:
rL LLVM
https://reviews.llvm.org/D53156
Files:
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp
Index: cfe/trunk/test/Analysis/osobject-retain-release.cpp
===================================================================
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp
@@ -1,18 +1,46 @@
// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config osx.cocoa.RetainCount:CheckOSObject=true -analyzer-output=text -verify %s
+struct OSMetaClass;
+
+#define OSTypeID(type) (type::metaClass)
+
+#define OSDynamicCast(type, inst) \
+ ((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type)))
+
struct OSObject {
virtual void retain();
virtual void release();
-
virtual ~OSObject(){}
+
+ static OSObject *generateObject(int);
+
+ static const OSMetaClass * const metaClass;
};
struct OSArray : public OSObject {
unsigned int getCount();
static OSArray *withCapacity(unsigned int capacity);
+
+ static const OSMetaClass * const metaClass;
};
+struct OSMetaClassBase {
+ static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
+};
+
+void check_dynamic_cast() {
+ OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1));
+ arr->release();
+}
+
+void check_dynamic_cast_null_check() {
+ OSArray *arr = OSDynamicCast(OSArray, OSObject::generateObject(1));
+ if (!arr)
+ return;
+ arr->release();
+}
+
void use_after_release() {
OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain count}}
arr->release(); // expected-note{{Object released}}
Index: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
===================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -774,12 +774,23 @@
// annotate attribute. If it does, we will not inline it.
bool hasTrustedImplementationAnnotation = false;
+ const LocationContext *LCtx = C.getLocationContext();
+
+ // Process OSDynamicCast: should just return the first argument.
+ // For now, tresting the cast as a no-op, and disregarding the case where
+ // the output becomes null due to the type mismatch.
+ if (FD->getNameAsString() == "safeMetaCast") {
+ state = state->BindExpr(CE, LCtx,
+ state->getSVal(CE->getArg(0), LCtx));
+ C.addTransition(state);
+ return true;
+ }
+
// See if it's one of the specific functions we know how to eval.
if (!SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation))
return false;
// Bind the return value.
- const LocationContext *LCtx = C.getLocationContext();
SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
if (RetVal.isUnknown() ||
(hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D53156.169333.patch
Type: text/x-patch
Size: 2959 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181011/74b0e4d1/attachment.bin>
More information about the llvm-commits
mailing list