]> granicus.if.org Git - clang/commitdiff
[analyzer] [NFC] Split up RetainSummaryManager from RetainCountChecker
authorGeorge Karpenkov <ekarpenkov@apple.com>
Sat, 18 Aug 2018 01:45:50 +0000 (01:45 +0000)
committerGeorge Karpenkov <ekarpenkov@apple.com>
Sat, 18 Aug 2018 01:45:50 +0000 (01:45 +0000)
ARCMigrator is using code from RetainCountChecker, which is a layering
violation (and it also does it badly, by using a different header, and
then relying on implementation being present in a header file).

This change splits up RetainSummaryManager into a separate library in
lib/Analysis, which can be used independently of a checker.

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340114 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/clang/Analysis/ObjCRetainCount.h [deleted file]
include/clang/Analysis/RetainSummaryManager.h [moved from lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.h with 70% similarity]
include/clang/StaticAnalyzer/Checkers/SelectorExtras.h [moved from lib/StaticAnalyzer/Checkers/SelectorExtras.h with 85% similarity]
lib/ARCMigrate/CMakeLists.txt
lib/ARCMigrate/ObjCMT.cpp
lib/Analysis/CMakeLists.txt
lib/Analysis/RetainSummaryManager.cpp [moved from lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.cpp with 95% similarity]
lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
lib/StaticAnalyzer/Checkers/CMakeLists.txt
lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp

