Commit 2aabee29 by Alexandre Oliva Committed by Alexandre Oliva

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
parent aeba6c28
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> 2005-02-18 James A. Morrison <phython@gcc.gnu.org>
* stmt.c (emit_case_bit_tests): Call fold_convert instead of convert. * stmt.c (emit_case_bit_tests): Call fold_convert instead of convert.
......
...@@ -2394,8 +2394,14 @@ expand_case (tree exp) ...@@ -2394,8 +2394,14 @@ expand_case (tree exp)
BITMAP_FREE (label_bitmap); BITMAP_FREE (label_bitmap);
/* cleanup_tree_cfg removes all SWITCH_EXPR with a single /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
destination, such as one with a default case only. */ destination, such as one with a default case only. However,
gcc_assert (count != 0); 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. */ /* Compute span of values. */
range = fold (build2 (MINUS_EXPR, index_type, maxval, minval)); range = fold (build2 (MINUS_EXPR, index_type, maxval, minval));
......
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> 2005-02-18 Jakub Jelinek <jakub@redhat.com>
PR c++/20023 PR c++/20023
......
// { 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 ;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment