aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-05-05 23:09:16 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2009-05-05 23:09:16 +0200
commit32f579f6ebde02d94ac8fbd0379b1d0207dd9ac5 (patch)
tree04135baa9f723c92400dc6a7d81d23fdc587597b
parent6e57a01df44693719cdaa9c552bfc3d729f5c095 (diff)
downloadgcc-32f579f6ebde02d94ac8fbd0379b1d0207dd9ac5.zip
gcc-32f579f6ebde02d94ac8fbd0379b1d0207dd9ac5.tar.gz
gcc-32f579f6ebde02d94ac8fbd0379b1d0207dd9ac5.tar.bz2
re PR middle-end/39666 (spurious warning with ranged-switch statements)
PR middle-end/39666 * gimplify.c (gimplify_switch_expr): If case labels cover the whole range of the type, but default label is missing, add it with one of the existing labels instead of adding a new label for it. * gcc.dg/pr39666-1.c: New test. * gcc.dg/pr39666-2.c: Likewise. * g++.dg/warn/Wuninitialized-4.C: Likewise. * g++.dg/warn/Wuninitialized-5.C: Likewise. * gfortran.dg/pr39666-1.f90: Likewise. * gfortran.dg/pr39666-2.f90: Likewise. From-SVN: r147136
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/gimplify.c61
-rw-r--r--gcc/testsuite/ChangeLog10
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuninitialized-4.C22
-rw-r--r--gcc/testsuite/g++.dg/warn/Wuninitialized-5.C22
-rw-r--r--gcc/testsuite/gcc.dg/pr39666-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/pr39666-2.c22
-rw-r--r--gcc/testsuite/gfortran.dg/pr39666-1.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/pr39666-2.f9014
9 files changed, 183 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a4271b0..9ab24db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -12,6 +12,11 @@
(gen_variable_die): Likewise. Check TREE_PRIVATE/TREE_PROTECTED
unconditionally.
+ PR middle-end/39666
+ * gimplify.c (gimplify_switch_expr): If case labels cover the whole
+ range of the type, but default label is missing, add it with one
+ of the existing labels instead of adding a new label for it.
+
2009-05-05 Joseph Myers <joseph@codesourcery.com>
* dwarf.h: Remove.
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 0909d31..0c33dab 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1604,20 +1604,63 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
}
len = i;
+ if (!VEC_empty (tree, labels))
+ sort_case_labels (labels);
+
if (!default_case)
{
- gimple new_default;
+ tree type = TREE_TYPE (switch_expr);
/* If the switch has no default label, add one, so that we jump
- around the switch body. */
- default_case = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE,
- NULL_TREE, create_artificial_label ());
- new_default = gimple_build_label (CASE_LABEL (default_case));
- gimplify_seq_add_stmt (&switch_body_seq, new_default);
- }
+ around the switch body. If the labels already cover the whole
+ range of type, add the default label pointing to one of the
+ existing labels. */
+ if (type == void_type_node)
+ type = TREE_TYPE (SWITCH_COND (switch_expr));
+ if (len
+ && INTEGRAL_TYPE_P (type)
+ && TYPE_MIN_VALUE (type)
+ && TYPE_MAX_VALUE (type)
+ && tree_int_cst_equal (CASE_LOW (VEC_index (tree, labels, 0)),
+ TYPE_MIN_VALUE (type)))
+ {
+ tree low, high = CASE_HIGH (VEC_index (tree, labels, len - 1));
+ if (!high)
+ high = CASE_LOW (VEC_index (tree, labels, len - 1));
+ if (tree_int_cst_equal (high, TYPE_MAX_VALUE (type)))
+ {
+ for (i = 1; i < len; i++)
+ {
+ high = CASE_LOW (VEC_index (tree, labels, i));
+ low = CASE_HIGH (VEC_index (tree, labels, i - 1));
+ if (!low)
+ low = CASE_LOW (VEC_index (tree, labels, i - 1));
+ if ((TREE_INT_CST_LOW (low) + 1
+ != TREE_INT_CST_LOW (high))
+ || (TREE_INT_CST_HIGH (low)
+ + (TREE_INT_CST_LOW (high) == 0)
+ != TREE_INT_CST_HIGH (high)))
+ break;
+ }
+ if (i == len)
+ default_case = build3 (CASE_LABEL_EXPR, void_type_node,
+ NULL_TREE, NULL_TREE,
+ CASE_LABEL (VEC_index (tree,
+ labels, 0)));
+ }
+ }
- if (!VEC_empty (tree, labels))
- sort_case_labels (labels);
+ if (!default_case)
+ {
+ gimple new_default;
+
+ default_case = build3 (CASE_LABEL_EXPR, void_type_node,
+ NULL_TREE, NULL_TREE,
+ create_artificial_label ());
+ new_default = gimple_build_label (CASE_LABEL (default_case));
+ gimplify_seq_add_stmt (&switch_body_seq, new_default);
+ }
+ }
gimple_switch = gimple_build_switch_vec (SWITCH_COND (switch_expr),
default_case, labels);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 376e468..e5a6e5e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2009-05-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/39666
+ * gcc.dg/pr39666-1.c: New test.
+ * gcc.dg/pr39666-2.c: Likewise.
+ * g++.dg/warn/Wuninitialized-4.C: Likewise.
+ * g++.dg/warn/Wuninitialized-5.C: Likewise.
+ * gfortran.dg/pr39666-1.f90: Likewise.
+ * gfortran.dg/pr39666-2.f90: Likewise.
+
2009-05-05 Adam Nemet <anemet@caviumnetworks.com>
* gcc.target/mips/mips.exp: Add -mtune= to mips_option_groups.
diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-4.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-4.C
new file mode 100644
index 0000000..3d2543f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-4.C
@@ -0,0 +1,22 @@
+// PR middle-end/39666
+// { dg-do compile }
+// { dg-options "-O2 -Wuninitialized" }
+
+int
+foo (int i)
+{
+ int j;
+ switch (i)
+ {
+ case -__INT_MAX__ - 1 ... -1:
+ j = 6;
+ break;
+ case 0:
+ j = 5;
+ break;
+ case 1 ... __INT_MAX__:
+ j = 4;
+ break;
+ }
+ return j;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-5.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-5.C
new file mode 100644
index 0000000..26add34
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-5.C
@@ -0,0 +1,22 @@
+// PR middle-end/39666
+// { dg-do compile }
+// { dg-options "-O2 -Wuninitialized" }
+
+int
+foo (int i)
+{
+ int j; // { dg-warning "may be used uninitialized" }
+ switch (i)
+ {
+ case -__INT_MAX__ - 1 ... -1:
+ j = 6;
+ break;
+ case 0:
+ j = 5;
+ break;
+ case 2 ... __INT_MAX__:
+ j = 4;
+ break;
+ }
+ return j;
+}
diff --git a/gcc/testsuite/gcc.dg/pr39666-1.c b/gcc/testsuite/gcc.dg/pr39666-1.c
new file mode 100644
index 0000000..f1ba499
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr39666-1.c
@@ -0,0 +1,22 @@
+/* PR middle-end/39666 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized" } */
+
+int
+foo (int i)
+{
+ int j;
+ switch (i)
+ {
+ case -__INT_MAX__ - 1 ... -1:
+ j = 6;
+ break;
+ case 0:
+ j = 5;
+ break;
+ case 1 ... __INT_MAX__:
+ j = 4;
+ break;
+ }
+ return j;
+}
diff --git a/gcc/testsuite/gcc.dg/pr39666-2.c b/gcc/testsuite/gcc.dg/pr39666-2.c
new file mode 100644
index 0000000..e4ef1d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr39666-2.c
@@ -0,0 +1,22 @@
+/* PR middle-end/39666 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wuninitialized" } */
+
+int
+foo (int i)
+{
+ int j; /* { dg-warning "may be used uninitialized" } */
+ switch (i)
+ {
+ case -__INT_MAX__ - 1 ... -1:
+ j = 6;
+ break;
+ case 0:
+ j = 5;
+ break;
+ case 2 ... __INT_MAX__:
+ j = 4;
+ break;
+ }
+ return j;
+}
diff --git a/gcc/testsuite/gfortran.dg/pr39666-1.f90 b/gcc/testsuite/gfortran.dg/pr39666-1.f90
new file mode 100644
index 0000000..31840ec
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr39666-1.f90
@@ -0,0 +1,14 @@
+! PR middle-end/39666
+! { dg-do compile }
+! { dg-options "-O2 -Wuninitialized" }
+
+FUNCTION f(n)
+ INTEGER, INTENT(in) :: n
+ REAL :: f
+
+ SELECT CASE (n)
+ CASE (:-1); f = -1.0
+ CASE (0); f = 0.0
+ CASE (1:); f = 1.0
+ END SELECT
+END FUNCTION
diff --git a/gcc/testsuite/gfortran.dg/pr39666-2.f90 b/gcc/testsuite/gfortran.dg/pr39666-2.f90
new file mode 100644
index 0000000..720a716
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr39666-2.f90
@@ -0,0 +1,14 @@
+! PR middle-end/39666
+! { dg-do compile }
+! { dg-options "-O2 -Wuninitialized" }
+
+FUNCTION f(n) ! { dg-warning "may be used uninitialized" }
+ INTEGER, INTENT(in) :: n
+ REAL :: f
+
+ SELECT CASE (n)
+ CASE (:-1); f = -1.0
+ CASE (0); f = 0.0
+ CASE (2:); f = 1.0
+ END SELECT
+END FUNCTION