re PR c++/20008 (internal compiler error: in expand_case, at stmt.c:2397)

gcc/ChangeLog:
PR c++/20008
* stmt.c (expand_case): Don't assume cleanup_tree_cfg will remove
cases that are out-of-range for the index type.
gcc/testsuite/ChangeLog:
PR c++/20008
* g++.dg/opt/switch4.C: New.

From-SVN: r95225
This commit is contained in:
Alexandre Oliva 2005-02-18 12:20:49 +00:00 committed by Alexandre Oliva
parent aeba6c285a
commit 2aabee29e1
4 changed files with 49 additions and 2 deletions

View file

@ -1,3 +1,9 @@
2005-02-18 Alexandre Oliva <aoliva@redhat.com>
PR c++/20008
* stmt.c (expand_case): Don't assume cleanup_tree_cfg will remove
cases that are out-of-range for the index type.
2005-02-18 James A. Morrison <phython@gcc.gnu.org>
* stmt.c (emit_case_bit_tests): Call fold_convert instead of convert.

View file

@ -2394,8 +2394,14 @@ expand_case (tree exp)
BITMAP_FREE (label_bitmap);
/* cleanup_tree_cfg removes all SWITCH_EXPR with a single
destination, such as one with a default case only. */
gcc_assert (count != 0);
destination, such as one with a default case only. However,
it doesn't remove cases that are out of range for the switch
type, so we may still get a zero here. */
if (count == 0)
{
emit_jump (default_label);
return;
}
/* Compute span of values. */
range = fold (build2 (MINUS_EXPR, index_type, maxval, minval));

View file

@ -1,3 +1,8 @@
2005-02-18 Alexandre Oliva <aoliva@redhat.com>
PR c++/20008
* g++.dg/opt/switch4.C: New.
2005-02-18 Jakub Jelinek <jakub@redhat.com>
PR c++/20023

View file

@ -0,0 +1,30 @@
// { dg-do compile }
// PR c++/20008
// We failed to compile this because CFG cleanup left the switch
// statement intact, whereas expand_case expected at least one
// in-range case to remain.
typedef enum _SECStatus {
SECWouldBlock = -2,
SECFailure = -1,
SECSuccess = 0
} SECStatus;
typedef enum {
SEC_ERROR_BAD_SIGNATURE = (-0x2000) + 10
} SECErrorCodes;
void g(void);
void f(SECStatus status)
{
switch( status )
{
case SEC_ERROR_BAD_SIGNATURE :
// This case can be optimized away in C++ (but apparently not in
// C), because the enum type is defined with a narrow range.
g();
break ;
}
}