[analyzer] Retain count checker for OSObject: recognize OSDynamicCast

For now, tresting the cast as a no-op, and disregarding the case where
the output becomes null due to the type mismatch.

rdar://45174557

Differential Revision: https://reviews.llvm.org/D53156

llvm-svn: 344311
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index e5d27f5..ca58f14 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/clang/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())) {