r178063 - [analyzer] Change inlining policy to inline small functions when reanalyzing ObjC methods as top level.

Anna Zaks ganna at apple.com
Tue Mar 26 11:57:58 PDT 2013


Author: zaks
Date: Tue Mar 26 13:57:58 2013
New Revision: 178063

URL: http://llvm.org/viewvc/llvm-project?rev=178063&view=rev
Log:
[analyzer] Change inlining policy to inline small functions when reanalyzing ObjC methods as top level.

This allows us to better reason about(inline) small wrapper functions.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
    cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
    cfe/trunk/test/Analysis/retain-release-inline.m

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=178063&r1=178062&r2=178063&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue Mar 26 13:57:58 2013
@@ -48,13 +48,13 @@ class CXXConstructorCall;
 
 class ExprEngine : public SubEngine {
 public:
-  /// The modes of inlining.
+  /// The modes of inlining, which override the default analysis-wide settings.
   enum InliningModes {
-    /// Do not inline any of the callees.
-    Inline_None = 0,
-    /// Inline all callees.
-    Inline_All = 0x1
-  } ;
+    /// Follow the default settings for inlining callees.
+    Inline_Regular = 0,
+    /// Do minimal inlining of callees.
+    Inline_Minimal = 0x1
+  };
 
 private:
   AnalysisManager &AMgr;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=178063&r1=178062&r2=178063&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Tue Mar 26 13:57:58 2013
@@ -683,7 +683,7 @@ bool ExprEngine::shouldInlineCall(const
   if (CalleeADC->isBodyAutosynthesized())
     return true;
 
-  if (HowToInline == Inline_None)
+  if (!AMgr.shouldInlineCall())
     return false;
 
   // Check if we should inline a call based on its kind.
@@ -745,6 +745,12 @@ bool ExprEngine::shouldInlineCall(const
     NumReachedInlineCountMax++;
     return false;
   }
+
+  if (HowToInline == Inline_Minimal &&
+      (CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize()
+      || IsRecursive))
+    return false;
+
   Engine.FunctionSummaries->bumpNumTimesInlined(D);
 
   return true;

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=178063&r1=178062&r2=178063&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Tue Mar 26 13:57:58 2013
@@ -234,11 +234,11 @@ public:
       else if (Mode == AM_Path) {
         llvm::errs() << " (Path, ";
         switch (IMode) {
-          case ExprEngine::Inline_None:
-            llvm::errs() << " Inline_None";
+          case ExprEngine::Inline_Minimal:
+            llvm::errs() << " Inline_Minimal";
             break;
-          case ExprEngine::Inline_All:
-            llvm::errs() << " Inline_All";
+          case ExprEngine::Inline_Regular:
+            llvm::errs() << " Inline_Regular";
             break;
         }
         llvm::errs() << ")";
@@ -284,7 +284,8 @@ public:
   virtual void HandleTranslationUnit(ASTContext &C);
 
   /// \brief Determine which inlining mode should be used when this function is
-  /// analyzed. For example, determines if the callees should be inlined.
+  /// analyzed. This allows to redefine the default inlining policies when
+  /// analyzing a given function.
   ExprEngine::InliningModes
   getInliningModeForFunction(const Decl *D, SetOfConstDecls Visited);
 
@@ -299,7 +300,7 @@ public:
   /// set of functions which should be considered analyzed after analyzing the
   /// given root function.
   void HandleCode(Decl *D, AnalysisMode Mode,
-                  ExprEngine::InliningModes IMode = ExprEngine::Inline_None,
+                  ExprEngine::InliningModes IMode = ExprEngine::Inline_Minimal,
                   SetOfConstDecls *VisitedCallees = 0);
 
   void RunPathSensitiveChecks(Decl *D,
@@ -410,22 +411,18 @@ static bool shouldSkipFunction(const Dec
 ExprEngine::InliningModes
 AnalysisConsumer::getInliningModeForFunction(const Decl *D,
                                              SetOfConstDecls Visited) {
-  ExprEngine::InliningModes HowToInline =
-      (Mgr->shouldInlineCall()) ? ExprEngine::Inline_All :
-                                  ExprEngine::Inline_None;
-
   // We want to reanalyze all ObjC methods as top level to report Retain
-  // Count naming convention errors more aggressively. But we can turn off
+  // Count naming convention errors more aggressively. But we should tune down
   // inlining when reanalyzing an already inlined function.
   if (Visited.count(D)) {
     assert(isa<ObjCMethodDecl>(D) &&
            "We are only reanalyzing ObjCMethods.");
     const ObjCMethodDecl *ObjCM = cast<ObjCMethodDecl>(D);
     if (ObjCM->getMethodFamily() != OMF_init)
-      HowToInline = ExprEngine::Inline_None;
+      return ExprEngine::Inline_Minimal;
   }
 
-  return HowToInline;
+  return ExprEngine::Inline_Regular;
 }
 
 void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) {
@@ -595,7 +592,7 @@ void AnalysisConsumer::HandleCode(Decl *
     checkerMgr->runCheckersOnASTBody(D, *Mgr, BR);
   if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) {
     RunPathSensitiveChecks(D, IMode, VisitedCallees);
-    if (IMode != ExprEngine::Inline_None)
+    if (IMode != ExprEngine::Inline_Minimal)
       NumFunctionsAnalyzed++;
   }
 }

Modified: cfe/trunk/test/Analysis/retain-release-inline.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release-inline.m?rev=178063&r1=178062&r2=178063&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/retain-release-inline.m (original)
+++ cfe/trunk/test/Analysis/retain-release-inline.m Tue Mar 26 13:57:58 2013
@@ -361,3 +361,30 @@ CFStringRef testCovariantReturnType() {
   }
   return Str;
 }
+
+// Test that we reanalyze ObjC methods which have been inlined. When reanalyzing
+// them, make sure we inline very small functions.
+
+ at interface MyClass : NSObject
+- (id)test_return_retained_NS;
+- (void)test_return_retained;
+ at end
+
+id returnInputParam(id x) {
+  return x;
+}
+ at implementation MyClass
+- (id)test_return_retained_NS {
+  // This method does not follow naming conventions, so a warning will be
+  // reported when it is reanalyzed at top level.
+  return returnInputParam([[NSString alloc] init]); // expected-warning {{leak}}
+}
+
+- (void)test_return_retained {
+  id x = test_return_retained_NS(); // expected-warning {{leak}}
+  [x retain];
+  [x release];
+}
+
+ at end
+





More information about the cfe-commits mailing list