r350858 - [analyzer] [NFC] Track object type with ArgEffect in RetainCountChecker.

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 10 10:14:00 PST 2019


Author: george.karpenkov
Date: Thu Jan 10 10:13:59 2019
New Revision: 350858

URL: http://llvm.org/viewvc/llvm-project?rev=350858&view=rev
Log:
[analyzer] [NFC] Track object type with ArgEffect in RetainCountChecker.

This would be needed in the future.

https://reviews.llvm.org/D56040

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
    cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350858&r1=350857&r2=350858&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 10 10:13:59 2019
@@ -52,9 +52,7 @@ enum class ObjKind {
   OS
 };
 
-/// An ArgEffect summarizes the retain count behavior on an argument or receiver
-/// to a function or method.
-enum ArgEffect {
+enum ArgEffectKind {
   /// There is no effect.
   DoNothing,
 
@@ -133,6 +131,27 @@ enum ArgEffect {
   DecRefMsgAndStopTrackingHard
 };
 
+/// An ArgEffect summarizes the retain count behavior on an argument or receiver
+/// to a function or method.
+class ArgEffect {
+  ArgEffectKind K;
+  ObjKind O;
+public:
+  explicit ArgEffect(ArgEffectKind K = DoNothing, ObjKind O = ObjKind::AnyObj)
+      : K(K), O(O) {}
+
+  ArgEffectKind getKind() const { return K; }
+  ObjKind getObjKind() const { return O; }
+
+  ArgEffect withKind(ArgEffectKind NewK) {
+    return ArgEffect(NewK, O);
+  }
+
+  bool operator==(const ArgEffect &Other) const {
+    return K == Other.K && O == Other.O;
+  }
+};
+
 /// RetEffect summarizes a call's retain/release behavior with respect
 /// to its return value.
 class RetEffect {
@@ -218,7 +237,9 @@ class CallEffects {
   RetEffect Ret;
   ArgEffect Receiver;
 
-  CallEffects(const RetEffect &R) : Ret(R) {}
+  CallEffects(const RetEffect &R,
+              ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj))
+      : Ret(R), Receiver(Receiver) {}
 
 public:
   /// Returns the argument effects for a call.
@@ -263,7 +284,8 @@ namespace llvm {
 
 template <> struct FoldingSetTrait<ArgEffect> {
 static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
-  ID.AddInteger((unsigned) X);
+  ID.AddInteger((unsigned) X.getKind());
+  ID.AddInteger((unsigned) X.getObjKind());
 }
 };
 template <> struct FoldingSetTrait<RetEffect> {
@@ -377,8 +399,8 @@ public:
   void setThisEffect(ArgEffect e) { This = e; }
 
   bool isNoop() const {
-    return Ret == RetEffect::MakeNoRet() && Receiver == DoNothing
-      && DefaultArgEffect == MayEscape && This == DoNothing
+    return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing
+      && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing
       && Args.isEmpty();
   }
 
@@ -547,32 +569,31 @@ class RetainSummaryManager {
 
   const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
 
-  const RetainSummary *getPersistentSummary(RetEffect RetEff,
-                                            ArgEffects ScratchArgs,
-                                            ArgEffect ReceiverEff = DoNothing,
-                                            ArgEffect DefaultEff = MayEscape,
-                                            ArgEffect ThisEff = DoNothing) {
-    RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff,
-                       ThisEff);
+  const RetainSummary *
+  getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs,
+                       ArgEffect ReceiverEff = ArgEffect(DoNothing),
+                       ArgEffect DefaultEff = ArgEffect(MayEscape),
+                       ArgEffect ThisEff = ArgEffect(DoNothing)) {
+    RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
     return getPersistentSummary(Summ);
   }
 
   const RetainSummary *getDoNothingSummary() {
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ArgEffects(AF.getEmptyMap()),
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   }
 
   const RetainSummary *getDefaultSummary() {
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ArgEffects(AF.getEmptyMap()),
-                                DoNothing, MayEscape);
+                                ArgEffect(DoNothing), ArgEffect(MayEscape));
   }
 
   const RetainSummary *getPersistentStopSummary() {
-    return getPersistentSummary(RetEffect::MakeNoRet(),
-                                ArgEffects(AF.getEmptyMap()),
-                                StopTracking, StopTracking);
+    return getPersistentSummary(
+        RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()),
+        ArgEffect(StopTracking), ArgEffect(StopTracking));
   }
 
   void InitializeClassMethodSummaries();

Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=350858&r1=350857&r2=350858&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Thu Jan 10 10:13:59 2019
@@ -1484,13 +1484,13 @@ void ObjCMigrateASTConsumer::AddCFAnnota
        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
+    if (AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
         NSAPIObj->isMacroDefined("CF_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
       Editor->commit(commit);
     }
-    else if (AE == DecRefMsg && !pd->hasAttr<NSConsumedAttr>() &&
+    else if (AE.getKind() == DecRefMsg && !pd->hasAttr<NSConsumedAttr>() &&
              NSAPIObj->isMacroDefined("NS_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
@@ -1536,13 +1536,13 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) {
-      if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>())
+    if (AE.getKind() == DecRef /*CFConsumed annotated*/ ||
+        AE.getKind() == IncRef) {
+      if (AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>())
         ArgCFAudited = true;
-      else if (AE == IncRef)
+      else if (AE.getKind() == IncRef)
         ArgCFAudited = true;
-    }
-    else {
+    } else {
       QualType AT = pd->getType();
       if (!AuditedType(AT)) {
         AddCFAnnotations(Ctx, CE, FuncDecl, FuncIsReturnAnnotated);
@@ -1610,7 +1610,7 @@ void ObjCMigrateASTConsumer::AddCFAnnota
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
+    if (AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
         NSAPIObj->isMacroDefined("CF_CONSUMED")) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
@@ -1626,13 +1626,14 @@ void ObjCMigrateASTConsumer::migrateAddM
     return;
 
   CallEffects CE  = CallEffects::getEffect(MethodDecl);
-  bool MethodIsReturnAnnotated = (MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
-                                  MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
-                                  MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
-                                  MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
-                                  MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
+  bool MethodIsReturnAnnotated =
+      (MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
+       MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
+       MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
+       MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
+       MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
 
-  if (CE.getReceiver() == DecRefMsg &&
+  if (CE.getReceiver().getKind() == DecRefMsg &&
       !MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
       MethodDecl->getMethodFamily() != OMF_init &&
       MethodDecl->getMethodFamily() != OMF_release &&
@@ -1666,8 +1667,8 @@ void ObjCMigrateASTConsumer::migrateAddM
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if ((AE == DecRef && !pd->hasAttr<CFConsumedAttr>()) || AE == IncRef ||
-        !AuditedType(pd->getType())) {
+    if ((AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>()) ||
+        AE.getKind() == IncRef || !AuditedType(pd->getType())) {
       AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
       return;
     }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=350858&r1=350857&r2=350858&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp Thu Jan 10 10:13:59 2019
@@ -248,7 +248,7 @@ void RetainCountChecker::checkPostStmt(c
   if (!BE)
     return;
 
-  ArgEffect AE = IncRef;
+  ArgEffectKind AE = IncRef;
 
   switch (BE->getBridgeKind()) {
     case OBC_Bridge:
@@ -534,7 +534,7 @@ void RetainCountChecker::processSummaryO
     SVal V = CallOrMsg.getArgSVal(idx);
 
     if (SymbolRef Sym = V.getAsLocSymbol()) {
-      bool ShouldRemoveBinding = Summ.getArg(idx) == StopTrackingHard;
+      bool ShouldRemoveBinding = Summ.getArg(idx).getKind() == StopTrackingHard;
       if (const RefVal *T = getRefBinding(state, Sym))
         if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
           ShouldRemoveBinding = true;
@@ -547,7 +547,7 @@ void RetainCountChecker::processSummaryO
   // Evaluate the effect on the message receiver.
   if (const auto *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg)) {
     if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
-      if (Summ.getReceiverEffect() == StopTrackingHard) {
+      if (Summ.getReceiverEffect().getKind() == StopTrackingHard) {
         state = removeRefBinding(state, Sym);
       }
     }
@@ -566,7 +566,7 @@ void RetainCountChecker::processSummaryO
 
 static ProgramStateRef updateOutParameter(ProgramStateRef State,
                                           SVal ArgVal,
-                                          ArgEffect Effect) {
+                                          ArgEffectKind Effect) {
   auto *ArgRegion = dyn_cast_or_null<TypedValueRegion>(ArgVal.getAsRegion());
   if (!ArgRegion)
     return State;
@@ -611,7 +611,7 @@ void RetainCountChecker::checkSummary(co
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
     SVal V = CallOrMsg.getArgSVal(idx);
 
-    ArgEffect Effect = Summ.getArg(idx);
+    ArgEffectKind Effect = Summ.getArg(idx).getKind();
     if (Effect == RetainedOutParameter || Effect == UnretainedOutParameter) {
       state = updateOutParameter(state, V, Effect);
     } else if (SymbolRef Sym = V.getAsLocSymbol()) {
@@ -637,8 +637,8 @@ void RetainCountChecker::checkSummary(co
       if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
         if (const RefVal *T = getRefBinding(state, Sym)) {
           ReceiverIsTracked = true;
-          state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
-                                 hasErr, C);
+          state = updateSymbol(state, Sym, *T,
+                               Summ.getReceiverEffect().getKind(), hasErr, C);
           if (hasErr) {
             ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
             ErrorSym = Sym;
@@ -648,7 +648,7 @@ void RetainCountChecker::checkSummary(co
     } 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(),
+          state = updateSymbol(state, Sym, *T, Summ.getThisEffect().getKind(),
                                hasErr, C);
           if (hasErr) {
             ErrorRange = MCall->getOriginExpr()->getSourceRange();
@@ -707,10 +707,11 @@ void RetainCountChecker::checkSummary(co
   }
 }
 
-ProgramStateRef
-RetainCountChecker::updateSymbol(ProgramStateRef state, SymbolRef sym,
-                                 RefVal V, ArgEffect E, RefVal::Kind &hasErr,
-                                 CheckerContext &C) const {
+ProgramStateRef RetainCountChecker::updateSymbol(ProgramStateRef state,
+                                                 SymbolRef sym, RefVal V,
+                                                 ArgEffectKind E,
+                                                 RefVal::Kind &hasErr,
+                                                 CheckerContext &C) const {
   bool IgnoreRetainMsg = (bool)C.getASTContext().getLangOpts().ObjCAutoRefCount;
   switch (E) {
   default:
@@ -1405,7 +1406,7 @@ void RetainCountChecker::checkBeginFunct
 
     QualType Ty = Param->getType();
     const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
-    if (AE && *AE == DecRef && isISLObjectRef(Ty)) {
+    if (AE && AE->getKind() == DecRef && isISLObjectRef(Ty)) {
       state = setRefBinding(
           state, Sym, RefVal::makeOwned(ObjKind::Generalized, Ty));
     } else if (isISLObjectRef(Ty)) {

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h?rev=350858&r1=350857&r2=350858&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h Thu Jan 10 10:13:59 2019
@@ -347,7 +347,7 @@ public:
   void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
 
   ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
-                               RefVal V, ArgEffect E, RefVal::Kind &hasErr,
+                               RefVal V, ArgEffectKind E, RefVal::Kind &hasErr,
                                CheckerContext &C) const;
 
   void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=350858&r1=350857&r2=350858&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp Thu Jan 10 10:13:59 2019
@@ -48,7 +48,9 @@ static bool shouldGenerateNote(llvm::raw
   RefVal PrevV = *PrevT;
 
   // Specially handle -dealloc.
-  if (std::find(AEffects.begin(), AEffects.end(), Dealloc) != AEffects.end()) {
+  if (std::find_if(AEffects.begin(), AEffects.end(), [](ArgEffect &E) {
+        return E.getKind() == Dealloc;
+      }) != AEffects.end()) {
     // Determine if the object's reference count was pushed to zero.
     assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
     // We may not have transitioned to 'release' if we hit an error.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=350858&r1=350857&r2=350858&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Jan 10 10:13:59 2019
@@ -201,8 +201,8 @@ const RetainSummary *RetainSummaryManage
     // Part of: <rdar://problem/39390714>.
     return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
                                 ScratchArgs,
-                                DoNothing,
-                                DoNothing);
+                                ArgEffect(DoNothing),
+                                ArgEffect(DoNothing));
   } else if (FName == "CFPlugInInstanceCreate") {
     return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs);
   } else if (FName == "IORegistryEntrySearchCFProperty" ||
@@ -213,25 +213,25 @@ const RetainSummary *RetainSummaryManage
                FName == "IOOpenFirmwarePathMatching"))) {
     // Part of <rdar://problem/6961230>. (IOKit)
     // This should be addressed using a API table.
-    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
-                                ScratchArgs, DoNothing, DoNothing);
+    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs,
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "IOServiceGetMatchingService" ||
              FName == "IOServiceGetMatchingServices") {
     // FIXES: <rdar://problem/6326900>
     // This should be addressed using a API table.  This strcmp is also
     // a little gross, but there is no need to super optimize here.
-    ScratchArgs = AF.add(ScratchArgs, 1, DecRef);
+    ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(DecRef, ObjKind::CF));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "IOServiceAddNotification" ||
              FName == "IOServiceAddMatchingNotification") {
     // Part of <rdar://problem/6961230>. (IOKit)
     // This should be addressed using a API table.
-    ScratchArgs = AF.add(ScratchArgs, 2, DecRef);
+    ScratchArgs = AF.add(ScratchArgs, 2, ArgEffect(DecRef, ObjKind::CF));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "CVPixelBufferCreateWithBytes") {
     // FIXES: <rdar://problem/7283567>
     // Eventually this can be improved by recognizing that the pixel
@@ -239,38 +239,38 @@ const RetainSummary *RetainSummaryManage
     // a callback and doing full IPA to make sure this is done correctly.
     // FIXME: This function has an out parameter that returns an
     // allocated object.
-    ScratchArgs = AF.add(ScratchArgs, 7, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 7, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "CGBitmapContextCreateWithData") {
     // FIXES: <rdar://problem/7358899>
     // Eventually this can be improved by recognizing that 'releaseInfo'
     // passed to CGBitmapContextCreateWithData is released via
     // a callback and doing full IPA to make sure this is done correctly.
-    ScratchArgs = AF.add(ScratchArgs, 8, StopTracking);
-    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF),
-                                ScratchArgs, DoNothing, DoNothing);
+    ScratchArgs = AF.add(ScratchArgs, 8, ArgEffect(ArgEffect(StopTracking)));
+    return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), ScratchArgs,
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {
     // FIXES: <rdar://problem/7283567>
     // Eventually this can be improved by recognizing that the pixel
     // buffer passed to CVPixelBufferCreateWithPlanarBytes is released
     // via a callback and doing full IPA to make sure this is done
     // correctly.
-    ScratchArgs = AF.add(ScratchArgs, 12, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 12, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "VTCompressionSessionEncodeFrame") {
     // The context argument passed to VTCompressionSessionEncodeFrame()
     // is passed to the callback specified when creating the session
     // (e.g. with VTCompressionSessionCreate()) which can release it.
     // To account for this possibility, conservatively stop tracking
     // the context.
-    ScratchArgs = AF.add(ScratchArgs, 5, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 5, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName == "dispatch_set_context" ||
              FName == "xpc_connection_set_context") {
     // <rdar://problem/11059275> - The analyzer currently doesn't have
@@ -279,20 +279,21 @@ const RetainSummary *RetainSummaryManage
     // <rdar://problem/13783514> - Same problem, but for XPC.
     // FIXME: this hack should possibly go away once we can handle
     // libdispatch and XPC finalizers.
-    ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
                                 ScratchArgs,
-                                DoNothing, DoNothing);
+                                ArgEffect(DoNothing), ArgEffect(DoNothing));
   } else if (FName.startswith("NSLog")) {
     return getDoNothingSummary();
   } else if (FName.startswith("NS") &&
              (FName.find("Insert") != StringRef::npos)) {
     // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
     // be deallocated by NSMapRemove. (radar://11152419)
-    ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
-    ScratchArgs = AF.add(ScratchArgs, 2, StopTracking);
+    ScratchArgs = AF.add(ScratchArgs, 1, ArgEffect(StopTracking));
+    ScratchArgs = AF.add(ScratchArgs, 2, ArgEffect(StopTracking));
     return getPersistentSummary(RetEffect::MakeNoRet(),
-                                ScratchArgs, DoNothing, DoNothing);
+                                ScratchArgs, ArgEffect(DoNothing),
+                                ArgEffect(DoNothing));
   }
 
   if (RetTy->isPointerType()) {
@@ -367,16 +368,17 @@ const RetainSummary *RetainSummaryManage
       // "AppendValue", or "SetAttribute", then we assume that arguments may
       // "escape."  This means that something else holds on to the object,
       // allowing it be used even after its local retain count drops to 0.
-      ArgEffect E = (StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||
-                     StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
-                     StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
-                     StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||
-                     StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
-                        ? MayEscape
-                        : DoNothing;
+      ArgEffectKind E =
+          (StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||
+           StrInStrNoCase(FName, "AddValue") != StringRef::npos ||
+           StrInStrNoCase(FName, "SetValue") != StringRef::npos ||
+           StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||
+           StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)
+              ? MayEscape
+              : DoNothing;
 
       return getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
-                                  DoNothing, E);
+                                  ArgEffect(DoNothing), ArgEffect(E, ObjKind::CF));
     }
   }
 
@@ -415,8 +417,9 @@ RetainSummaryManager::generateSummary(co
     if (!(TrackOSObjects && isOSObjectRelated(MD)))
       return getPersistentSummary(RetEffect::MakeNoRet(),
                                   ArgEffects(AF.getEmptyMap()),
-                                  DoNothing, StopTracking,
-                                  DoNothing);
+                                  ArgEffect(DoNothing),
+                                  ArgEffect(StopTracking),
+                                  ArgEffect(DoNothing));
 
   return getDefaultSummary();
 }
@@ -449,7 +452,7 @@ RetainSummaryManager::getFunctionSummary
 //===----------------------------------------------------------------------===//
 
 static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {
-  switch (E) {
+  switch (E.getKind()) {
   case DoNothing:
   case Autorelease:
   case DecRefBridgedTransferred:
@@ -461,15 +464,15 @@ static ArgEffect getStopTrackingHardEqui
   case MayEscape:
   case StopTracking:
   case StopTrackingHard:
-    return StopTrackingHard;
+    return E.withKind(StopTrackingHard);
   case DecRef:
   case DecRefAndStopTrackingHard:
-    return DecRefAndStopTrackingHard;
+    return E.withKind(DecRefAndStopTrackingHard);
   case DecRefMsg:
   case DecRefMsgAndStopTrackingHard:
-    return DecRefMsgAndStopTrackingHard;
+    return E.withKind(DecRefMsgAndStopTrackingHard);
   case Dealloc:
-    return Dealloc;
+    return E.withKind(Dealloc);
   }
 
   llvm_unreachable("Unknown ArgEffect kind");
@@ -489,7 +492,7 @@ void RetainSummaryManager::updateSummary
                               E = CustomArgEffects.end();
          I != E; ++I) {
       ArgEffect Translated = getStopTrackingHardEquivalent(I->second);
-      if (Translated != DefEffect)
+      if (Translated.getKind() != DefEffect.getKind())
         ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
     }
 
@@ -535,7 +538,7 @@ void RetainSummaryManager::updateSummary
       ParentMap &PM = LCtx->getAnalysisDeclContext()->getParentMap();
       if (!PM.isConsumedExpr(ME)) {
         RetainSummaryTemplate ModifiableSummaryTemplate(S, *this);
-        ModifiableSummaryTemplate->setReceiverEffect(DoNothing);
+        ModifiableSummaryTemplate->setReceiverEffect(ArgEffect(DoNothing));
         ModifiableSummaryTemplate->setRetEffect(RetEffect::MakeNoRet());
       }
     }
@@ -661,43 +664,43 @@ RetainSummaryManager::getUnarySummary(co
 
   ArgEffect Effect;
   switch (func) {
-  case cfretain: Effect = IncRef; break;
-  case cfrelease: Effect = DecRef; break;
-  case cfautorelease: Effect = Autorelease; break;
-  case cfmakecollectable: Effect = MakeCollectable; break;
+  case cfretain: Effect = Effect.withKind(IncRef); break;
+  case cfrelease: Effect = Effect.withKind(DecRef); break;
+  case cfautorelease: Effect = Effect.withKind(Autorelease); break;
+  case cfmakecollectable: Effect = Effect.withKind(MakeCollectable); break;
   }
 
   ScratchArgs = AF.add(ScratchArgs, 0, Effect);
   return getPersistentSummary(RetEffect::MakeNoRet(),
                               ScratchArgs,
-                              DoNothing, DoNothing);
+                              ArgEffect(DoNothing), ArgEffect(DoNothing));
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
                               AF.getEmptyMap(),
-                              /*ReceiverEff=*/DoNothing,
-                              /*DefaultEff=*/DoNothing,
-                              /*ThisEff=*/IncRef);
+                              /*ReceiverEff=*/ArgEffect(DoNothing),
+                              /*DefaultEff=*/ArgEffect(DoNothing),
+                              /*ThisEff=*/ArgEffect(IncRef, ObjKind::OS));
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryReleaseRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
                               AF.getEmptyMap(),
-                              /*ReceiverEff=*/DoNothing,
-                              /*DefaultEff=*/DoNothing,
-                              /*ThisEff=*/DecRef);
+                              /*ReceiverEff=*/ArgEffect(DoNothing),
+                              /*DefaultEff=*/ArgEffect(DoNothing),
+                              /*ThisEff=*/ArgEffect(DecRef, ObjKind::OS));
 }
 
 const RetainSummary *
 RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNoRet(),
                               AF.getEmptyMap(),
-                              /*ReceiverEff=*/DoNothing,
-                              /*DefaultEff=*/DoNothing,
-                              /*ThisEff=*/Dealloc);
+                              /*ReceiverEff=*/ArgEffect(DoNothing),
+                              /*DefaultEff=*/ArgEffect(DoNothing),
+                              /*ThisEff=*/ArgEffect(Dealloc, ObjKind::OS));
 }
 
 const RetainSummary *
@@ -722,7 +725,7 @@ const RetainSummary *
 RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::CF),
                               ArgEffects(AF.getEmptyMap()),
-                              DoNothing, DoNothing);
+                              ArgEffect(DoNothing), ArgEffect(DoNothing));
 }
 
 
@@ -775,19 +778,24 @@ bool RetainSummaryManager::applyFunction
     const ParmVarDecl *pd, unsigned parm_idx, const FunctionDecl *FD,
     RetainSummaryTemplate &Template) {
   if (hasEnabledAttr<NSConsumedAttr>(pd)) {
-    Template->addArg(AF, parm_idx, DecRefMsg);
+    Template->addArg(AF, parm_idx, ArgEffect(DecRefMsg, ObjKind::ObjC));
+    return true;
+  } else if (hasEnabledAttr<CFConsumedAttr>(pd)) {
+    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
+    return true;
+  } else if (hasEnabledAttr<OSConsumedAttr>(pd)) {
+    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::OS));
     return true;
