From 1a1d92ac5e1354634af08c62a1d72e263d13be0c Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Sun, 20 Apr 2008 20:38:08 +0000 Subject: [PATCH] Fix PR2236 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 | 22 +++++++++++++++++----- lib/CodeGen/CodeGenModule.h | 5 ++--- test/CodeGen/unusedstatic.c | 7 +++++++ 3 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 test/CodeGen/unusedstatic.c diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 51d0a89cea..98a8aaaf86 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -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(D); - EmitGlobalVarInit(VD); + EmitGlobalVarInit(cast(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(D)->getName(); + const NamedDecl *D = StaticDecls[i]; + std::string Msg = D->getName(); getDiags().Report(Context.getFullLoc(D->getLocation()), diag::warn_unused_static, &Msg, 1); } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index aa676d6fdc..e048d59564 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -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 GlobalDeclMap; - std::vector StaticDecls; + std::vector StaticDecls; std::vector GlobalCtors; std::vector Annotations; diff --git a/test/CodeGen/unusedstatic.c b/test/CodeGen/unusedstatic.c new file mode 100644 index 0000000000..902596e30e --- /dev/null +++ b/test/CodeGen/unusedstatic.c @@ -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}}