aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-03-09 20:34:10 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2009-03-09 20:34:10 +0100
commit8c30a5105f004e885ae81edbf9c1607547bd4ace (patch)
treead67b3505d09efcb012641d1816d48aa0e3e2fdf /gcc
parent9a9ba8d9b1292607bc97da712976937c4d81909d (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/decl.c3
-rw-r--r--gcc/cp/semantics.c14
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/opt/switch2.C2
-rw-r--r--gcc/testsuite/g++.dg/other/switch3.C25
-rw-r--r--gcc/testsuite/g++.dg/warn/Wswitch-1.C6
-rw-r--r--gcc/testsuite/g++.dg/warn/switch1.C15
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;
+ }
+}