-  } else if (hasEnabledAttr<CFConsumedAttr>(pd) ||
-             hasEnabledAttr<OSConsumedAttr>(pd) ||
-             hasRCAnnotation(pd, "rc_ownership_consumed")) {
-    Template->addArg(AF, parm_idx, DecRef);
+  } else if (hasRCAnnotation(pd, "rc_ownership_consumed")) {
+    Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::Generalized));
     return true;
   } else if (hasEnabledAttr<CFReturnsRetainedAttr>(pd) ||
              hasRCAnnotation(pd, "rc_ownership_returns_retained")) {
     QualType PointeeTy = pd->getType()->getPointeeType();
     if (!PointeeTy.isNull()) {
       if (coreFoundation::isCFObjectRef(PointeeTy)) {
-        Template->addArg(AF, parm_idx, RetainedOutParameter);
+        Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter,
+                                                 ObjKind::CF));
         return true;
       }
     }
@@ -795,7 +803,8 @@ bool RetainSummaryManager::applyFunction
     QualType PointeeTy = pd->getType()->getPointeeType();
     if (!PointeeTy.isNull()) {
       if (coreFoundation::isCFObjectRef(PointeeTy)) {
-        Template->addArg(AF, parm_idx, UnretainedOutParameter);
+        Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter,
+                                                 ObjKind::CF));
         return true;
       }
     }
