Commit ef4f94ac by Richard Henderson Committed by Richard Henderson

re PR rtl-optimization/4330 (Optimizer generates illegal assembly code)

        PR opt/4330
        * langhooks.h (lang_hooks.decls.warn_unused_global): New.
        * toplev.c (check_global_declarations): Use it.
        * langhooks-def.h (lhd_warn_unused_global_decl): Declare.
        (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
        (LANG_HOOKS_DECLS): Add it.
        * langhooks.c (lhd_warn_unused_global_decl): New.
        * c-decl.c (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
        * c-objc-common.c (c_warn_unused_global_decl): New.
        * c-tree.h (c_warn_unused_global_decl): Declare.
        * objc/objc-lang.c (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.

        * cp-lang.c (cxx_warn_unused_global_decl): New.
        (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.

	* g++.dg/warn/Wunused-2.C: New.
	* gcc.dg/unused-4.c: New.

From-SVN: r51818
parent 599bba86
2002-04-03 Richard Henderson <rth@redhat.com>
PR opt/4330
* langhooks.h (lang_hooks.decls.warn_unused_global): New.
* toplev.c (check_global_declarations): Use it.
* langhooks-def.h (lhd_warn_unused_global_decl): Declare.
(LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
(LANG_HOOKS_DECLS): Add it.
* langhooks.c (lhd_warn_unused_global_decl): New.
* c-decl.c (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
* c-objc-common.c (c_warn_unused_global_decl): New.
* c-tree.h (c_warn_unused_global_decl): Declare.
* objc/objc-lang.c (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
2002-04-03 Neil Booth <neil@daikokuya.demon.co.uk> 2002-04-03 Neil Booth <neil@daikokuya.demon.co.uk>
* langhooks-def.h (lhd_set_decl_assembler_name, * langhooks-def.h (lhd_set_decl_assembler_name,
......
...@@ -66,6 +66,8 @@ static void c_post_options PARAMS ((void)); ...@@ -66,6 +66,8 @@ static void c_post_options PARAMS ((void));
#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval #define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
#undef LANG_HOOKS_STATICP #undef LANG_HOOKS_STATICP
#define LANG_HOOKS_STATICP c_staticp #define LANG_HOOKS_STATICP c_staticp
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
#undef LANG_HOOKS_PRINT_IDENTIFIER #undef LANG_HOOKS_PRINT_IDENTIFIER
#define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier #define LANG_HOOKS_PRINT_IDENTIFIER c_print_identifier
#undef LANG_HOOKS_SET_YYDEBUG #undef LANG_HOOKS_SET_YYDEBUG
......
...@@ -209,6 +209,20 @@ c_cannot_inline_tree_fn (fnp) ...@@ -209,6 +209,20 @@ c_cannot_inline_tree_fn (fnp)
return 0; return 0;
} }
/* Called from check_global_declarations. */
bool
c_warn_unused_global_decl (decl)
tree decl;
{
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
return false;
if (DECL_IN_SYSTEM_HEADER (decl))
return false;
return true;
}
/* Initialization common to C and Objective-C front ends. */ /* Initialization common to C and Objective-C front ends. */
const char * const char *
c_objc_common_init (filename) c_objc_common_init (filename)
......
...@@ -237,6 +237,7 @@ extern const char *c_objc_common_init PARAMS ((const char *)); ...@@ -237,6 +237,7 @@ extern const char *c_objc_common_init PARAMS ((const char *));
extern int c_missing_noreturn_ok_p PARAMS ((tree)); extern int c_missing_noreturn_ok_p PARAMS ((tree));
extern void c_objc_common_finish_file PARAMS ((void)); extern void c_objc_common_finish_file PARAMS ((void));
extern int defer_fn PARAMS ((tree)); extern int defer_fn PARAMS ((tree));
extern bool c_warn_unused_global_decl PARAMS ((tree));
#define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \ #define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \
c_build_qualified_type ((TYPE), \ c_build_qualified_type ((TYPE), \
......
2002-04-03 Richard Henderson <rth@redhat.com>
* cp-lang.c (cxx_warn_unused_global_decl): New.
(LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
2002-04-03 Neil Booth <neil@daikokuya.demon.co.uk> 2002-04-03 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Redefine. * cp-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Redefine.
......
...@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */
static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree)); static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
static bool ok_to_generate_alias_set_for_type PARAMS ((tree)); static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
static bool cxx_warn_unused_global_decl PARAMS ((tree));
#undef LANG_HOOKS_NAME #undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU C++" #define LANG_HOOKS_NAME "GNU C++"
...@@ -87,6 +88,8 @@ static bool ok_to_generate_alias_set_for_type PARAMS ((tree)); ...@@ -87,6 +88,8 @@ static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
#define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function #define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function
#undef LANG_HOOKS_SET_YYDEBUG #undef LANG_HOOKS_SET_YYDEBUG
#define LANG_HOOKS_SET_YYDEBUG cxx_set_yydebug #define LANG_HOOKS_SET_YYDEBUG cxx_set_yydebug
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES #undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \ #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \
...@@ -133,6 +136,47 @@ static bool ok_to_generate_alias_set_for_type PARAMS ((tree)); ...@@ -133,6 +136,47 @@ static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
/* Each front end provides its own hooks, for toplev.c. */ /* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
/* Tree code classes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
const char tree_code_type[] = {
#include "tree.def"
'x',
#include "c-common.def"
'x',
#include "cp-tree.def"
};
#undef DEFTREECODE
/* Table indexed by tree code giving number of expression
operands beyond the fixed part of the node structure.
Not used for types or decls. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
const unsigned char tree_code_length[] = {
#include "tree.def"
0,
#include "c-common.def"
0,
#include "cp-tree.def"
};
#undef DEFTREECODE
/* Names of tree components.
Used for printing out the tree and error messages. */
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
const char *const tree_code_name[] = {
#include "tree.def"
"@@dummy",
#include "c-common.def"
"@@dummy",
#include "cp-tree.def"
};
#undef DEFTREECODE
/* Check if a C++ type is safe for aliasing. /* Check if a C++ type is safe for aliasing.
Return TRUE if T safe for aliasing FALSE otherwise. */ Return TRUE if T safe for aliasing FALSE otherwise. */
...@@ -185,47 +229,6 @@ ok_to_generate_alias_set_for_type (t) ...@@ -185,47 +229,6 @@ ok_to_generate_alias_set_for_type (t)
return true; return true;
} }
/* Tree code classes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
const char tree_code_type[] = {
#include "tree.def"
'x',
#include "c-common.def"
'x',
#include "cp-tree.def"
};
#undef DEFTREECODE
/* Table indexed by tree code giving number of expression
operands beyond the fixed part of the node structure.
Not used for types or decls. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
const unsigned char tree_code_length[] = {
#include "tree.def"
0,
#include "c-common.def"
0,
#include "cp-tree.def"
};
#undef DEFTREECODE
/* Names of tree components.
Used for printing out the tree and error messages. */
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
const char *const tree_code_name[] = {
#include "tree.def"
"@@dummy",
#include "c-common.def"
"@@dummy",
#include "cp-tree.def"
};
#undef DEFTREECODE
/* Special routine to get the alias set for C++. */ /* Special routine to get the alias set for C++. */
static HOST_WIDE_INT static HOST_WIDE_INT
...@@ -238,3 +241,21 @@ cxx_get_alias_set (t) ...@@ -238,3 +241,21 @@ cxx_get_alias_set (t)
return c_common_get_alias_set (t); return c_common_get_alias_set (t);
} }
/* Called from check_global_declarations. */
static bool
cxx_warn_unused_global_decl (decl)
tree decl;
{
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
return false;
if (DECL_IN_SYSTEM_HEADER (decl))
return false;
/* Const variables take the place of #defines in C++. */
if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl))
return false;
return true;
}
...@@ -56,6 +56,7 @@ extern rtx lhd_expand_expr PARAMS ((tree, rtx, enum machine_mode, int)); ...@@ -56,6 +56,7 @@ extern rtx lhd_expand_expr PARAMS ((tree, rtx, enum machine_mode, int));
extern void lhd_print_error_function PARAMS ((struct diagnostic_context *, extern void lhd_print_error_function PARAMS ((struct diagnostic_context *,
const char *)); const char *));
extern void lhd_set_decl_assembler_name PARAMS ((tree)); extern void lhd_set_decl_assembler_name PARAMS ((tree));
extern bool lhd_warn_unused_global_decl PARAMS ((tree));
/* Declarations of default tree inlining hooks. */ /* Declarations of default tree inlining hooks. */
tree lhd_tree_inlining_walk_subtrees PARAMS ((tree *, int *, tree lhd_tree_inlining_walk_subtrees PARAMS ((tree *, int *,
...@@ -176,6 +177,7 @@ int lhd_tree_dump_type_quals PARAMS ((tree)); ...@@ -176,6 +177,7 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
#define LANG_HOOKS_SET_BLOCK set_block #define LANG_HOOKS_SET_BLOCK set_block
#define LANG_HOOKS_PUSHDECL pushdecl #define LANG_HOOKS_PUSHDECL pushdecl
#define LANG_HOOKS_GETDECLS getdecls #define LANG_HOOKS_GETDECLS getdecls
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
#define LANG_HOOKS_DECLS { \ #define LANG_HOOKS_DECLS { \
LANG_HOOKS_PUSHLEVEL, \ LANG_HOOKS_PUSHLEVEL, \
...@@ -184,7 +186,8 @@ int lhd_tree_dump_type_quals PARAMS ((tree)); ...@@ -184,7 +186,8 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
LANG_HOOKS_INSERT_BLOCK, \ LANG_HOOKS_INSERT_BLOCK, \
LANG_HOOKS_SET_BLOCK, \ LANG_HOOKS_SET_BLOCK, \
LANG_HOOKS_PUSHDECL, \ LANG_HOOKS_PUSHDECL, \
LANG_HOOKS_GETDECLS \ LANG_HOOKS_GETDECLS, \
LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL \
} }
/* The whole thing. The structure is defined in langhooks.h. */ /* The whole thing. The structure is defined in langhooks.h. */
......
...@@ -113,6 +113,25 @@ lhd_staticp (exp) ...@@ -113,6 +113,25 @@ lhd_staticp (exp)
return 0; return 0;
} }
/* Called from check_global_declarations. */
bool
lhd_warn_unused_global_decl (decl)
tree decl;
{
/* This is what used to exist in check_global_declarations. Probably
not many of these actually apply to non-C languages. */
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
return false;
if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl))
return false;
if (DECL_IN_SYSTEM_HEADER (decl))
return false;
return true;
}
/* Called when -dy is given on the command line. */ /* Called when -dy is given on the command line. */
void void
......
...@@ -133,6 +133,10 @@ struct lang_hooks_for_decls ...@@ -133,6 +133,10 @@ struct lang_hooks_for_decls
/* Returns the chain of decls so far in the current scope level. */ /* Returns the chain of decls so far in the current scope level. */
tree (*getdecls) PARAMS ((void)); tree (*getdecls) PARAMS ((void));
/* Returns true when we should warn for an unused global DECL.
We will already have checked that it has static binding. */
bool (*warn_unused_global) PARAMS ((tree));
}; };
/* Language-specific hooks. See langhooks-def.h for defaults. */ /* Language-specific hooks. See langhooks-def.h for defaults. */
......
...@@ -68,6 +68,9 @@ static void objc_post_options PARAMS ((void)); ...@@ -68,6 +68,9 @@ static void objc_post_options PARAMS ((void));
#define LANG_HOOKS_DECL_PRINTABLE_NAME objc_printable_name #define LANG_HOOKS_DECL_PRINTABLE_NAME objc_printable_name
#undef LANG_HOOKS_SET_YYDEBUG #undef LANG_HOOKS_SET_YYDEBUG
#define LANG_HOOKS_SET_YYDEBUG c_set_yydebug #define LANG_HOOKS_SET_YYDEBUG c_set_yydebug
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
/* Inlining hooks same as the C front end. */ /* Inlining hooks same as the C front end. */
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \ #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
......
// { dg-do compile }
// { dg-options "-Wunused -O3" }
static const int i = 0;
static void f() { } /* { dg-warning "defined but not used" } */
static inline void g() { }
/* { dg-do compile } */
/* { dg-options "-Wunused -O3" } */
static const int i = 0; /* { dg-warning "defined but not used" } */
static void f() { } /* { dg-warning "defined but not used" } */
static inline void g() { }
...@@ -1945,22 +1945,19 @@ check_global_declarations (vec, len) ...@@ -1945,22 +1945,19 @@ check_global_declarations (vec, len)
assemble_external (decl); assemble_external (decl);
} }
/* Warn about static fns or vars defined but not used, /* Warn about static fns or vars defined but not used. */
but not about inline functions or static consts if (((warn_unused_function && TREE_CODE (decl) == FUNCTION_DECL)
since defining those in header files is normal practice. */ || (warn_unused_variable && TREE_CODE (decl) == VAR_DECL))
if (((warn_unused_function && ! TREE_USED (decl)
&& TREE_CODE (decl) == FUNCTION_DECL && ! DECL_INLINE (decl)) /* The TREE_USED bit for file-scope decls is kept in the identifier,
|| (warn_unused_variable to handle multiple external decls in different scopes. */
&& TREE_CODE (decl) == VAR_DECL && ! TREE_READONLY (decl))) && ! TREE_USED (DECL_NAME (decl))
&& ! DECL_IN_SYSTEM_HEADER (decl)
&& ! DECL_EXTERNAL (decl) && ! DECL_EXTERNAL (decl)
&& ! TREE_PUBLIC (decl) && ! TREE_PUBLIC (decl)
&& ! TREE_USED (decl) /* Global register variables must be declared to reserve them. */
&& (TREE_CODE (decl) == FUNCTION_DECL || ! DECL_REGISTER (decl)) && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
/* The TREE_USED bit for file-scope decls /* Otherwise, ask the language. */
is kept in the identifier, to handle multiple && (*lang_hooks.decls.warn_unused_global) (decl))
external decls in different scopes. */
&& ! TREE_USED (DECL_NAME (decl)))
warning_with_decl (decl, "`%s' defined but not used"); warning_with_decl (decl, "`%s' defined but not used");
timevar_push (TV_SYMOUT); timevar_push (TV_SYMOUT);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment