cppexp.c (parse_defined): Mark macro used.

* cppexp.c (parse_defined): Mark macro used.
	* cpphash.h (struct cpp_macro): New member "used".
	(_cpp_mark_macro_used, _cpp_warn_if_unused_macro): New.
	(struct cpp_reader): New member.
	* cppinit.c (cpp_finish_options): Set first_unused_line.
	(cpp_finish): Warn of unused macros if requested.
	(OPT_TABLE): New switches.
	(cpp_handle_option): Handle them.
	* cpplib.c (do_undef): Warn if macro unused.
	(do_ifdef, do_ifndef): Mark macro used.
	* cpplib.h (struct cpp_options): New member.
	* cppmacro.c (_cpp_warn_if_unused_macro): New.
	(enter_macro_context): Mark macro used.
	(_cpp_create_definition): Mark macro unused; warn if unused
	when redefined.
	* cpptrad.c (scan_out_logcial_line, push_replacement_text):
	Mark macros used.
	* doc/cppopts.texi: Update.
testsuite:
	* gcc.dg/cpp/trad/Wunused.c, gcc.dg/cpp/trad/Wunused.h,
	gcc.dg/cpp/Wunused.c, gcc.dg/cpp/Wunused.h: New tests.

From-SVN: r55692
This commit is contained in:
Neil Booth 2002-07-23 22:57:49 +00:00 committed by Neil Booth
parent b841421a28
commit a69cbaac60
14 changed files with 177 additions and 7 deletions

View File

@ -1,3 +1,24 @@
2002-07-24 Neil Booth <neil@daikokuya.co.uk>
* cppexp.c (parse_defined): Mark macro used.
* cpphash.h (struct cpp_macro): New member "used".
(_cpp_mark_macro_used, _cpp_warn_if_unused_macro): New.
(struct cpp_reader): New member.
* cppinit.c (cpp_finish_options): Set first_unused_line.
(cpp_finish): Warn of unused macros if requested.
(OPT_TABLE): New switches.
(cpp_handle_option): Handle them.
* cpplib.c (do_undef): Warn if macro unused.
(do_ifdef, do_ifndef): Mark macro used.
* cpplib.h (struct cpp_options): New member.
* cppmacro.c (_cpp_warn_if_unused_macro): New.
(enter_macro_context): Mark macro used.
(_cpp_create_definition): Mark macro unused; warn if unused
when redefined.
* cpptrad.c (scan_out_logcial_line, push_replacement_text):
Mark macros used.
* doc/cppopts.texi: Update.
2002-07-23 Neil Booth <neil@daikokuya.co.uk>
* dwarf2out.c (SECTION_ASM_OP,

View File

@ -501,6 +501,8 @@ parse_defined (pfile)
cpp_error (pfile, DL_WARNING,
"this use of \"defined\" may not be portable");
_cpp_mark_macro_used (node);
/* A possible controlling macro of the form #if !defined ().
_cpp_parse_expr checks there was no other junk on the line. */
pfile->mi_ind_cmacro = node;

View File

@ -98,8 +98,15 @@ struct cpp_macro
/* If macro defined in system header. */
unsigned int syshdr : 1;
/* Non-zero if it has been expanded or had its existence tested. */
unsigned int used : 1;
};
#define _cpp_mark_macro_used(NODE) do { \
if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \
(NODE)->value.macro->used = 1; } while (0)
/* A generic memory buffer, and operations on it. */
typedef struct _cpp_buff _cpp_buff;
struct _cpp_buff
@ -370,6 +377,9 @@ struct cpp_reader
for include files. (Altered as we get more of them.) */
unsigned int max_include_len;
/* Macros on or after this line are warned about if unused. */
unsigned int first_unused_line;
/* Date and time text. Calculated together if either is requested. */
const uchar *date;
const uchar *time;
@ -477,6 +487,8 @@ extern bool _cpp_arguments_ok PARAMS ((cpp_reader *, cpp_macro *,
unsigned int));
extern const uchar *_cpp_builtin_macro_text PARAMS ((cpp_reader *,
cpp_hashnode *));
int _cpp_warn_if_unused_macro PARAMS ((cpp_reader *, cpp_hashnode *,
void *));
/* In cpphash.c */
extern void _cpp_init_hashtable PARAMS ((cpp_reader *, hash_table *));
extern void _cpp_destroy_hashtable PARAMS ((cpp_reader *));

View File