diff --git a/include/clang/Analysis/ObjCRetainCount.h b/include/clang/Analysis/ObjCRetainCount.h
deleted file mode 100644 (file)
index 9dff1ea..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-//==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- C++ -*--//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the core data structures for retain count "summaries"
-//  for Objective-C and Core Foundation APIs.  These summaries are used
-//  by the static analyzer to summarize the retain/release effects of
-//  function and method calls.  This drives a path-sensitive typestate
-//  analysis in the static analyzer, but can also potentially be used by
-//  other clients.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
-#define LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-class FunctionDecl;
-class ObjCMethodDecl;
-
-namespace ento { namespace objc_retain {
-
-/// An ArgEffect summarizes the retain count behavior on an argument or receiver
-/// to a function or method.
-enum ArgEffect {
-  /// There is no effect.
-  DoNothing,
-
-  /// The argument is treated as if an -autorelease message had been sent to
-  /// the referenced object.
-  Autorelease,
-
-  /// The argument is treated as if an -dealloc message had been sent to
-  /// the referenced object.
-  Dealloc,
-
-  /// The argument has its reference count decreased by 1.  This is as
-  /// if CFRelease has been called on the argument.
-  DecRef,
-
-  /// The argument has its reference count decreased by 1.  This is as
-  /// if a -release message has been sent to the argument.  This differs
-  /// in behavior from DecRef when GC is enabled.
-  DecRefMsg,
-
-  /// The argument has its reference count decreased by 1 to model
-  /// a transferred bridge cast under ARC.
-  DecRefBridgedTransferred,
-
-  /// The argument has its reference count increased by 1.  This is as
-  /// if a -retain message has been sent to the argument.  This differs
-  /// in behavior from IncRef when GC is enabled.
-  IncRefMsg,
-
-  /// The argument has its reference count increased by 1.  This is as
-  /// if CFRetain has been called on the argument.
-  IncRef,
-
-  /// Used to mark an argument as collectible in GC mode, currently a noop.
-  MakeCollectable,
-
-  /// The argument is a pointer to a retain-counted object; on exit, the new
-  /// value of the pointer is a +0 value or NULL.
-  UnretainedOutParameter,
-
-  /// The argument is a pointer to a retain-counted object; on exit, the new
-  /// value of the pointer is a +1 value or NULL.
-  RetainedOutParameter,
-
-  /// The argument is treated as potentially escaping, meaning that
-  /// even when its reference count hits 0 it should be treated as still
-  /// possibly being alive as someone else *may* be holding onto the object.
-  MayEscape,
-
-  /// All typestate tracking of the object ceases.  This is usually employed
-  /// when the effect of the call is completely unknown.
-  StopTracking,
-
-  /// All typestate tracking of the object ceases.  Unlike StopTracking,
-  /// this is also enforced when the method body is inlined.
-  ///
-  /// In some cases, we obtain a better summary for this checker
-  /// by looking at the call site than by inlining the function.
-  /// Signifies that we should stop tracking the symbol even if
-  /// the function is inlined.
-  StopTrackingHard,
-
-  /// Performs the combined functionality of DecRef and StopTrackingHard.
-  ///
-  /// The models the effect that the called function decrements the reference
-  /// count of the argument and all typestate tracking on that argument
-  /// should cease.
-  DecRefAndStopTrackingHard,
-
-  /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
-  ///
-  /// The models the effect that the called function decrements the reference
-  /// count of the argument and all typestate tracking on that argument
-  /// should cease.
-  DecRefMsgAndStopTrackingHard
-};
-
-/// RetEffect summarizes a call's retain/release behavior with respect
-/// to its return value.
-class RetEffect {
-public:
-  enum Kind {
-    /// Indicates that no retain count information is tracked for
-    /// the return value.
-    NoRet,
-    /// Indicates that the returned value is an owned (+1) symbol.
-    OwnedSymbol,
-    /// Indicates that the returned value is an object with retain count
-    /// semantics but that it is not owned (+0).  This is the default
-    /// for getters, etc.
-    NotOwnedSymbol,
-    /// Indicates that the object is not owned and controlled by the
-    /// Garbage collector.
-    GCNotOwnedSymbol,
-    /// Indicates that the return value is an owned object when the
-    /// receiver is also a tracked object.
-    OwnedWhenTrackedReceiver,
-    // Treat this function as returning a non-tracked symbol even if
-    // the function has been inlined. This is used where the call
-    // site summary is more presise than the summary indirectly produced
-    // by inlining the function
-    NoRetHard
-  };
-
-  /// Determines the object kind of a tracked object.
-  enum ObjKind {
-    /// Indicates that the tracked object is a CF object.  This is
-    /// important between GC and non-GC code.
-    CF,
-    /// Indicates that the tracked object is an Objective-C object.
-    ObjC,
-    /// Indicates that the tracked object could be a CF or Objective-C object.
-    AnyObj,
-    /// Indicates that the tracked object is a generalized object.
-    Generalized
-  };
-
-private:
-  Kind K;
-  ObjKind O;
-
-  RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
-
-public:
-  Kind getKind() const { return K; }
-
-  ObjKind getObjKind() const { return O; }
-
-  bool isOwned() const {
-    return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
-  }
-
-  bool notOwned() const {
-    return K == NotOwnedSymbol;
-  }
-
-  bool operator==(const RetEffect &Other) const {
-    return K == Other.K && O == Other.O;
-  }
-
-  static RetEffect MakeOwnedWhenTrackedReceiver() {
-    return RetEffect(OwnedWhenTrackedReceiver, ObjC);
-  }
-
-  static RetEffect MakeOwned(ObjKind o) {
-    return RetEffect(OwnedSymbol, o);
-  }
-  static RetEffect MakeNotOwned(ObjKind o) {
-    return RetEffect(NotOwnedSymbol, o);
-  }
-  static RetEffect MakeGCNotOwned() {
-    return RetEffect(GCNotOwnedSymbol, ObjC);
-  }
-  static RetEffect MakeNoRet() {
-    return RetEffect(NoRet);
-  }
-  static RetEffect MakeNoRetHard() {
-    return RetEffect(NoRetHard);
-  }
-};
-
-/// Encapsulates the retain count semantics on the arguments, return value,
-/// and receiver (if any) of a function/method call.
-///
-/// Note that construction of these objects is not highly efficient.  That
-/// is okay for clients where creating these objects isn't really a bottleneck.
-/// The purpose of the API is to provide something simple.  The actual
-/// static analyzer checker that implements retain/release typestate
-/// tracking uses something more efficient.
-class CallEffects {
-  llvm::SmallVector<ArgEffect, 10> Args;
-  RetEffect Ret;
-  ArgEffect Receiver;
-
-  CallEffects(const RetEffect &R) : Ret(R) {}
-
-public:
-  /// Returns the argument effects for a call.
-  ArrayRef<ArgEffect> getArgs() const { return Args; }
-
-  /// Returns the effects on the receiver.
-  ArgEffect getReceiver() const { return Receiver; }
-
-  /// Returns the effect on the return value.
-  RetEffect getReturnValue() const { return Ret; }
-
-  /// Return the CallEfect for a given Objective-C method.
-  static CallEffects getEffect(const ObjCMethodDecl *MD);
-
-  /// Return the CallEfect for a given C/C++ function.
-  static CallEffects getEffect(const FunctionDecl *FD);
-};
-
-}}}
-
-#endif
-
similarity index 70%
rename from lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.h
rename to include/clang/Analysis/RetainSummaryManager.h
index dd56a4485899b10731efab173c2f9fc6328e839f..b13dc98637ac89c5156c259e422df497bcaef782 100644 (file)
@@ -1,4 +1,4 @@
-//=== RetainCountSummaries.h - Checks for leaks and other issues -*- C++ -*--//
+//=== RetainSummaryManager.h - Summaries for reference counting ---*- C++ -*--//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,25 +7,22 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This file defines summaries implementation for RetainCountChecker, which
+//  This file defines summaries implementation for retain counting, which
 //  implements a reference count checker for Core Foundation and Cocoa
 //  on (Mac OS X).
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_SUMMARY_H
-#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_SUMMARY_H
+#ifndef LLVM_CLANG_LIB_ANALYSIS_RETAINSUMMARYMANAGER
+#define LLVM_CLANG_LIB_ANALYSIS_RETAINSUMMARYMANAGER
 
