[cfe-commits] r99243 - in /cfe/trunk: lib/Sema/AnalysisBasedWarnings.cpp lib/Sema/AnalysisBasedWarnings.h test/Sema/return.c

Ted Kremenek kremenek at apple.com
Mon Mar 22 18:37:13 PDT 2010


Author: kremenek
Date: Mon Mar 22 20:37:12 2010
New Revision: 99243

URL: http://llvm.org/viewvc/llvm-project?rev=99243&view=rev
Log:
For forward-declared static inline functions, delay CFG-based warnings until we
encounter a definition.

Modified:
    cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
    cfe/trunk/lib/Sema/AnalysisBasedWarnings.h
    cfe/trunk/test/Sema/return.c

Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=99243&r1=99242&r2=99243&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Mon Mar 22 20:37:12 2010
@@ -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;
+                    }
                   }
                 }
+              }
       }
     }
   }

Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.h?rev=99243&r1=99242&r2=99243&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.h (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.h Mon Mar 22 20:37:12 2010
@@ -39,7 +39,8 @@
   Sema &S;
   Policy DefaultPolicy;
 
-  llvm::DenseMap<const FunctionDecl*, unsigned> VisitedFD;
+  enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 };
+  llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD;
 
 public:
   AnalysisBasedWarnings(Sema &s);

Modified: cfe/trunk/test/Sema/return.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/return.c?rev=99243&r1=99242&r2=99243&view=diff
==============================================================================
--- cfe/trunk/test/Sema/return.c (original)
+++ cfe/trunk/test/Sema/return.c Mon Mar 22 20:37:12 2010
@@ -227,12 +227,15 @@
 // when they are used.
 static inline int si_has_missing_return() {} // no-warning
 static inline int si_has_missing_return_2() {}; // expected-warning{{control reaches end of non-void function}}
+static inline int si_forward();
 static inline int si_has_missing_return_3(int x) {
   if (x)
    return si_has_missing_return_3(x+1);
 } // expected-warning{{control may reach end of non-void function}}
 
 int test_static_inline(int x) {
+  si_forward();
   return x ? si_has_missing_return_2() : si_has_missing_return_3(x);
 }
+static inline int si_forward() {} // expected-warning{{control reaches end of non-void function}}
 





More information about the cfe-commits mailing list