From 32f579f6ebde02d94ac8fbd0379b1d0207dd9ac5 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek <jakub@redhat.com> Date: Tue, 5 May 2009 23:09:16 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 ++ gcc/gimplify.c | 61 +++++++++++++++++--- gcc/testsuite/ChangeLog | 10 ++++ gcc/testsuite/g++.dg/warn/Wuninitialized-4.C | 22 +++++++ gcc/testsuite/g++.dg/warn/Wuninitialized-5.C | 22 +++++++ gcc/testsuite/gcc.dg/pr39666-1.c | 22 +++++++ gcc/testsuite/gcc.dg/pr39666-2.c | 22 +++++++ gcc/testsuite/gfortran.dg/pr39666-1.f90 | 14 +++++ gcc/testsuite/gfortran.dg/pr39666-2.f90 | 14 +++++ 9 files changed, 183 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wuninitialized-4.C create mode 100644 gcc/testsuite/g++.dg/warn/Wuninitialized-5.C create mode 100644 gcc/testsuite/gcc.dg/pr39666-1.c create mode 100644 gcc/testsuite/gcc.dg/pr39666-2.c create mode 100644 gcc/testsuite/gfortran.dg/pr39666-1.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr39666-2.f90 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4271b052ace..9ab24dbad9e0 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 0909d3173689..0c33dab479af 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 376e4682cbe8..e5a6e5e2549a 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 000000000000..3d2543fb1758 --- /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 000000000000..26add34945f2 --- /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 000000000000..f1ba499c3311 --- /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 000000000000..e4ef1d5d2b72 --- /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 000000000000..31840ec1df82 --- /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 000000000000..720a716ae315 --- /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 -- GitLab