@ -1009,6 +1009,8 @@ cpp_finish_options (pfile)
_cpp_maybe_push_include_file (pfile);
}
pfile->first_unused_line = pfile->line;
free_chain (CPP_OPTION (pfile, pending)->imacros_head);
free_chain (CPP_OPTION (pfile, pending)->directive_head);
}
@ -1081,6 +1083,10 @@ void
cpp_finish (pfile)
cpp_reader *pfile;
{
/* Warn about unused macros before popping the final buffer. */
if (CPP_OPTION (pfile, warn_unused_macros))
cpp_forall_identifiers (pfile, _cpp_warn_if_unused_macro, NULL);
/* cpplex.c leaves the final buffer on the stack. This it so that
it returns an unending stream of CPP_EOFs to the client. If we
popped the buffer, we'd dereference a NULL buffer pointer and
@ -1165,10 +1171,12 @@ new_pending_directive (pend, text, handler)
DEF_OPT("Wno-traditional", 0, OPT_Wno_traditional) \
DEF_OPT("Wno-trigraphs", 0, OPT_Wno_trigraphs) \
DEF_OPT("Wno-undef", 0, OPT_Wno_undef) \
DEF_OPT("Wno-unused-macros", 0, OPT_Wno_unused_macros) \
DEF_OPT("Wsystem-headers", 0, OPT_Wsystem_headers) \
DEF_OPT("Wtraditional", 0, OPT_Wtraditional) \
DEF_OPT("Wtrigraphs", 0, OPT_Wtrigraphs) \
DEF_OPT("Wundef", 0, OPT_Wundef) \
DEF_OPT("Wunused-macros", 0, OPT_Wunused_macros) \
DEF_OPT("d", no_arg, OPT_d) \
DEF_OPT("fno-operator-names", 0, OPT_fno_operator_names) \
DEF_OPT("fno-preprocessed", 0, OPT_fno_preprocessed) \
@ -1692,6 +1700,13 @@ cpp_handle_option (pfile, argc, argv)
CPP_OPTION (pfile, warn_comments) = 0;
break;
case OPT_Wunused_macros:
CPP_OPTION (pfile, warn_unused_macros) = 1;
break;
case OPT_Wno_unused_macros:
CPP_OPTION (pfile, warn_unused_macros) = 0;
break;
case OPT_Wundef:
CPP_OPTION (pfile, warn_undef) = 1;
break;

View File

@ -545,6 +545,9 @@ do_undef (pfile)
if (node->flags & NODE_WARN)
cpp_error (pfile, DL_WARNING, "undefining \"%s\"", NODE_NAME (node));
if (CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, node, NULL);
_cpp_free_definition (node);
}
check_eol (pfile);
@ -1331,10 +1334,11 @@ do_ifdef (pfile)
const cpp_hashnode *node = lex_macro_node (pfile);
if (node)
skip = node->type != NT_MACRO;
if (node)
check_eol (pfile);
{
skip = node->type != NT_MACRO;
_cpp_mark_macro_used (node);
check_eol (pfile);
}
}
push_conditional (pfile, skip, T_IFDEF, 0);
@ -1351,11 +1355,13 @@ do_ifndef (pfile)
if (! pfile->state.skipping)
{
node = lex_macro_node (pfile);
if (node)
skip = node->type == NT_MACRO;
if (node)
check_eol (pfile);
{
skip = node->type == NT_MACRO;
_cpp_mark_macro_used (node);
check_eol (pfile);
}
}
push_conditional (pfile, skip, T_IFNDEF, node);

View File

@ -361,6 +361,9 @@ struct cpp_options
/* Nonzero means warn if undefined identifiers are evaluated in an #if. */
unsigned char warn_undef;
/* Nonzero means warn of unused macros from the main file. */
unsigned char warn_unused_macros;
/* Nonzero for the 1999 C Standard, including corrigenda and amendments. */
unsigned char c99;

View File

@ -74,6 +74,29 @@ static void check_trad_stringification PARAMS ((cpp_reader *,
const cpp_macro *,
const cpp_string *));
/* Emits a warning if NODE is a macro defined in the main file that
has not been used. */
int
_cpp_warn_if_unused_macro (pfile, node, v)
cpp_reader *pfile;
cpp_hashnode *node;
void *v ATTRIBUTE_UNUSED;
{
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
{
cpp_macro *macro = node->value.macro;
if (!macro->used
/* Skip front-end built-ins and command line macros. */
&& macro->line >= pfile->first_unused_line
&& MAIN_FILE_P (lookup_line (&pfile->line_maps, macro->line)))
cpp_error_with_line (pfile, DL_WARNING, macro->line, 0,
"macro \"%s\" is not used", NODE_NAME (node));
}
return 1;
}
/* Allocates and returns a CPP_STRING token, containing TEXT of length
LEN, after null-terminating it. TEXT must be in permanent storage. */
static const cpp_token *
@ -728,6 +751,8 @@ enter_macro_context (pfile, node)
/* Disable the macro within its expansion. */
node->flags |= NODE_DISABLED;
macro->used = 1;
if (macro->paramc == 0)
push_token_context (pfile, node, macro->exp.tokens, macro->count);
@ -1488,6 +1513,7 @@ _cpp_create_definition (pfile, node)
macro->params = 0;
macro->paramc = 0;
macro->variadic = 0;
macro->used = 0;
macro->count = 0;
macro->fun_like = 0;
/* To suppress some diagnostics. */
@ -1523,6 +1549,9 @@ _cpp_create_definition (pfile, node)
if (node->type != NT_VOID)
{
if (CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, node, NULL);
if (warn_of_redefinition (pfile, node, macro))
{
cpp_error_with_line (pfile, DL_PEDWARN, pfile->directive_line, 0,

View File

@ -655,6 +655,7 @@ scan_out_logical_line (pfile, macro)
{
cpp_macro *m = fmacro.node->value.macro;
m->used = 1;
lex_state = ls_none;
save_argument (&fmacro, out - pfile->out.base);
@ -789,6 +790,7 @@ push_replacement_text (pfile, node)
else
{
cpp_macro *macro = node->value.macro;
macro->used = 1;
text = macro->exp.text;
len = macro->count;
}

View File

@ -110,6 +110,16 @@ Warn whenever an identifier which is not a macro is encountered in an
@samp{#if} directive, outside of @samp{defined}. Such identifiers are
replaced with zero.
@item -Wunused-macros
@opindex Wunused-macros
Warn about macros defined in the main file that are unused. A macro
is @dfn{used} if it is expanded or tested for existence at least once.
The preprocessor will also warn if the macro has not been used at the
time it is redefined or undefined.
Built-in macros, macros defined on the command line, and macros
defined in include files are not warned about.
@item -Wendif-labels
@opindex Wendif-labels
Warn whenever an @samp{#else} or an @samp{#endif} are followed by text.

View File

@ -1,3 +1,8 @@
2002-07-24 Neil Booth <neil@daikokuya.co.uk>
* gcc.dg/cpp/trad/Wunused.c, gcc.dg/cpp/trad/Wunused.h,
gcc.dg/cpp/Wunused.c, gcc.dg/cpp/Wunused.h: New tests.
2002-07-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.c-torture/execute/va-arg-15.x, va-arg-16.x, va-arg-17.x:

View File

@ -0,0 +1,32 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
/* { dg-options -Wunused-macros } */
/* Test everything related to -Wunused-macros.
Source: Neil Booth, 23 Jul 2002. */
#include "Wunused.h"
#define used1 /* { dg-bogus "used" } */
#define used2 /* { dg-bogus "used" } */
#define used3 /* { dg-bogus "used" } */
#define used4 used4 /* { dg-bogus "used" } */
#define unused5 /* { dg-warning "used" } */
#define unused6 /* { dg-warning "used" } */
#define unused7() /* { dg-warning "used" } */
#if defined used1
#endif
#ifdef used2
#endif
#ifndef used3
#endif
used4
unused7
#undef unused5
#define unused6
unused6

View File

@ -0,0 +1 @@
#define unused_but_ok

View File

@ -0,0 +1,31 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
/* { dg-options "-Wunused-macros -traditional-cpp" } */
/* Test everything related to -Wunused-macros.
Source: Neil Booth, 23 Jul 2002. */
#include "Wunused.h"
#define used1 /* { dg-bogus "used" } */
#define used2 /* { dg-bogus "used" } */
#define used3 /* { dg-bogus "used" } */
#define used4 something /* { dg-bogus "used" } */
#define unused5 /* { dg-warning "used" } */
#define unused6 /* { dg-warning "used" } */
#define unused7() /* { dg-warning "used" } */
#if defined used1
#endif
#ifdef used2
#endif
#ifndef used3
#endif
used4
#undef unused5
#define unused6
unused6

View File

@ -0,0 +1 @@
#define unused_but_ok