@@ -834,7 +843,7 @@ RetainSummaryManager::updateSummaryFromA
     Template->setRetEffect(*RetE);
 
   if (hasEnabledAttr<OSConsumesThisAttr>(FD))
-    Template->setThisEffect(DecRef);
+    Template->setThisEffect(ArgEffect(DecRef, ObjKind::OS));
 }
 
 void
@@ -848,7 +857,7 @@ RetainSummaryManager::updateSummaryFromA
 
   // Effects on the receiver.
   if (MD->hasAttr<NSConsumesSelfAttr>())
-    Template->setReceiverEffect(DecRefMsg);
+    Template->setReceiverEffect(ArgEffect(DecRefMsg, ObjKind::ObjC));
 
   // Effects on the parameters.
   unsigned parm_idx = 0;
@@ -856,19 +865,23 @@ RetainSummaryManager::updateSummaryFromA
        pi != pe; ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
     if (pd->hasAttr<NSConsumedAttr>()) {
-      Template->addArg(AF, parm_idx, DecRefMsg);
-    } else if (pd->hasAttr<CFConsumedAttr>() || pd->hasAttr<OSConsumedAttr>()) {
-      Template->addArg(AF, parm_idx, DecRef);
+      Template->addArg(AF, parm_idx, ArgEffect(DecRefMsg, ObjKind::ObjC));
+    } else if (pd->hasAttr<CFConsumedAttr>()) {
+      Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::CF));
+    } else if (pd->hasAttr<OSConsumedAttr>()) {
+      Template->addArg(AF, parm_idx, ArgEffect(DecRef, ObjKind::OS));
     } else if (pd->hasAttr<CFReturnsRetainedAttr>()) {
       QualType PointeeTy = pd->getType()->getPointeeType();
       if (!PointeeTy.isNull())
         if (coreFoundation::isCFObjectRef(PointeeTy))
-          Template->addArg(AF, parm_idx, RetainedOutParameter);
+          Template->addArg(AF, parm_idx,
+                           ArgEffect(RetainedOutParameter, ObjKind::CF));
     } else if (pd->hasAttr<CFReturnsNotRetainedAttr>()) {
       QualType PointeeTy = pd->getType()->getPointeeType();
       if (!PointeeTy.isNull())
         if (coreFoundation::isCFObjectRef(PointeeTy))
-          Template->addArg(AF, parm_idx, UnretainedOutParameter);
+          Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter,
+                                                   ObjKind::CF));
     }
   }
 
