[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