-#include "../ClangSACheckers.h"
-#include "../AllocationDiagnostics.h"
-#include "../SelectorExtras.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
-#include "clang/Analysis/ObjCRetainCount.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ParentMap.h"
+#include "clang/StaticAnalyzer/Checkers/SelectorExtras.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 
 using namespace clang;
 using namespace ento;
-using namespace objc_retain;
 
 namespace clang {
 namespace ento {
-namespace retaincountchecker {
+
+/// An ArgEffect summarizes the retain count behavior on an argument or receiver
+/// to a function or method.
+enum ArgEffect {
+  /// There is no effect.
+  DoNothing,
+
+  /// The argument is treated as if an -autorelease message had been sent to
+  /// the referenced object.
+  Autorelease,
+
+  /// The argument is treated as if an -dealloc message had been sent to
+  /// the referenced object.
+  Dealloc,
+
+  /// The argument has its reference count decreased by 1.  This is as
+  /// if CFRelease has been called on the argument.
+  DecRef,
+
+  /// The argument has its reference count decreased by 1.  This is as
+  /// if a -release message has been sent to the argument.  This differs
+  /// in behavior from DecRef when GC is enabled.
+  DecRefMsg,
+
+  /// The argument has its reference count decreased by 1 to model
+  /// a transferred bridge cast under ARC.
+  DecRefBridgedTransferred,
+
+  /// The argument has its reference count increased by 1.  This is as
+  /// if a -retain message has been sent to the argument.  This differs
+  /// in behavior from IncRef when GC is enabled.
+  IncRefMsg,
+
+  /// The argument has its reference count increased by 1.  This is as
+  /// if CFRetain has been called on the argument.
+  IncRef,
+
+  /// The argument acts as if has been passed to CFMakeCollectable, which
+  /// transfers the object to the Garbage Collector under GC.
+  MakeCollectable,
+
+  /// The argument is a pointer to a retain-counted object; on exit, the new
+  /// value of the pointer is a +0 value or NULL.
+  UnretainedOutParameter,
+
+  /// The argument is a pointer to a retain-counted object; on exit, the new
+  /// value of the pointer is a +1 value or NULL.
+  RetainedOutParameter,
+
+  /// The argument is treated as potentially escaping, meaning that
+  /// even when its reference count hits 0 it should be treated as still
+  /// possibly being alive as someone else *may* be holding onto the object.
+  MayEscape,
+
+  /// All typestate tracking of the object ceases.  This is usually employed
+  /// when the effect of the call is completely unknown.
+  StopTracking,
+
+  /// All typestate tracking of the object ceases.  Unlike StopTracking,
+  /// this is also enforced when the method body is inlined.
+  ///
+  /// In some cases, we obtain a better summary for this checker
+  /// by looking at the call site than by inlining the function.
+  /// Signifies that we should stop tracking the symbol even if
+  /// the function is inlined.
+  StopTrackingHard,
+
+  /// Performs the combined functionality of DecRef and StopTrackingHard.
+  ///
+  /// The models the effect that the called function decrements the reference
+  /// count of the argument and all typestate tracking on that argument
+  /// should cease.
+  DecRefAndStopTrackingHard,
+
+  /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
+  ///
+  /// The models the effect that the called function decrements the reference
+  /// count of the argument and all typestate tracking on that argument
+  /// should cease.
+  DecRefMsgAndStopTrackingHard
+};
+
+/// RetEffect summarizes a call's retain/release behavior with respect
+/// to its return value.
+class RetEffect {
+public:
+  enum Kind {
+    /// Indicates that no retain count information is tracked for
+    /// the return value.
+    NoRet,
+    /// Indicates that the returned value is an owned (+1) symbol.
+    OwnedSymbol,
+    /// Indicates that the returned value is an object with retain count
+    /// semantics but that it is not owned (+0).  This is the default
+    /// for getters, etc.
+    NotOwnedSymbol,
+    /// Indicates that the object is not owned and controlled by the
+    /// Garbage collector.
+    GCNotOwnedSymbol,
+    /// Indicates that the return value is an owned object when the
+    /// receiver is also a tracked object.
+    OwnedWhenTrackedReceiver,
+    // Treat this function as returning a non-tracked symbol even if
+    // the function has been inlined. This is used where the call
+    // site summary is more presise than the summary indirectly produced
+    // by inlining the function
+    NoRetHard
+  };
+
+  /// Determines the object kind of a tracked object.
+  enum ObjKind {
+    /// Indicates that the tracked object is a CF object.  This is
+    /// important between GC and non-GC code.
+    CF,
+    /// Indicates that the tracked object is an Objective-C object.
+    ObjC,
+    /// Indicates that the tracked object could be a CF or Objective-C object.
+    AnyObj,
+    /// Indicates that the tracked object is a generalized object.
+    Generalized
+  };
+
+private:
+  Kind K;
+  ObjKind O;
+
+  RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
+
+public:
+  Kind getKind() const { return K; }
+
+  ObjKind getObjKind() const { return O; }
+
+  bool isOwned() const {
+    return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
+  }
+
+  bool notOwned() const {
+    return K == NotOwnedSymbol;
+  }
+
+  bool operator==(const RetEffect &Other) const {
+    return K == Other.K && O == Other.O;
+  }
+
+  static RetEffect MakeOwnedWhenTrackedReceiver() {
+    return RetEffect(OwnedWhenTrackedReceiver, ObjC);
+  }
+
+  static RetEffect MakeOwned(ObjKind o) {
+    return RetEffect(OwnedSymbol, o);
+  }
+  static RetEffect MakeNotOwned(ObjKind o) {
+    return RetEffect(NotOwnedSymbol, o);
+  }
+  static RetEffect MakeGCNotOwned() {
+    return RetEffect(GCNotOwnedSymbol, ObjC);
+  }
+  static RetEffect MakeNoRet() {
+    return RetEffect(NoRet);
+  }
+  static RetEffect MakeNoRetHard() {
+    return RetEffect(NoRetHard);
+  }
+};
+
+/// Encapsulates the retain count semantics on the arguments, return value,
+/// and receiver (if any) of a function/method call.
+///
+/// Note that construction of these objects is not highly efficient.  That
+/// is okay for clients where creating these objects isn't really a bottleneck.
+/// The purpose of the API is to provide something simple.  The actual
+/// static analyzer checker that implements retain/release typestate
+/// tracking uses something more efficient.
+class CallEffects {
+  llvm::SmallVector<ArgEffect, 10> Args;
+  RetEffect Ret;
+  ArgEffect Receiver;
+
+  CallEffects(const RetEffect &R) : Ret(R) {}
+
+public:
+  /// Returns the argument effects for a call.
+  ArrayRef<ArgEffect> getArgs() const { return Args; }
+
+  /// Returns the effects on the receiver.
+  ArgEffect getReceiver() const { return Receiver; }
+
+  /// Returns the effect on the return value.
+  RetEffect getReturnValue() const { return Ret; }
+
+  /// Return the CallEfect for a given Objective-C method.
+  static CallEffects getEffect(const ObjCMethodDecl *MD);
+
+  /// Return the CallEfect for a given C/C++ function.
+  static CallEffects getEffect(const FunctionDecl *FD);
+};
 
 /// A key identifying a summary.
 class ObjCSummaryKey {
@@ -68,12 +260,10 @@ public:
   Selector getSelector() const { return S; }
 };
 
-} // end namespace retaincountchecker
 } // end namespace ento
 } // end namespace clang
 
 namespace llvm {
-using namespace retaincountchecker;
 
 template <> struct FoldingSetTrait<ArgEffect> {
 static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
@@ -116,7 +306,6 @@ template <> struct DenseMapInfo<ObjCSummaryKey> {
 
 namespace clang {
 namespace ento {
-namespace retaincountchecker {
 
 /// ArgEffects summarizes the effects of a function/method call on all of
 /// its arguments.
@@ -199,12 +388,12 @@ public:
     return Args.isEmpty();
   }
 
-private:
   ArgEffects getArgEffects() const { return Args; }
+
+private:
   ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
 
   friend class RetainSummaryManager;
-  friend class RetainCountChecker;
 };
 
 class ObjCSummaryCache {
@@ -399,6 +588,9 @@ class RetainSummaryManager {
     addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
   }
 
+  const RetainSummary * generateSummary(const FunctionDecl *FD,
+                                        bool &AllowAnnotations);
+
 public:
   RetainSummaryManager(ASTContext &ctx, bool usesARC)
    : Ctx(ctx),
@@ -419,7 +611,7 @@ public:
   bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);
 
   const RetainSummary *getSummary(const CallEvent &Call,
-                                  ProgramStateRef State = nullptr);
+                                  QualType ReceiverType=QualType());
 
   const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
 
@@ -428,8 +620,9 @@ public:
                                         QualType RetTy,
                                         ObjCMethodSummariesTy &CachedSummaries);
 
-  const RetainSummary *getInstanceMethodSummary(const ObjCMethodCall &M,
-                                                ProgramStateRef State);
+  const RetainSummary *
+  getInstanceMethodSummary(const ObjCMethodCall &M,
+                           QualType ReceiverType);
 
   const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) {
     assert(!M.isInstanceMessage());
@@ -475,10 +668,6 @@ public:
 
   RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
 
-private:
-  const RetainSummary * generateSummary(const FunctionDecl *FD,
-                                        bool &AllowAnnotations);
-
   friend class RetainSummaryTemplate;
 };
 
@@ -511,7 +700,6 @@ public:
   }
 };
 