@@ -881,7 +894,7 @@ const RetainSummary *
 RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
                                                Selector S, QualType RetTy) {
   // Any special effects?
-  ArgEffect ReceiverEff = DoNothing;
+  ArgEffect ReceiverEff = ArgEffect(DoNothing, ObjKind::ObjC);
   RetEffect ResultEff = RetEffect::MakeNoRet();
 
   // Check the method family, and apply any default annotations.
@@ -918,7 +931,7 @@ RetainSummaryManager::getStandardMethodS
       break;
     case OMF_init:
       ResultEff = ObjCInitRetE;
-      ReceiverEff = DecRefMsg;
+      ReceiverEff = ArgEffect(DecRefMsg, ObjKind::ObjC);
       break;
     case OMF_alloc:
     case OMF_new:
@@ -930,16 +943,16 @@ RetainSummaryManager::getStandardMethodS
         ResultEff = RetEffect::MakeOwned(ObjKind::CF);
       break;
     case OMF_autorelease:
-      ReceiverEff = Autorelease;
+      ReceiverEff = ArgEffect(Autorelease, ObjKind::ObjC);
       break;
     case OMF_retain:
-      ReceiverEff = IncRefMsg;
+      ReceiverEff = ArgEffect(IncRefMsg, ObjKind::ObjC);
       break;
     case OMF_release:
-      ReceiverEff = DecRefMsg;
+      ReceiverEff = ArgEffect(DecRefMsg, ObjKind::ObjC);
       break;
     case OMF_dealloc:
-      ReceiverEff = Dealloc;
+      ReceiverEff = ArgEffect(Dealloc, ObjKind::ObjC);
       break;
     case OMF_self:
       // -self is handled specially by the ExprEngine to propagate the receiver.
@@ -961,17 +974,17 @@ RetainSummaryManager::getStandardMethodS
         if (ResultEff == ObjCInitRetE)
           ResultEff = RetEffect::MakeNoRetHard();
         else
-          ReceiverEff = StopTrackingHard;
+          ReceiverEff = ArgEffect(StopTrackingHard, ObjKind::ObjC);
       }
     }
   }
 
