Index: c-common.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-common.c,v retrieving revision 1.649 diff -u -p -r1.649 c-common.c --- c-common.c 9 Aug 2005 12:05:09 -0000 1.649 +++ c-common.c 22 Aug 2005 16:15:20 -0000 @@ -3804,7 +3804,32 @@ c_do_switch_warnings (splay_tree cases, { splay_tree_node node = splay_tree_lookup (cases, (splay_tree_key) TREE_VALUE (chain)); - + if (!node) + { + tree low_value = TREE_VALUE (chain); + splay_tree_node low_bound; + splay_tree_node high_bound; + /* Even though there wasn't an exact match, there might be a + case range which includes the enumator's value. */ + low_bound = splay_tree_predecessor (cases, + (splay_tree_key) low_value); + high_bound = splay_tree_successor (cases, + (splay_tree_key) low_value); + + /* It is smaller than the LOW_VALUE, so there is no need to check + unless the LOW_BOUND is in fact itself a case range. */ + if (low_bound + && CASE_HIGH ((tree) low_bound->value) + && tree_int_cst_compare (CASE_HIGH ((tree) low_bound->value), + low_value) >= 0) + node = low_bound; + /* The low end of that range is bigger than the current value. */ + else if (high_bound + && (tree_int_cst_compare ((tree) high_bound->key, + low_value) + <= 0)) + node = high_bound; + } if (node) { /* Mark the CASE_LOW part of the case entry as seen, so Index: testsuite/gcc.dg/switch-warn-3.c =================================================================== RCS file: testsuite/gcc.dg/switch-warn-3.c diff -N testsuite/gcc.dg/switch-warn-3.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gcc.dg/switch-warn-3.c 22 Aug 2005 16:15:28 -0000 @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-Wswitch-enum" } */ + +enum a { a0, a1, a2, a3 }; + +int error(enum a aa) +{ + switch ( aa ) + { + case a0 ... a3: + return 1; + } + return 0; +}