-} // end namespace retaincountchecker
 } // end namespace ento
 } // end namespace clang
 
similarity index 85%
rename from lib/StaticAnalyzer/Checkers/SelectorExtras.h
rename to include/clang/StaticAnalyzer/Checkers/SelectorExtras.h
index b11d070c629b492a39ce8e351e8f5dd4d114d63c..093eea227961517fb3d9562684d2a4f34ba77ffb 100644 (file)
@@ -33,13 +33,6 @@ static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx,
   Sel = getKeywordSelector(Ctx, IIs...);
 }
 
-static inline void lazyInitNullarySelector(Selector &Sel, ASTContext &Ctx,
-                                           const char *Name) {
-  if (!Sel.isNull())
-    return;
-  Sel = GetNullarySelector(Name, Ctx);
-}
-
 } // end namespace ento
 } // end namespace clang
 
index b716a20fe63f9fc8aaa97bbcce6ae6cfc312c8da..619328ca5ca7611d67afacc6fd487ada96b2a13f 100644 (file)
@@ -34,5 +34,4 @@ add_clang_library(clangARCMigrate
   clangRewrite
   clangSema
   clangSerialization
-  clangStaticAnalyzerCheckers
   )
index 7353c8c479712988ba1b48e36ec5b1b5dbd5572f..29cdb6f53275ed489e659669a5deff6ad9047ed9 100644 (file)
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Transforms.h"
-#include "clang/Analysis/ObjCRetainCount.h"
+#include "clang/Analysis/RetainSummaryManager.h"
 #include "clang/ARCMigrate/ARCMT.h"
 #include "clang/ARCMigrate/ARCMTActions.h"
 #include "clang/AST/ASTConsumer.h"
