For forward-declared static inline functions, delay CFG-based warnings until we
encounter a definition.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99243 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index a044576..45b08db 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -353,8 +353,14 @@
 
     // Only analyze 'static inline' functions when explicitly asked.
     if (!analyzeStaticInline && FD->isInlineSpecified() &&
-        FD->getStorageClass() == FunctionDecl::Static)
-      return;
+        FD->getStorageClass() == FunctionDecl::Static) {
+      FD = FD->getCanonicalDecl();
+      VisitFlag &visitFlag = VisitedFD[FD];
+      if (visitFlag == Pending)
+        visitFlag = Visited;
+      else
+        return;
+    }
   }
 
   const Stmt *Body = D->getBody();
@@ -397,18 +403,26 @@
             if (const DeclRefExpr *DR =
                 dyn_cast<DeclRefExpr>(CE->getCallee()->IgnoreParenCasts()))
               if (const FunctionDecl *calleeD =
-                  dyn_cast<FunctionDecl>(DR->getDecl()))
+                  dyn_cast<FunctionDecl>(DR->getDecl())) {
+                calleeD = calleeD->getCanonicalDecl();
                 if (calleeD->isInlineSpecified() &&
                     calleeD->getStorageClass() == FunctionDecl::Static) {
                   // Have we analyzed this static inline function before?
-                  unsigned &visited = VisitedFD[calleeD];
-                  if (!visited) {
+                  VisitFlag &visitFlag = VisitedFD[calleeD];
+                  if (visitFlag == NotVisited) {
                     // Mark the callee visited prior to analyzing it
                     // so we terminate in case of recursion.
-                    visited = 1;
-                    IssueWarnings(DefaultPolicy, calleeD, QualType(), true);
+                    if (calleeD->getBody()) {
+                      visitFlag = Visited;
+                      IssueWarnings(DefaultPolicy, calleeD, QualType(), true);
+                    }
+                    else {
+                      // Delay warnings until we encounter the definition.
+                      visitFlag = Pending;
+                    }
                   }
                 }
+              }
       }
     }
   }