224 lines
5.8 KiB
Diff
224 lines
5.8 KiB
Diff
2009-05-05 Jakub Jelinek <jakub@redhat.com>
|
|
|
|
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.
|
|
|
|
--- gcc/gimplify.c (revision 147135)
|
|
+++ gcc/gimplify.c (revision 147136)
|
|
@@ -1604,20 +1604,63 @@ gimplify_switch_expr (tree *expr_p, gimp
|
|
}
|
|
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);
|
|
--- gcc/testsuite/gcc.dg/pr39666-1.c (revision 0)
|
|
+++ gcc/testsuite/gcc.dg/pr39666-1.c (revision 147136)
|
|
@@ -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;
|
|
+}
|
|
--- gcc/testsuite/gcc.dg/pr39666-2.c (revision 0)
|
|
+++ gcc/testsuite/gcc.dg/pr39666-2.c (revision 147136)
|
|
@@ -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;
|
|
+}
|
|
--- gcc/testsuite/g++.dg/warn/Wuninitialized-5.C (revision 0)
|
|
+++ gcc/testsuite/g++.dg/warn/Wuninitialized-5.C (revision 147136)
|
|
@@ -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;
|
|
+}
|
|
--- gcc/testsuite/g++.dg/warn/Wuninitialized-4.C (revision 0)
|
|
+++ gcc/testsuite/g++.dg/warn/Wuninitialized-4.C (revision 147136)
|
|
@@ -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;
|
|
+}
|
|
--- gcc/testsuite/gfortran.dg/pr39666-1.f90 (revision 0)
|
|
+++ gcc/testsuite/gfortran.dg/pr39666-1.f90 (revision 147136)
|
|
@@ -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
|
|
--- gcc/testsuite/gfortran.dg/pr39666-2.f90 (revision 0)
|
|
+++ gcc/testsuite/gfortran.dg/pr39666-2.f90 (revision 147136)
|
|
@@ -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
|