-  if (ReceiverEff == DoNothing &&
+  if (ReceiverEff.getKind() == DoNothing &&
       ResultEff.getKind() == RetEffect::NoRet)
     return getDefaultSummary();
 
   return getPersistentSummary(ResultEff, ArgEffects(AF.getEmptyMap()),
-                              ReceiverEff, MayEscape);
+                              ArgEffect(ReceiverEff), ArgEffect(MayEscape));
 }
 
 const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
@@ -1037,11 +1050,11 @@ void RetainSummaryManager::InitializeCla
                                      ScratchArgs));
 
   // Create the [NSAutoreleasePool addObject:] summary.
-  ScratchArgs = AF.add(ScratchArgs, 0, Autorelease);
+  ScratchArgs = AF.add(ScratchArgs, 0, ArgEffect(Autorelease));
   addClassMethSummary("NSAutoreleasePool", "addObject",
-                      getPersistentSummary(RetEffect::MakeNoRet(),
-                                           ScratchArgs,
-                                           DoNothing, Autorelease));
+                      getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
+                                           ArgEffect(DoNothing),
+                                           ArgEffect(Autorelease)));
 }
 
 void RetainSummaryManager::InitializeMethodSummaries() {
@@ -1051,7 +1064,7 @@ void RetainSummaryManager::InitializeMet
   // receiver.
   const RetainSummary *InitSumm = getPersistentSummary(ObjCInitRetE,
                                                        ScratchArgs,
-                                                       DecRefMsg);
+                                                       ArgEffect(DecRefMsg));
   addNSObjectMethSummary(GetNullarySelector("init", Ctx), InitSumm);
 
   // awakeAfterUsingCoder: behaves basically like an 'init' method.  It
