On 06/10/2015 12:02 PM, Marek Polacek wrote:
Linus's kind words here <https://lkml.org/lkml/2015/5/27/941> prodded
me to improving the -Wswitch-bool warning.  In particular, this patch
makes the warning not warn when the case values aren't outside bool
range.  But it will still warn about
Linus being Linus. While I agree with his points, the way he makes them isn't all that helpful.

Anyway...



   switch (boolean)
     {
     case false ... true: ...
     default: ...
     }

That of course means that the warning must be delayed to the point where
all the case labels have been parsed.  Then there are these annoying
differences between C and C++ (type of a comparison), which means some
splay trees fun.  Another problem stems from the fact that case labels
that are outside the range of the original type of the switch controlling
expression are dropped on the floor, so I had to add the OUTSIDE_RANGE_P
flag.  Case ranges are fun as well.
Ugh.


If this patch is approved, I'd like to backport it even to 5 branch after
some time so it's fixed in 5.2.
If it's OK with Jakub, it's fine with me.



There's also the possibility to add -Wswitch-bool=2 that would warn every
time the compiler sees a switch with a boolean controlling expr, i.e. do
what we're doing now.  But that would be something for trunk only.
No strong opinions on -Wswitch-bool=2.  Your call as a followup.


Thoughts?

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2015-06-10  Marek Polacek  <pola...@redhat.com>

        PR c/66322
        * c-common.c (check_case_bounds): Add bool * parameter.  Set
        OUTSIDE_RANGE_P.
        (c_add_case_label): Add bool * parameter.  Pass it down to
        check_case_bounds.
        (c_do_switch_warnings): Add bool parameters.  Implement -Wswitch-bool
        warning here.
        * c-common.h (c_add_case_label, c_do_switch_warnings): Update
        declarations.

        * c-typeck.c (struct c_switch): Add BOOL_COND_P and OUTSIDE_RANGE_P.
        (c_start_case): Set BOOL_COND_P and OUTSIDE_RANGE_P.  Don't warn
        about -Wswitch-bool here.
        (do_case): Update c_add_case_label call.
        (c_finish_case): Update c_do_switch_warnings call.

        * decl.c (struct cp_switch): Add OUTSIDE_RANGE_P.
        (push_switch): Set OUTSIDE_RANGE_P.
        (pop_switch): Update c_do_switch_warnings call.
        (finish_case_label): Update c_add_case_label call.
        * semantics.c (finish_switch_cond): Don't warn about -Wswitch-bool
        here.

        * function.c (stack_protect_epilogue): Remove a cast to int.
        * doc/invoke.texi: Update -Wswitch-bool description.

        * c-c++-common/pr60439.c: Add dg-prune-output and add switch cases.
        * c-c++-common/pr66322.c: New test.
        * g++.dg/eh/scope1.C: Remove dg-warning.
OK.
jeff

Reply via email to