diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-03-09 20:34:10 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2009-03-09 20:34:10 +0100 |
commit | 8c30a5105f004e885ae81edbf9c1607547bd4ace (patch) | |
tree | ad67b3505d09efcb012641d1816d48aa0e3e2fdf /gcc | |
parent | 9a9ba8d9b1292607bc97da712976937c4d81909d (diff) | |
download | gcc-8c30a5105f004e885ae81edbf9c1607547bd4ace.zip gcc-8c30a5105f004e885ae81edbf9c1607547bd4ace.tar.gz gcc-8c30a5105f004e885ae81edbf9c1607547bd4ace.tar.bz2 |
re PR c++/39371 (Incorrectly rejects switch((unsigned int)boolvar))
PR c++/39371
* semantics.c (finish_switch_cond): Don't call get_unwidened.
* decl.c (finish_case_label): Pass SWITCH_STMT_TYPE as 3rd argument
instead of TREE_TYPE (cond).
* g++.dg/opt/switch2.C: Add -w to dg-options.
* g++.dg/warn/Wswitch-1.C: Adjust expected warnings.
* g++.dg/warn/switch1.C: New test.
* g++.dg/other/switch3.C: New test.
From-SVN: r144732
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 3 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/switch2.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/switch3.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wswitch-1.C | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/switch1.C | 15 |
8 files changed, 59 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c4b151b..e4161c5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2009-03-09 Jakub Jelinek <jakub@redhat.com> + + PR c++/39371 + * semantics.c (finish_switch_cond): Don't call get_unwidened. + * decl.c (finish_case_label): Pass SWITCH_STMT_TYPE as 3rd argument + instead of TREE_TYPE (cond). + 2009-03-08 H.J. Lu <hongjiu.lu@intel.com> PR c++/39060 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4ed3425..03e65d0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2806,7 +2806,8 @@ finish_case_label (tree low_value, tree high_value) if (!check_switch_goto (switch_stack->level)) return error_mark_node; - r = c_add_case_label (switch_stack->cases, cond, TREE_TYPE (cond), + r = c_add_case_label (switch_stack->cases, cond, + SWITCH_STMT_TYPE (switch_stack->switch_stmt), low_value, high_value); /* After labels, make any new cleanups in the function go into their diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 5f01a83..eb5d25a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -945,8 +945,6 @@ finish_switch_cond (tree cond, tree switch_stmt) tree orig_type = NULL; if (!processing_template_decl) { - tree index; - /* Convert the condition to an integer or enumeration type. */ cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true); if (cond == NULL_TREE) @@ -963,18 +961,6 @@ finish_switch_cond (tree cond, tree switch_stmt) cond = perform_integral_promotions (cond); cond = maybe_cleanup_point_expr (cond); } - - if (cond != error_mark_node) - { - index = get_unwidened (cond, NULL_TREE); - /* We can't strip a conversion from a signed type to an unsigned, - because if we did, int_fits_type_p would do the wrong thing - when checking case values for being in range, - and it's too hard to do the right thing. */ - if (TYPE_UNSIGNED (TREE_TYPE (cond)) - == TYPE_UNSIGNED (TREE_TYPE (index))) - cond = index; - } } if (check_for_bare_parameter_packs (cond)) cond = error_mark_node; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5329e90..60f2f92 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2009-03-09 Jakub Jelinek <jakub@redhat.com> + PR c++/39371 + * g++.dg/opt/switch2.C: Add -w to dg-options. + * g++.dg/warn/Wswitch-1.C: Adjust expected warnings. + * g++.dg/warn/switch1.C: New test. + * g++.dg/other/switch3.C: New test. + PR tree-optimization/39394 * gcc.c-torture/compile/pr39394.c: New test. diff --git a/gcc/testsuite/g++.dg/opt/switch2.C b/gcc/testsuite/g++.dg/opt/switch2.C index 2590273..f7374cb 100644 --- a/gcc/testsuite/g++.dg/opt/switch2.C +++ b/gcc/testsuite/g++.dg/opt/switch2.C @@ -1,5 +1,5 @@ // { dg-do compile } -// { dg-options "-O2" } +// { dg-options "-O2 -w" } extern int foo (int); diff --git a/gcc/testsuite/g++.dg/other/switch3.C b/gcc/testsuite/g++.dg/other/switch3.C new file mode 100644 index 0000000..4f9b548 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/switch3.C @@ -0,0 +1,25 @@ +// PR c++/39371 +// { dg-do compile } + +void +foo (bool b) +{ + switch ((unsigned int) b) + { + case 1: + case 2: + break; + } +} + +void +bar (unsigned char b) +{ + switch ((unsigned int) b) + { + case 1: + case 257: + case 513: + break; + } +} diff --git a/gcc/testsuite/g++.dg/warn/Wswitch-1.C b/gcc/testsuite/g++.dg/warn/Wswitch-1.C index 9b05cd1..6a20944 100644 --- a/gcc/testsuite/g++.dg/warn/Wswitch-1.C +++ b/gcc/testsuite/g++.dg/warn/Wswitch-1.C @@ -50,14 +50,14 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el, { case e1: return 1; case e2: return 2; - case 3: return 3; /* { dg-warning "case value '3' not in enumerated type 'e'" "excess 3" } */ + case 3: return 3; /* { dg-warning "exceeds maximum value" } */ } switch (ep) { case e1: return 1; case e2: return 2; - case 3: return 3; + case 3: return 3; /* { dg-warning "exceeds maximum value" } */ default: break; - } /* Since there is a default, no warning about ``case 3'' */ + } return 0; } diff --git a/gcc/testsuite/g++.dg/warn/switch1.C b/gcc/testsuite/g++.dg/warn/switch1.C new file mode 100644 index 0000000..49c17e9 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/switch1.C @@ -0,0 +1,15 @@ +// { dg-do compile { target { int32plus } } } + +signed char sc; + +void +foo (void) +{ + switch (sc) + { + case 1: + case 2 * __SCHAR_MAX__ + 3: // { dg-warning "case label value exceeds maximum" } + case - 2 * __SCHAR_MAX__ - 1: // { dg-warning "case label value is less than minimum" } + break; + } +} |