-Wunused-macros
Neil Booth
neil@daikokuya.co.uk
Tue Jul 23 13:21:00 GMT 2002
As recently discussed, here's a patch to warn about macros
defined in the main file that are not used. Docs and full
tests included.
I've not added it to -Wunused, since -Wall implies -Wunused,
and I think this option may be too pricey to go there. If you
disagree, please shout.
Neil.
* 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.
============================================================
Index: gcc/cppexp.c
--- gcc/cppexp.c 20 Jul 2002 13:31:56 -0000 1.129
+++ gcc/cppexp.c 23 Jul 2002 19:53:22 -0000
@@ -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;
============================================================
Index: gcc/cpphash.h
--- gcc/cpphash.h 27 Jun 2002 06:01:58 -0000 1.167
+++ gcc/cpphash.h 23 Jul 2002 19:53:23 -0000
@@ -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 ((
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 *));
============================================================
Index: gcc/cppinit.c
--- gcc/cppinit.c 21 Jul 2002 21:59:02 -0000 1.245
+++ gcc/cppinit.c 23 Jul 2002 19:53:23 -0000
@@ -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, handl
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) \
@@ -1690,6 +1698,13 @@ cpp_handle_option (pfile, argc, argv)
case OPT_Wno_comment:
case OPT_Wno_comments:
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:
============================================================
Index: gcc/cpplib.c
--- gcc/cpplib.c 17 Jul 2002 21:31:27 -0000 1.319
+++ gcc/cpplib.c 23 Jul 2002 19:53:24 -0000
@@ -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);
============================================================
Index: gcc/cpplib.h
--- gcc/cpplib.h 20 Jul 2002 13:31:56 -0000 1.226
+++ gcc/cpplib.h 23 Jul 2002 19:53:24 -0000
@@ -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;
============================================================
Index: gcc/cppmacro.c
--- gcc/cppmacro.c 17 Jul 2002 17:27:13 -0000 1.117
+++ gcc/cppmacro.c 23 Jul 2002 19:53:25 -0000
@@ -74,6 +74,27 @@ static void check_trad_stringification P
const cpp_macro *,
const cpp_string *));
+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 +749,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 +1511,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 +1547,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,
============================================================
Index: gcc/cpptrad.c
--- gcc/cpptrad.c 17 Jul 2002 17:27:13 -0000 1.26
+++ gcc/cpptrad.c 23 Jul 2002 19:53:25 -0000
@@ -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;
}
============================================================
Index: gcc/doc/cppopts.texi
--- gcc/doc/cppopts.texi 2 Jul 2002 22:20:33 -0000 1.8
+++ gcc/doc/cppopts.texi 23 Jul 2002 19:53:25 -0000
@@ -110,6 +110,16 @@ Warn whenever an identifier which is not
@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.
============================================================
Index: gcc/testsuite/gcc.dg/cpp/Wunused.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/cpp/Wunused.c 23 Jul 2002 19:53:25 -0000
@@ -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
============================================================
Index: gcc/testsuite/gcc.dg/cpp/Wunused.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/cpp/Wunused.h 23 Jul 2002 19:53:25 -0000
@@ -0,0 +1 @@
+#define unused_but_ok
============================================================
Index: gcc/testsuite/gcc.dg/cpp/trad/Wunused.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/cpp/trad/Wunused.c 23 Jul 2002 19:53:25 -0000
@@ -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
============================================================
Index: gcc/testsuite/gcc.dg/cpp/trad/Wunused.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/gcc.dg/cpp/trad/Wunused.h 23 Jul 2002 19:53:25 -0000
@@ -0,0 +1 @@
+#define unused_but_ok
More information about the Gcc-patches
mailing list