From 7dc6165912fffbcf022950cd1e58b3aa519a2625 Mon Sep 17 00:00:00 2001 From: cagney Date: Tue, 26 Mar 2002 15:36:37 +0000 Subject: [PATCH] Add -Wswitch-enum. Document. Fix PR c/5044. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51386 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 +++++++ gcc/doc/invoke.texi | 11 +++++-- gcc/f/ChangeLog | 5 +++ gcc/f/invoke.texi | 3 ++ gcc/flags.h | 5 +++ gcc/stmt.c | 8 ++--- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/Wswitch-enum.c | 63 +++++++++++++++++++++++++++++++++++++ gcc/toplev.c | 7 +++++ 9 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wswitch-enum.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a64e93..3af3e3b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2002-03-26 Andrew Cagney + + * doc/invoke.texi (Option Summary): Mention -Wswitch-enum. + (Warning Options): Document -Wswitch-enum. + * toplev.c (W_options): Add -Wswitch-enum. Update comment on + -Wswitch. + (warn_switch_enum): Define variables. + * flags.h (warn_switch_enum): Declare variables. + * stmt.c (expand_end_case_type): When warn_switch_enum / + -Wswitch-enum, perform switch checks. + Fix PR c/5044. + 2002-03-26 Richard Earnshaw * arm.md (reload_mulsi3, reload_mulsi_compare0, reload_muladdsi) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 321cda2..8f51f29 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -228,8 +228,8 @@ in the following sections. -Wno-import -Wpacked -Wpadded @gol -Wparentheses -Wpointer-arith -Wredundant-decls @gol -Wreturn-type -Wsequence-point -Wshadow @gol --Wsign-compare -Wswitch -Wswitch-default -Wsystem-headers @gol --Wtrigraphs -Wundef -Wuninitialized @gol +-Wsign-compare -Wswitch -Wswitch-default -Wswitch-enum @gol +-Wsystem-headers -Wtrigraphs -Wundef -Wuninitialized @gol -Wunknown-pragmas -Wunreachable-code @gol -Wunused -Wunused-function -Wunused-label -Wunused-parameter @gol -Wunused-value -Wunused-variable -Wwrite-strings} @@ -2039,6 +2039,13 @@ provoke warnings when this option is used. Warn whenever a @code{switch} statement does not have a @code{default} case. +@item -Wswitch-enum +@opindex Wswitch-enum +Warn whenever a @code{switch} statement has an index of enumeral type +and lacks a @code{case} for one or more of the named codes of that +enumeration. @code{case} labels outside the enumeration range also +provoke warnings when this option is used. + @item -Wtrigraphs @opindex Wtrigraphs Warn if any trigraphs are encountered that might change the meaning of diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog index da22c00..68c8ade 100644 --- a/gcc/f/ChangeLog +++ b/gcc/f/ChangeLog @@ -1,3 +1,8 @@ +Tue Mar 26 10:30:05 2002 Andrew Cagney + + * invoke.texi (Warning Options): Mention -Wswitch-enum. + Fix PR c/5044. + Tue Mar 26 07:30:51 2002 Neil Booth * com.c (LANG_HOOKS_MARK_TREE): Redefine. diff --git a/gcc/f/invoke.texi b/gcc/f/invoke.texi index 025fb9e..479ff2f 100644 --- a/gcc/f/invoke.texi +++ b/gcc/f/invoke.texi @@ -1359,6 +1359,9 @@ Some of these have no effect when compiling programs written in Fortran: @cindex -Wswitch-default option @cindex options, -Wswitch-default @item -Wswitch-default +@cindex -Wswitch-enum option +@cindex options, -Wswitch-enum +@item -Wswitch-enum @cindex -Wtraditional option @cindex options, -Wtraditional @item -Wtraditional diff --git a/gcc/flags.h b/gcc/flags.h index ee9753a..b9fca23 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -135,6 +135,11 @@ extern int warn_switch; extern int warn_switch_default; +/* Warn if a switch on an enum fails to have a case for every enum + value (regardless of the presence or otherwise of a default case). */ + +extern int warn_switch_enum; + /* Nonzero means warn about function definitions that default the return type or that use a null return and have a return-type other than void. */ diff --git a/gcc/stmt.c b/gcc/stmt.c index 5823f8b..fcda52d 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -5280,10 +5280,10 @@ expand_end_case_type (orig_index, orig_type) { /* If the switch expression was an enumerated type, check that exactly all enumeration literals are covered by the cases. - The check is made -Wswitch was specified and there is no - default case. */ - - if ((warn_switch && !thiscase->data.case_stmt.default_label) + The check is made when -Wswitch was specified and there is no + default case, or when -Wswitch-enum was specified. */ + if (((warn_switch && !thiscase->data.case_stmt.default_label) + || warn_switch_enum) && TREE_CODE (orig_type) == ENUMERAL_TYPE && TREE_CODE (index_expr) != INTEGER_CST) check_for_full_enumeration_handling (orig_type); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7299c6d..684ee9d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2002-03-26 Andrew Cagney + + * gcc.dg/Wswitch-enum.c: New test. + Fix PR c/5044. + 2002-03-26 Richard Henderson * gcc.c-torture/execute/20020307-2.c (main): Pass a variable sized diff --git a/gcc/testsuite/gcc.dg/Wswitch-enum.c b/gcc/testsuite/gcc.dg/Wswitch-enum.c new file mode 100644 index 0000000..00e4b55 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wswitch-enum.c @@ -0,0 +1,63 @@ +/* PR c/5044 */ +/* { dg-do compile } */ +/* { dg-options "-Wswitch-enum" } */ + +enum e { e1, e2 }; + +int +foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el, + enum e em, enum e en, enum e eo, enum e ep) +{ + switch (i) + { + case 1: return 1; + case 2: return 2; + } + switch (j) + { + case 3: return 4; + case 4: return 3; + default: break; + } + switch (ei) + { /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" } */ + } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" { target *-*-* } 23 } */ + switch (ej) + { /* { dg-warning "enumeration value `e1' not handled in switch" "enum e1" { target *-*-* } 28 } */ + default: break; + } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */ + switch (ek) + { + case e1: return 1; + } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */ + switch (el) + { + case e1: return 1; + default: break; + } /* { dg-warning "enumeration value `e2' not handled in switch" "enum e2" } */ + switch (em) + { + case e1: return 1; + case e2: return 2; + } + switch (en) + { + case e1: return 1; + case e2: return 2; + default: break; + } + switch (eo) + { + case e1: return 1; + case e2: return 2; + case 3: return 3; + } /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */ + switch (ep) + { + case e1: return 1; + case e2: return 2; + case 3: return 3; + default: break; + } /* { dg-warning "case value `3' not in enumerated type `e'" "excess 3" } */ + return 0; +} diff --git a/gcc/toplev.c b/gcc/toplev.c index 8c7517e..7268b5a 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1401,6 +1401,11 @@ int warn_switch; int warn_switch_default; +/* Warn if a switch on an enum fails to have a case for every enum + value (regardless of the presence or otherwise of a default case). */ + +int warn_switch_enum; + /* Nonzero means warn about function definitions that default the return type or that use a null return and have a return-type other than void. */ @@ -1473,6 +1478,8 @@ static const lang_independent_options W_options[] = N_("Warn about enumerated switches, with no default, missing a case") }, {"switch-default", &warn_switch_default, 1, N_("Warn about enumerated switches missing a default case") }, + {"switch-enum", &warn_switch_enum, 1, + N_("Warn about all enumerated switches missing a specific case") }, {"aggregate-return", &warn_aggregate_return, 1, N_("Warn about returning structures, unions or arrays") }, {"cast-align", &warn_cast_align, 1, -- 2.7.4