]> granicus.if.org Git - clang/commitdiff
Fix PR2236
authorNate Begeman <natebegeman@mac.com>
Sun, 20 Apr 2008 20:38:08 +0000 (20:38 +0000)
committerNate Begeman <natebegeman@mac.com>
Sun, 20 Apr 2008 20:38:08 +0000 (20:38 +0000)
Add test
Implement feedback from Chris re: PR1998

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50001 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
test/CodeGen/unusedstatic.c [new file with mode: 0644]

index 51d0a89cea396f21b4d8a8b5d0752b6a89419774..98a8aaaf86d4d9f07c6cd15673ba3377a3938d35 100644 (file)
@@ -303,6 +303,19 @@ void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
     // If the function is a static, defer code generation until later so we can
     // easily omit unused statics.
     if (FD->getStorageClass() == FunctionDecl::Static) {
+      // We need to check the Module here to see if GetAddrOfFunctionDecl() has
+      // already added this function to the Module because the address of the
+      // function's prototype was taken.  If this is the case, call 
+      // GetAddrOfFunctionDecl to insert the static FunctionDecl into the used
+      // GlobalDeclsMap, so that EmitStatics will generate code for it later.
+      //
+      // Example:
+      // static int foo();
+      // int bar() { return foo(); }
+      // static int foo() { return 5; }
+      if (getModule().getFunction(FD->getName()))
+        GetAddrOfFunctionDecl(FD, true);
+
       StaticDecls.push_back(FD);
       return;
     }
@@ -320,7 +333,7 @@ void CodeGenModule::EmitStatics() {
     for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) {
       // Check the map of used decls for our static. If not found, continue.
       const Decl *D = StaticDecls[i];
-      if (GlobalDeclMap[D] == 0)
+      if (!GlobalDeclMap.count(D))
         continue;
       
       // If this is a function decl, generate code for the static function if it
@@ -330,8 +343,7 @@ void CodeGenModule::EmitStatics() {
         if (FD->getBody())
           CodeGenFunction(*this).GenerateCode(FD);
       } else {
-        const VarDecl *VD = cast<VarDecl>(D);
-        EmitGlobalVarInit(VD);
+        EmitGlobalVarInit(cast<VarDecl>(D));
       }
       // Erase the used decl from the list.
       StaticDecls[i] = StaticDecls.back();
@@ -346,8 +358,8 @@ void CodeGenModule::EmitStatics() {
   
   // Warn about all statics that are still unused at end of code generation.
   for (unsigned i = 0, e = StaticDecls.size(); i != e; ++i) {
-    const Decl *D = StaticDecls[i];
-    std::string Msg = cast<NamedDecl>(D)->getName();
+    const NamedDecl *D = StaticDecls[i];
+    std::string Msg = D->getName();
     getDiags().Report(Context.getFullLoc(D->getLocation()), 
                       diag::warn_unused_static, &Msg, 1);
   }
index aa676d6fdc686ba38f0eef021d557f119b66433c..e048d59564422f4cd33d49aea1cec6888639f865 100644 (file)
@@ -34,9 +34,8 @@ namespace clang {
   class Decl;
   class Expr;
   class Stmt;
-  class ValueDecl;
+  class NamedDecl;
   class VarDecl;
-  class TypeDecl;
   struct LangOptions;
   class Diagnostic;
   class AnnotateAttr;
@@ -59,7 +58,7 @@ class CodeGenModule {
   llvm::Function *MemCpyFn;
   llvm::Function *MemSetFn;
   llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap;
-  std::vector<const Decl*> StaticDecls;
+  std::vector<const NamedDecl*> StaticDecls;
   
   std::vector<llvm::Constant*> GlobalCtors;
   std::vector<llvm::Constant*> Annotations;
diff --git a/test/CodeGen/unusedstatic.c b/test/CodeGen/unusedstatic.c
new file mode 100644 (file)
index 0000000..902596e
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: clang %s -emit-llvm -verify
+// PR1998
+// PR2236
+static void a (void);
+void b (void) { a (); }
+static void a(void) {}
+static void c(void) {}  // expected-warning {{static 'c' defined but not used}}