Hello, This patch fixes a regression when folding a cast cond expression to a constant in case label.
The problem came from the removal of the lines in c-common.c:check_case_value /* ??? Can we ever get nops here for a valid case value? We shouldn't for C. */ STRIP_TYPE_NOPS (value); so the check for INTEGER_CST) now fails. The NOP is stripped after folding in 'c_fully_fold' and recreated in the fly even if no change of type is needed (the constant's type was converted to an integer, same than the case's type). Removal of this NOP_EXPR if !CAN_HAVE_LOCATION_P fixes the problem. looks safe from my testing, because the loc is inserted using 'protected_set_expr_location', whereas no loc for a constant case doesn't seem to introduce new problems with the debugging information. But in case I also added a few paranoid gcc_assert. The motivating failing case is added in the attached testsuite part, The test now compiles and generates the expected error with -pedantic or -pedantic-error Bootstrapped/Regression tested on x86 Thanks for any comment, and if OK to go for 4.6 and trunk Many thanks Christian
2010-02-15 Christian Bruel <christian.br...@st.com> * gcc.dg/case-const-1.c: Add cond expr label and cast case. * gcc.dg/case-const-2.c: Likewise. * gcc.dg/case-const-3.c: Likewise. Index: testsuite/gcc.dg/case-const-1.c =================================================================== --- testsuite/gcc.dg/case-const-1.c (revision 184254) +++ testsuite/gcc.dg/case-const-1.c (working copy) @@ -4,6 +4,8 @@ /* { dg-options "" } */ extern int i; +extern unsigned int u; + void f (int c) { @@ -13,3 +15,13 @@ ; } } + +void +b (int c) +{ + switch (c) + { + case (int) (2 | ((4 < 8) ? 8 : u)): + ; + } +} Index: testsuite/gcc.dg/case-const-2.c =================================================================== --- testsuite/gcc.dg/case-const-2.c (revision 184254) +++ testsuite/gcc.dg/case-const-2.c (working copy) @@ -4,6 +4,8 @@ /* { dg-options "-pedantic" } */ extern int i; +extern unsigned int u; + void f (int c) { @@ -13,3 +15,14 @@ ; } } + +void +b (int c) +{ + switch (c) + { + case (int) (2 | ((4 < 8) ? 8 : u)): /* { dg-warning "case label is not an integer constant expression" } */ + ; + } +} + Index: testsuite/gcc.dg/case-const-3.c =================================================================== --- testsuite/gcc.dg/case-const-3.c (revision 184254) +++ testsuite/gcc.dg/case-const-3.c (working copy) @@ -4,6 +4,8 @@ /* { dg-options "-pedantic-errors" } */ extern int i; +extern unsigned int u; + void f (int c) { @@ -13,3 +15,13 @@ ; } } + +void +b (int c) +{ + switch (c) + { + case (int) (2 | ((4 < 8) ? 8 : u)): /* { dg-error "case label is not an integer constant expression" } */ + ; + } +}
2010-02-15 Christian Bruel <christian.br...@st.com> * gcc/c-common.c (c_fully_fold_internal): Don't create a new NOP expr. * gcc/fold-const.c (try_move_mult_to_index): assert CAN_HAVE_LOCATION_P. (fold_comparison): Likewise. * gcc/tree.c (build_case_label): Likewise. Index: c-family/c-common.c =================================================================== --- c-family/c-common.c (revision 184254) +++ c-family/c-common.c (working copy) @@ -1435,12 +1435,9 @@ have been done by this point, so remove them again. */ nowarning |= TREE_NO_WARNING (ret); STRIP_TYPE_NOPS (ret); - if (nowarning && !TREE_NO_WARNING (ret)) - { - if (!CAN_HAVE_LOCATION_P (ret)) - ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret); - TREE_NO_WARNING (ret) = 1; - } + if (nowarning) + TREE_NO_WARNING (ret) = 1; + if (ret != expr) protected_set_expr_location (ret, loc); return ret; Index: tree.c =================================================================== --- tree.c (revision 184254) +++ tree.c (working copy) @@ -1678,6 +1678,7 @@ tree t = make_node (CASE_LABEL_EXPR); TREE_TYPE (t) = void_type_node; + gcc_assert (CAN_HAVE_LOCATION_P (t)); SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (label_decl)); CASE_LOW (t) = low_value; Index: fold-const.c =================================================================== --- fold-const.c (revision 184254) +++ fold-const.c (working copy) @@ -6972,6 +6972,7 @@ pref = TREE_OPERAND (addr, 0); ret = copy_node (pref); + gcc_assert (CAN_HAVE_LOCATION_P (ret)); SET_EXPR_LOCATION (ret, loc); pos = ret; @@ -9427,6 +9428,7 @@ if (save_p) { tem = save_expr (build2 (code, type, cval1, cval2)); + gcc_assert (CAN_HAVE_LOCATION_P (tem)); SET_EXPR_LOCATION (tem, loc); return tem; }