Unfortunately, toplev.c is a kitchen sink of things that do not belong anywhere in particular. For example, check_global_declarations is only used in cgraphunit.c. Moving it there allows us to make it static and remove one call to symtab_node::get.
Bootstrapped & regtested on x86_64-linux-gnu. OK? gcc/ChangeLog: 2015-09-15 Manuel López-Ibáñez <m...@gcc.gnu.org> * toplev.h (check_global_declaration): Remove declaration. * toplev.c (check_global_declaration): Move to ... * cgraphunit.c: ... here. Make it static and pass a symtab_node *. (analyze_functions): Update call.
Index: gcc/toplev.c =================================================================== --- gcc/toplev.c (revision 227762) +++ gcc/toplev.c (working copy) @@ -467,73 +467,10 @@ wrapup_global_declarations (tree *vec, i while (reconsider); return output_something; } -/* Issue appropriate warnings for the global declaration DECL. */ - -void -check_global_declaration (tree decl) -{ - /* Warn about any function declared static but not defined. We don't - warn about variables, because many programs have static variables - that exist only to get some text into the object file. */ - symtab_node *snode = symtab_node::get (decl); - if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_INITIAL (decl) == 0 - && DECL_EXTERNAL (decl) - && ! DECL_ARTIFICIAL (decl) - && ! TREE_NO_WARNING (decl) - && ! TREE_PUBLIC (decl) - && (warn_unused_function - || snode->referred_to_p (/*include_self=*/false))) - { - if (snode->referred_to_p (/*include_self=*/false)) - pedwarn (input_location, 0, "%q+F used but never defined", decl); - else - warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl); - /* This symbol is effectively an "extern" declaration now. */ - TREE_PUBLIC (decl) = 1; - } - - /* Warn about static fns or vars defined but not used. */ - if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL) - || (((warn_unused_variable && ! TREE_READONLY (decl)) - || (warn_unused_const_variable && TREE_READONLY (decl))) - && TREE_CODE (decl) == VAR_DECL)) - && ! DECL_IN_SYSTEM_HEADER (decl) - && ! snode->referred_to_p (/*include_self=*/false) - /* This TREE_USED check is needed in addition to referred_to_p - above, because the `__unused__' attribute is not being - considered for referred_to_p. */ - && ! TREE_USED (decl) - /* The TREE_USED bit for file-scope decls is kept in the identifier, - to handle multiple external decls in different scopes. */ - && ! (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl))) - && ! DECL_EXTERNAL (decl) - && ! DECL_ARTIFICIAL (decl) - && ! DECL_ABSTRACT_ORIGIN (decl) - && ! TREE_PUBLIC (decl) - /* A volatile variable might be used in some non-obvious way. */ - && ! TREE_THIS_VOLATILE (decl) - /* Global register variables must be declared to reserve them. */ - && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) - /* Global ctors and dtors are called by the runtime. */ - && (TREE_CODE (decl) != FUNCTION_DECL - || (!DECL_STATIC_CONSTRUCTOR (decl) - && !DECL_STATIC_DESTRUCTOR (decl))) - /* Otherwise, ask the language. */ - && lang_hooks.decls.warn_unused_global (decl)) - warning_at (DECL_SOURCE_LOCATION (decl), - (TREE_CODE (decl) == FUNCTION_DECL) - ? OPT_Wunused_function - : (TREE_READONLY (decl) - ? OPT_Wunused_const_variable - : OPT_Wunused_variable), - "%qD defined but not used", decl); -} - /* Compile an entire translation unit. Write a file of assembly output and various debugging dumps. */ static void compile_file (void) Index: gcc/toplev.h =================================================================== --- gcc/toplev.h (revision 227762) +++ gcc/toplev.h (working copy) @@ -59,11 +59,10 @@ extern void init_eh (void); extern void announce_function (tree); extern void wrapup_global_declaration_1 (tree); extern bool wrapup_global_declaration_2 (tree); extern bool wrapup_global_declarations (tree *, int); -extern void check_global_declaration (tree); extern void global_decl_processing (void); extern void dump_memory_report (bool); extern void dump_profile_report (void); Index: gcc/cgraphunit.c =================================================================== --- gcc/cgraphunit.c (revision 227762) +++ gcc/cgraphunit.c (working copy) @@ -921,10 +921,73 @@ walk_polymorphic_call_targets (hash_set< } } } } +/* Issue appropriate warnings for the global declaration DECL. */ + +static void +check_global_declaration (symtab_node *snode) +{ + tree decl = snode->decl; + + /* Warn about any function declared static but not defined. We don't + warn about variables, because many programs have static variables + that exist only to get some text into the object file. */ + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_INITIAL (decl) == 0 + && DECL_EXTERNAL (decl) + && ! DECL_ARTIFICIAL (decl) + && ! TREE_NO_WARNING (decl) + && ! TREE_PUBLIC (decl) + && (warn_unused_function + || snode->referred_to_p (/*include_self=*/false))) + { + if (snode->referred_to_p (/*include_self=*/false)) + pedwarn (input_location, 0, "%q+F used but never defined", decl); + else + warning (OPT_Wunused_function, "%q+F declared %<static%> but never defined", decl); + /* This symbol is effectively an "extern" declaration now. */ + TREE_PUBLIC (decl) = 1; + } + + /* Warn about static fns or vars defined but not used. */ + if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL) + || (((warn_unused_variable && ! TREE_READONLY (decl)) + || (warn_unused_const_variable && TREE_READONLY (decl))) + && TREE_CODE (decl) == VAR_DECL)) + && ! DECL_IN_SYSTEM_HEADER (decl) + && ! snode->referred_to_p (/*include_self=*/false) + /* This TREE_USED check is needed in addition to referred_to_p + above, because the `__unused__' attribute is not being + considered for referred_to_p. */ + && ! TREE_USED (decl) + /* The TREE_USED bit for file-scope decls is kept in the identifier, + to handle multiple external decls in different scopes. */ + && ! (DECL_NAME (decl) && TREE_USED (DECL_NAME (decl))) + && ! DECL_EXTERNAL (decl) + && ! DECL_ARTIFICIAL (decl) + && ! DECL_ABSTRACT_ORIGIN (decl) + && ! TREE_PUBLIC (decl) + /* A volatile variable might be used in some non-obvious way. */ + && ! TREE_THIS_VOLATILE (decl) + /* Global register variables must be declared to reserve them. */ + && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) + /* Global ctors and dtors are called by the runtime. */ + && (TREE_CODE (decl) != FUNCTION_DECL + || (!DECL_STATIC_CONSTRUCTOR (decl) + && !DECL_STATIC_DESTRUCTOR (decl))) + /* Otherwise, ask the language. */ + && lang_hooks.decls.warn_unused_global (decl)) + warning_at (DECL_SOURCE_LOCATION (decl), + (TREE_CODE (decl) == FUNCTION_DECL) + ? OPT_Wunused_function + : (TREE_READONLY (decl) + ? OPT_Wunused_const_variable + : OPT_Wunused_variable), + "%qD defined but not used", decl); +} /* Discover all functions and variables that are trivially needed, analyze them as well as all functions and variables referred by them */ static cgraph_node *first_analyzed; static varpool_node *first_analyzed_var; @@ -1108,11 +1171,11 @@ analyze_functions (bool first_time) if (first_time) { symtab_node *snode; FOR_EACH_SYMBOL (snode) - check_global_declaration (snode->decl); + check_global_declaration (snode); } if (symtab->dump_file) fprintf (symtab->dump_file, "\nRemoving unused symbols:");