@@ -35,8 +35,8 @@
 #include "llvm/Support/YAMLParser.h"
 
 using namespace clang;
+using namespace ento;
 using namespace arcmt;
-using namespace ento::objc_retain;
 
 namespace {
 
index 432067d98157560b8cdd69607892e5f35ef0e5bc..818ea16aa7175d2166101593551f2583bb344ba9 100644 (file)
@@ -24,6 +24,7 @@ add_clang_library(clangAnalysis
   ProgramPoint.cpp
   PseudoConstantAnalysis.cpp
   ReachableCode.cpp
+  RetainSummaryManager.cpp
   ScanfFormatString.cpp
   ThreadSafety.cpp
   ThreadSafetyCommon.cpp
similarity index 95%
rename from lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.cpp
rename to lib/Analysis/RetainSummaryManager.cpp
index 18813741f29470eefe482f88a5cbb4b82ac61d51..ba2fce40c506220f227987c97146448a11e4d142 100644 (file)
@@ -1,4 +1,4 @@
-//== RetainCountSummaries.cpp - Checks for leaks and other issues -*- C++ -*--//
+//== RetainSummaryManager.cpp - Summaries for reference counting --*- C++ -*--//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,25 +7,21 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This file defines summaries implementation for RetainCountChecker, which
+//  This file defines summaries implementation for retain counting, which
 //  implements a reference count checker for Core Foundation and Cocoa
 //  on (Mac OS X).
 //
 //===----------------------------------------------------------------------===//
 
-#include "RetainCountSummaries.h"
-#include "RetainCountChecker.h"
-
+#include "clang/Analysis/RetainSummaryManager.h"
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ParentMap.h"
 
-using namespace objc_retain;
 using namespace clang;
 using namespace ento;
-using namespace retaincountchecker;
 
 ArgEffects RetainSummaryManager::getArgEffects() {
   ArgEffects AE = ScratchArgs;
@@ -408,7 +404,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
 
 const RetainSummary *
 RetainSummaryManager::getSummary(const CallEvent &Call,
-                                 ProgramStateRef State) {
+                                 QualType ReceiverType) {
   const RetainSummary *Summ;
   switch (Call.getKind()) {
   case CE_Function:
@@ -425,7 +421,7 @@ RetainSummaryManager::getSummary(const CallEvent &Call,
   case CE_ObjCMessage: {
     const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
     if (Msg.isInstanceMessage())
-      Summ = getInstanceMethodSummary(Msg, State);
+      Summ = getInstanceMethodSummary(Msg, ReceiverType);
     else
       Summ = getClassMethodSummary(Msg);
     break;
@@ -739,22 +735,15 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
   return getPersistentSummary(ResultEff, ReceiverEff, MayEscape);
 }
 
-const RetainSummary *
-RetainSummaryManager::getInstanceMethodSummary(const ObjCMethodCall &Msg,
-                                               ProgramStateRef State) {
+const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
+    const ObjCMethodCall &Msg, QualType ReceiverType) {
   const ObjCInterfaceDecl *ReceiverClass = nullptr;
 
   // We do better tracking of the type of the object than the core ExprEngine.
   // See if we have its type in our private state.
-  // FIXME: Eventually replace the use of state->get<RefBindings> with
-  // a generic API for reasoning about the Objective-C types of symbolic
-  // objects.
-  SVal ReceiverV = Msg.getReceiverSVal();
-  if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
-    if (const RefVal *T = getRefBinding(State, Sym))
-      if (const ObjCObjectPointerType *PT =
-            T->getType()->getAs<ObjCObjectPointerType>())
-        ReceiverClass = PT->getInterfaceDecl();
+  if (!ReceiverType.isNull())
+    if (const auto *PT = ReceiverType->getAs<ObjCObjectPointerType>())
+      ReceiverClass = PT->getInterfaceDecl();
 
   // If we don't know what kind of object this is, fall back to its static type.
   if (!ReceiverClass)
@@ -884,3 +873,30 @@ void RetainSummaryManager::InitializeMethodSummaries() {
                      "format", "colorSpace");
   addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info");
 }
+
+CallEffects CallEffects::getEffect(const ObjCMethodDecl *MD) {
+  ASTContext &Ctx = MD->getASTContext();
+  LangOptions L = Ctx.getLangOpts();
+  RetainSummaryManager M(Ctx, L.ObjCAutoRefCount);
+  const RetainSummary *S = M.getMethodSummary(MD);
+  CallEffects CE(S->getRetEffect());
+  CE.Receiver = S->getReceiverEffect();
+  unsigned N = MD->param_size();
+  for (unsigned i = 0; i < N; ++i) {
+    CE.Args.push_back(S->getArg(i));
+  }
+  return CE;
+}
+
+CallEffects CallEffects::getEffect(const FunctionDecl *FD) {
+  ASTContext &Ctx = FD->getASTContext();
+  LangOptions L = Ctx.getLangOpts();
+  RetainSummaryManager M(Ctx, L.ObjCAutoRefCount);
+  const RetainSummary *S = M.getFunctionSummary(FD);
+  CallEffects CE(S->getRetEffect());
+  unsigned N = FD->param_size();
+  for (unsigned i = 0; i < N; ++i) {
+    CE.Args.push_back(S->getArg(i));
+  }
+  return CE;
+}
index cff0f0a29b0b494366a535e4d03f5f2fa1a98eb1..0e0dc76bafb2029572258dc22ac5fdd4ae8d71e8 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
-#include "SelectorExtras.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
+#include "clang/StaticAnalyzer/Checkers/SelectorExtras.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
index 0b2aab94dabcf7096ae8099e89047dbda8803f75..25cd526e5c85ac6d532d05f1e0aa28edc8b9c675 100644 (file)
@@ -77,7 +77,6 @@ add_clang_library(clangStaticAnalyzerCheckers
   PointerSubChecker.cpp
   PthreadLockChecker.cpp
   RetainCountChecker/RetainCountChecker.cpp
-  RetainCountChecker/RetainCountSummaries.cpp
   RetainCountChecker/RetainCountDiagnostics.cpp
   ReturnPointerRangeChecker.cpp
   ReturnUndefChecker.cpp
index 8a5c769b6b503c97737ec9e9da89205b294e5c77..8a973bb6c1e6c0defdbf74693e08b8c680af8add 100644 (file)
@@ -13,8 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
-#include "SelectorExtras.h"
 #include "clang/AST/Attr.h"
+#include "clang/StaticAnalyzer/Checkers/SelectorExtras.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
index a8957e1704eaeba60030c1549a348110e327daf0..9d6c8314d82de315999e8200db5dada38335c9a9 100644 (file)
@@ -16,7 +16,6 @@
 
 using namespace clang;
 using namespace ento;
-using namespace objc_retain;
 using namespace retaincountchecker;
 using llvm::StrInStrNoCase;
 
@@ -331,7 +330,19 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
 void RetainCountChecker::checkPostCall(const CallEvent &Call,
                                        CheckerContext &C) const {
   RetainSummaryManager &Summaries = getSummaryManager(C);
-  const RetainSummary *Summ = Summaries.getSummary(Call, C.getState());
+
+  // Leave null if no receiver.
+  QualType ReceiverType;
+  if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
+    if (MC->isInstanceMessage()) {
+      SVal ReceiverV = MC->getReceiverSVal();
+      if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
+        if (const RefVal *T = getRefBinding(C.getState(), Sym))
+          ReceiverType = T->getType();
+    }
+  }
+
+  const RetainSummary *Summ = Summaries.getSummary(Call, ReceiverType);
 
   if (C.wasInlined) {
     processSummaryOfInlined(*Summ, Call, C);
@@ -1387,45 +1398,6 @@ void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
   }
 }
 
-//===----------------------------------------------------------------------===//
-// Implementation of the CallEffects API.
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-namespace ento {
-namespace objc_retain {
-
-// This is a bit gross, but it allows us to populate CallEffects without
-// creating a bunch of accessors.  This kind is very localized, so the
-// damage of this macro is limited.
-#define createCallEffect(D, KIND)\
-  ASTContext &Ctx = D->getASTContext();\
-  LangOptions L = Ctx.getLangOpts();\
-  RetainSummaryManager M(Ctx, L.ObjCAutoRefCount);\
-  const RetainSummary *S = M.get ## KIND ## Summary(D);\
-  CallEffects CE(S->getRetEffect());\
-  CE.Receiver = S->getReceiverEffect();\
-  unsigned N = D->param_size();\
-  for (unsigned i = 0; i < N; ++i) {\
-    CE.Args.push_back(S->getArg(i));\
-  }
-
-CallEffects CallEffects::getEffect(const ObjCMethodDecl *MD) {
-  createCallEffect(MD, Method);
-  return CE;
-}
-
-CallEffects CallEffects::getEffect(const FunctionDecl *FD) {
-  createCallEffect(FD, Function);
-  return CE;
-}
-
-#undef createCallEffect
-
-} // end namespace objc_retain
-} // end namespace ento
-} // end namespace clang
-
 //===----------------------------------------------------------------------===//
 // Checker registration.
 //===----------------------------------------------------------------------===//
index 9946591c4d1bb1e18630d0d4a09c8197b314e10b..6d90655d3df892d4a45624e7384811185f6f324a 100644 (file)
 
 #include "../ClangSACheckers.h"
 #include "../AllocationDiagnostics.h"
-#include "../SelectorExtras.h"
-#include "RetainCountSummaries.h"
 #include "RetainCountDiagnostics.h"
-#include "clang/Analysis/ObjCRetainCount.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
+#include "clang/Analysis/RetainSummaryManager.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/StaticAnalyzer/Checkers/SelectorExtras.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
@@ -46,7 +45,6 @@
 #include <cstdarg>
 #include <utility>
 
-using namespace objc_retain;
 using llvm::StrInStrNoCase;
 
 namespace clang {
index cbdfe3a91665ce99cfc250178b7b8a104528176a..8634c37c34005321af492e2d02b7740a80098c8f 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H
 #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H
 
-#include "RetainCountSummaries.h"
+#include "clang/Analysis/RetainSummaryManager.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
index f42c78a76975edb5efbc1e98399fe29a6a7f474b..b28e604b3096e1653c2e5c2433507a7bab3b066f 100644 (file)
@@ -20,7 +20,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
-#include "SelectorExtras.h"
+#include "clang/StaticAnalyzer/Checkers/SelectorExtras.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"