r188432 - [static analyzer] Factor out ArgEffect and RetEffect into public header file.

Ted Kremenek kremenek at apple.com
Wed Aug 14 16:41:46 PDT 2013


Author: kremenek
Date: Wed Aug 14 18:41:46 2013
New Revision: 188432

URL: http://llvm.org/viewvc/llvm-project?rev=188432&view=rev
Log:
[static analyzer] Factor out ArgEffect and RetEffect into public header file.

This is a WIP change to allow other clients to query the retain count
heuristics of the static analyzer.

Added:
    cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp

Added: cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h?rev=188432&view=auto
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h (added)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h Wed Aug 14 18:41:46 2013
@@ -0,0 +1,187 @@
+//==-- 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_OBJCRETAINCOUNT_H
+#define LLVM_CLANG_OBJCRETAINCOUNT_H
+
+namespace clang { 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.
+  DecRefBridgedTransfered,
+
+  /// 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 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 cannot be 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 owned (+1) symbol and
+    /// that it should be treated as freshly allocated.
+    OwnedAllocatedSymbol,
+    /// 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 object is not owned and controlled by ARC.
+    ARCNotOwnedSymbol,
+    /// 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
+  };
+  
+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 == OwnedAllocatedSymbol ||
+    K == OwnedWhenTrackedReceiver;
+  }
+  
+  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, bool isAllocated = false) {
+    return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
+  }
+  static RetEffect MakeNotOwned(ObjKind o) {
+    return RetEffect(NotOwnedSymbol, o);
+  }
+  static RetEffect MakeGCNotOwned() {
+    return RetEffect(GCNotOwnedSymbol, ObjC);
+  }
+  static RetEffect MakeARCNotOwned() {
+    return RetEffect(ARCNotOwnedSymbol, ObjC);
+  }
+  static RetEffect MakeNoRet() {
+    return RetEffect(NoRet);
+  }
+  static RetEffect MakeNoRetHard() {
+    return RetEffect(NoRetHard);
+  }
+};
+  
+}}}
+
+#endif
+

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=188432&r1=188431&r2=188432&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Wed Aug 14 18:41:46 2013
@@ -28,6 +28,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableList.h"
@@ -41,116 +42,36 @@
 
 using namespace clang;
 using namespace ento;
+using namespace objc_retain;
 using llvm::StrInStrNoCase;
 
 //===----------------------------------------------------------------------===//
-// Primitives used for constructing summaries for function/method calls.
+// Adapters for FoldingSet.
 //===----------------------------------------------------------------------===//
 
-/// ArgEffect is used to summarize a function/method call's effect on a
-/// particular argument.
-enum ArgEffect { DoNothing, Autorelease, Dealloc, DecRef, DecRefMsg,
-                 DecRefBridgedTransfered,
-                 IncRefMsg, IncRef, MakeCollectable, MayEscape,
-
-                 // Stop tracking the argument - the effect of the call is
-                 // unknown.
-                 StopTracking,
-
-                 // 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,
-
-                 // The function decrements the reference count and the checker 
-                 // should stop tracking the argument.
-                 DecRefAndStopTrackingHard, DecRefMsgAndStopTrackingHard
-               };
-
 namespace llvm {
 template <> struct FoldingSetTrait<ArgEffect> {
-static inline void Profile(const ArgEffect X, FoldingSetNodeID& ID) {
+static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
   ID.AddInteger((unsigned) X);
 }
 };
+template <> struct FoldingSetTrait<RetEffect> {
+  static inline void Profile(const RetEffect &X, FoldingSetNodeID &ID) {
+    ID.AddInteger((unsigned) X.getKind());
+    ID.AddInteger((unsigned) X.getObjKind());
+}
+};
 } // end llvm namespace
 
+//===----------------------------------------------------------------------===//
+// Reference-counting logic (typestate + counts).
+//===----------------------------------------------------------------------===//
+
 /// ArgEffects summarizes the effects of a function/method call on all of
 /// its arguments.
 typedef llvm::ImmutableMap<unsigned,ArgEffect> ArgEffects;
 
 namespace {
-
-///  RetEffect is used to summarize a function/method call's behavior with
-///  respect to its return value.
-class RetEffect {
-public:
-  enum Kind { NoRet, OwnedSymbol, OwnedAllocatedSymbol,
-              NotOwnedSymbol, GCNotOwnedSymbol, ARCNotOwnedSymbol,
-              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
-            };
-
-  enum ObjKind { CF, ObjC, AnyObj };
-
-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 == OwnedAllocatedSymbol ||
-           K == OwnedWhenTrackedReceiver;
-  }
-
-  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, bool isAllocated = false) {
-    return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
-  }
-  static RetEffect MakeNotOwned(ObjKind o) {
-    return RetEffect(NotOwnedSymbol, o);
-  }
-  static RetEffect MakeGCNotOwned() {
-    return RetEffect(GCNotOwnedSymbol, ObjC);
-  }
-  static RetEffect MakeARCNotOwned() {
-    return RetEffect(ARCNotOwnedSymbol, ObjC);
-  }
-  static RetEffect MakeNoRet() {
-    return RetEffect(NoRet);
-  }
-  static RetEffect MakeNoRetHard() {
-    return RetEffect(NoRetHard);
-  }
-
-  void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddInteger((unsigned) K);
-    ID.AddInteger((unsigned) O);
-  }
-};
-
-//===----------------------------------------------------------------------===//
-// Reference-counting logic (typestate + counts).
-//===----------------------------------------------------------------------===//
-
 class RefVal {
 public:
   enum Kind {





More information about the cfe-commits mailing list