r188433 - [static analyzer] add a simple "CallEffects" API to query the retain count semantics of a method.

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


Author: kremenek
Date: Wed Aug 14 18:41:49 2013
New Revision: 188433

URL: http://llvm.org/viewvc/llvm-project?rev=188433&view=rev
Log:
[static analyzer] add a simple "CallEffects" API to query the retain count semantics of a method.

This is intended to be a simplified API, whose internals are
deliberately less efficient for the purpose of a simplified interface,
for use with clients that want to query the analyzer's heuristics for
determining retain count semantics.

There are no immediate clients, but it is intended to be used
by the ObjC modernizer.

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h?rev=188433&r1=188432&r2=188433&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h Wed Aug 14 18:41:49 2013
@@ -180,7 +180,39 @@ public:
     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.
+  llvm::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

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=188433&r1=188432&r2=188433&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Wed Aug 14 18:41:49 2013
@@ -317,6 +317,16 @@ public:
 
     return DefaultArgEffect;
   }
+
+  /// Return the number of argument effects.  This is O(n) in the number
+  /// of arguments.
+  unsigned getNumArgs() const {
+    unsigned N = 0;
+    for (ArgEffects::iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
+      ++N;
+    };
+    return N;
+  }
   
   void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) {
     Args = af.add(Args, idx, e);
@@ -3675,3 +3685,37 @@ void ento::registerRetainCountChecker(Ch
   Mgr.registerChecker<RetainCountChecker>(Mgr.getAnalyzerOptions());
 }
 
+//===----------------------------------------------------------------------===//
+// 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.GCOnly, L.ObjCAutoRefCount);\
+  const RetainSummary *S = M.get ## KIND ## Summary(D);\
+  CallEffects CE(S->getRetEffect());\
+  CE.Receiver = S->getReceiverEffect();\
+  unsigned N = S->getNumArgs();\
+  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
+
+}}}





More information about the cfe-commits mailing list