[analyzer] Preliminary version of retain count checking for OSObjects

Has quite a lot of false positives, disabled behind the flag.

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

llvm-svn: 340502
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index 30d4dd1..2b39ad6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -418,13 +418,18 @@
   }
 
   // Consult the summary for the return value.
+  SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
   RetEffect RE = Summ.getRetEffect();
-  if (RE.getKind() == RetEffect::NoRetHard) {
-    SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
-    if (Sym)
-      state = removeRefBinding(state, Sym);
+  if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
+    if (Optional<RefVal> updatedRefVal =
+            refValFromRetEffect(RE, MCall->getResultType())) {
+      state = setRefBinding(state, Sym, *updatedRefVal);
+    }
   }
 
+  if (RE.getKind() == RetEffect::NoRetHard && Sym)
+    state = removeRefBinding(state, Sym);
+
   C.addTransition(state);
 }
 
@@ -490,11 +495,10 @@
     }
   }
 
-  // Evaluate the effect on the message receiver.
+  // Evaluate the effect on the message receiver / `this` argument.
   bool ReceiverIsTracked = false;
   if (!hasErr) {
-    const ObjCMethodCall *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg);
-    if (MsgInvocation) {
+    if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
       if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
         if (const RefVal *T = getRefBinding(state, Sym)) {
           ReceiverIsTracked = true;
@@ -506,6 +510,17 @@
           }
         }
       }
+    } else if (const auto *MCall = dyn_cast<CXXMemberCall>(&CallOrMsg)) {
+      if (SymbolRef Sym = MCall->getCXXThisVal().getAsLocSymbol()) {
+        if (const RefVal *T = getRefBinding(state, Sym)) {
+          state = updateSymbol(state, Sym, *T, Summ.getThisEffect(),
+                               hasErr, C);
+          if (hasErr) {
+            ErrorRange = MCall->getOriginExpr()->getSourceRange();
+            ErrorSym = Sym;
+          }
+        }
+      }
     }
   }