@@ -1067,19 +1080,20 @@ void RetainSummaryManager::InitializeMet
 
   // Create the "retain" selector.
   RetEffect NoRet = RetEffect::MakeNoRet();
-  const RetainSummary *Summ = getPersistentSummary(NoRet, ScratchArgs, IncRefMsg);
+  const RetainSummary *Summ =
+      getPersistentSummary(NoRet, ScratchArgs, ArgEffect(IncRefMsg));
   addNSObjectMethSummary(GetNullarySelector("retain", Ctx), Summ);
 
   // Create the "release" selector.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, DecRefMsg);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(DecRefMsg));
   addNSObjectMethSummary(GetNullarySelector("release", Ctx), Summ);
 
   // Create the -dealloc summary.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, Dealloc);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Dealloc));
   addNSObjectMethSummary(GetNullarySelector("dealloc", Ctx), Summ);
 
   // Create the "autorelease" selector.
-  Summ = getPersistentSummary(NoRet, ScratchArgs, Autorelease);
+  Summ = getPersistentSummary(NoRet, ScratchArgs, ArgEffect(Autorelease));
   addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
 
   // For NSWindow, allocated objects are (initially) self-owned.
@@ -1088,8 +1102,9 @@ void RetainSummaryManager::InitializeMet
   //  Thus, we need to track an NSWindow's display status.
   //  This is tracked in <rdar://problem/6062711>.
   //  See also http://llvm.org/bugs/show_bug.cgi?id=3714.
-  const RetainSummary *NoTrackYet = getPersistentSummary(
-      RetEffect::MakeNoRet(), ScratchArgs, StopTracking, StopTracking);
+  const RetainSummary *NoTrackYet =
+      getPersistentSummary(RetEffect::MakeNoRet(), ScratchArgs,
+                           ArgEffect(StopTracking), ArgEffect(StopTracking));
 
   addClassMethSummary("NSWindow", "alloc", NoTrackYet);
 
@@ -1130,8 +1145,7 @@ CallEffects CallEffects::getEffect(const
                          /*TrackNSAndCFObjects=*/true,
                          /*TrackOSObjects=*/false);
   const RetainSummary *S = M.getMethodSummary(MD);
-  CallEffects CE(S->getRetEffect());
-  CE.Receiver = S->getReceiverEffect();
+  CallEffects CE(S->getRetEffect(), S->getReceiverEffect());
   unsigned N = MD->param_size();
   for (unsigned i = 0; i < N; ++i) {
     CE.Args.push_back(S->getArg(i));




More information about the cfe-commits mailing list