Sorry, the last version had some problems. On Thu, Jun 20, 2019 at 4:26 PM Matthew Beliveau <mbeli...@redhat.com> wrote: > > Hopefully fixed! > > On Thu, Jun 20, 2019 at 2:42 PM Marek Polacek <pola...@redhat.com> wrote: > > > > On Thu, Jun 20, 2019 at 09:33:18AM -0400, Matthew Beliveau wrote: > > > Sorry for the last update, I guess I didn't notice the other changes, > > > oops! > > > > > > This should have all the changes. Let me know if anything went wrong! > > > > > > Thanks, > > > Matthew Beliveau > > > > > > On Tue, Jun 18, 2019 at 1:38 PM Marek Polacek <pola...@redhat.com> wrote: > > > > > > > > On Tue, Jun 18, 2019 at 01:17:10PM -0400, Matthew Beliveau wrote: > > > > > Hello, > > > > > > > > > > This patch should change the formatting, and move the test files into > > > > > the appropriate directory! > > > > > > > > It doesn't address my other comments, though, so please send a new > > > > version > > > > with that fixed. > > > > > > > > Marek > > > > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > > > > > 2019-06-20 Matthew Beliveau <mbeli...@redhat.com> > > > > > > PR c++/90875 - added -Wswitch-outside-range option > > > * doc/invoke.texi (Wswitch-outside-range): Document. > > > > > > * c-warn.c (c_do_switch_warnings): Implemented new > > > Wswitch-outside-range > > > warning option. > > > > > > * c.opt (Wswitch-outside-range): Added new option. > > > > > > * c-c++-common/Wswitch-outside-range-1.C: New test. > > > * c-c++-common/Wswitch-outside-range-2.C: New test. > > > * c-c++-common/Wswitch-outside-range-3.C: New test. > > > * c-c++-common/Wswitch-outside-range-4.C: New test. > > > > > > diff --git gcc/c-family/c-warn.c gcc/c-family/c-warn.c > > > index 5941c10cddb..743099c75ca 100644 > > > --- gcc/c-family/c-warn.c > > > +++ gcc/c-family/c-warn.c > > > @@ -1460,8 +1460,9 @@ c_do_switch_warnings (splay_tree cases, location_t > > > switch_location, > > > min_value) >= 0) > > > { > > > location_t loc = EXPR_LOCATION ((tree) node->value); > > > - warning_at (loc, 0, "lower value in case label range" > > > - " less than minimum value for type"); > > > + warning_at (loc, OPT_Wswitch_outside_range, > > > + "lower value in case label range less than minimum > > > value" > > > + " for type"); > > > CASE_LOW ((tree) node->value) = convert (TREE_TYPE (cond), > > > min_value); > > > node->key = (splay_tree_key) CASE_LOW ((tree) node->value); > > > @@ -1474,8 +1475,8 @@ c_do_switch_warnings (splay_tree cases, location_t > > > switch_location, > > > if (node == NULL || !node->key) > > > break; > > > location_t loc = EXPR_LOCATION ((tree) node->value); > > > - warning_at (loc, 0, "case label value is less than minimum " > > > - "value for type"); > > > + warning_at (loc, OPT_Wswitch_outside_range, "case label value > > > is" > > > + " less than minimum value for type"); > > > splay_tree_remove (cases, node->key); > > > } > > > while (1); > > > @@ -1491,8 +1492,8 @@ c_do_switch_warnings (splay_tree cases, location_t > > > switch_location, > > > max_value) > 0) > > > { > > > location_t loc = EXPR_LOCATION ((tree) node->value); > > > - warning_at (loc, 0, "upper value in case label range" > > > - " exceeds maximum value for type"); > > > + warning_at (loc, OPT_Wswitch_outside_range, "upper value in case" > > > + " label range exceeds maximum value for > > > type"); > > > CASE_HIGH ((tree) node->value) > > > = convert (TREE_TYPE (cond), max_value); > > > outside_range_p = true; > > > > The formatting is still wrong here... > > > > > @@ -1503,7 +1504,7 @@ c_do_switch_warnings (splay_tree cases, location_t > > > switch_location, > > > != NULL) > > > { > > > location_t loc = EXPR_LOCATION ((tree) node->value); > > > - warning_at (loc, 0, > > > + warning_at (loc, OPT_Wswitch_outside_range, > > > "case label value exceeds maximum value for type"); > > > splay_tree_remove (cases, node->key); > > > outside_range_p = true; > > > > ...but is correct here. So make the other cases above like this one. > > > > > diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi > > > index eaef4cd63d2..210535cb84a 100644 > > > --- gcc/doc/invoke.texi > > > +++ gcc/doc/invoke.texi > > > @@ -5390,6 +5390,13 @@ switch ((int) (a == 4)) > > > @end smallexample > > > This warning is enabled by default for C and C++ programs. > > > > > > +@item -Wswitch-outside-range > > > +@opindex Wswitch-outside-range > > > +@opindex Wno-switch-outside-range > > > +Warn whenever a @code{switch} state has a value that is outside of its > > > > s/state/case/ > > > > > +respective type range. This warning is enabled by default for > > > +C and C++ progarams. > > > > "programs" > > > > > diff --git gcc/testsuite/c-c++-common/Wswitch-outside-range-1.C > > > gcc/testsuite/c-c++-common/Wswitch-outside-range-1.C > > > new file mode 100644 > > > index 00000000000..29e56f3ba2d > > > --- /dev/null > > > +++ gcc/testsuite/c-c++-common/Wswitch-outside-range-1.C > > > @@ -0,0 +1,8 @@ > > > +// PR c++/90875 > > > + > > > +void f(char c) > > > +{ > > > + switch (c) > > > + case 300: // { dg-warning "case label value exceeds maximum value > > > for type" } > > > + case -300:; // { dg-warning "case label value is less than minimum > > > value for type" } > > > +} > > > diff --git gcc/testsuite/c-c++-common/Wswitch-outside-range-2.C > > > gcc/testsuite/c-c++-common/Wswitch-outside-range-2.C > > > new file mode 100644 > > > index 00000000000..20cc019b209 > > > --- /dev/null > > > +++ gcc/testsuite/c-c++-common/Wswitch-outside-range-2.C > > > @@ -0,0 +1,9 @@ > > > +// PR c++/90875 > > > +// { dg-options -Wno-switch-outside-range } > > > + > > > +void f(char c) > > > +{ > > > + switch (c) > > > + case 300: //{ dg-bogus "case label value is less than minimum value > > > for type" } > > > + case -300:; // { dg-bogus "case label value is less than minimum > > > value for type" } > > > +} > > > diff --git gcc/testsuite/c-c++-common/Wswitch-outside-range-3.C > > > gcc/testsuite/c-c++-common/Wswitch-outside-range-3.C > > > new file mode 100644 > > > index 00000000000..baf15561af0 > > > --- /dev/null > > > +++ gcc/testsuite/c-c++-common/Wswitch-outside-range-3.C > > > @@ -0,0 +1,9 @@ > > > +// PR c++/90875 > > > +// { dg-options -Wno-pedantic } > > > + > > > +void f(char c) > > > +{ > > > + switch (c) > > > + > > > + case -300 ... 300:; // { dg-warning "lower value in case label range > > > less than minimum value for type|upper value in case label range exceeds > > > maximum value for type" } > > > +} > > > diff --git gcc/testsuite/c-c++-common/Wswitch-outside-range-4.C > > > gcc/testsuite/c-c++-common/Wswitch-outside-range-4.C > > > new file mode 100644 > > > index 00000000000..d9bd756dc50 > > > --- /dev/null > > > +++ gcc/testsuite/c-c++-common/Wswitch-outside-range-4.C > > > @@ -0,0 +1,9 @@ > > > +// PR c++/90875 > > > +// { dg-options "-Wno-pedantic -Wno-switch-outside-range" } > > > + > > > +void f(char c) > > > +{ > > > + switch (c) > > > + > > > + case -300 ... 300:; // { dg-bogus "lower value in case label range > > > less than minimum value for type|upper value in case label range exceeds > > > maximum value for type" } > > > +} > > > > In c-c++-common/, the tests have to have file name suffix ".c", otherwise > > they will be disregarded; testsuite/g++.dg/dg.exp has > > > > # C/C++ common tests. > > g++-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/*.\[cSi\]]] \ > > "" "" > > > > Marek
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2019-06-20 Matthew Beliveau <mbeli...@redhat.com> PR c++/90875 - added -Wswitch-outside-range option * doc/invoke.texi (Wswitch-outside-range): Document. * c-warn.c (c_do_switch_warnings): Implemented new Wswitch-outside-range warning option. * c.opt (Wswitch-outside-range): Added new option. * c-c++-common/Wswitch-outside-range-1.c: New test. * c-c++-common/Wswitch-outside-range-2.c: New test. * c-c++-common/Wswitch-outside-range-3.c: New test. * c-c++-common/Wswitch-outside-range-4.c: New test. diff --git gcc/c-family/c-warn.c gcc/c-family/c-warn.c index 5941c10cddb..b5d09e761d7 100644 --- gcc/c-family/c-warn.c +++ gcc/c-family/c-warn.c @@ -1460,8 +1460,9 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location, min_value) >= 0) { location_t loc = EXPR_LOCATION ((tree) node->value); - warning_at (loc, 0, "lower value in case label range" - " less than minimum value for type"); + warning_at (loc, OPT_Wswitch_outside_range, + "lower value in case label range less than minimum" + " value for type"); CASE_LOW ((tree) node->value) = convert (TREE_TYPE (cond), min_value); node->key = (splay_tree_key) CASE_LOW ((tree) node->value); @@ -1474,8 +1475,8 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location, if (node == NULL || !node->key) break; location_t loc = EXPR_LOCATION ((tree) node->value); - warning_at (loc, 0, "case label value is less than minimum " - "value for type"); + warning_at (loc, OPT_Wswitch_outside_range, "case label value is" + " less than minimum value for type"); splay_tree_remove (cases, node->key); } while (1); @@ -1491,8 +1492,8 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location, max_value) > 0) { location_t loc = EXPR_LOCATION ((tree) node->value); - warning_at (loc, 0, "upper value in case label range" - " exceeds maximum value for type"); + warning_at (loc, OPT_Wswitch_outside_range, "upper value in case" + " label range exceeds maximum value for type"); CASE_HIGH ((tree) node->value) = convert (TREE_TYPE (cond), max_value); outside_range_p = true; @@ -1503,7 +1504,7 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location, != NULL) { location_t loc = EXPR_LOCATION ((tree) node->value); - warning_at (loc, 0, + warning_at (loc, OPT_Wswitch_outside_range, "case label value exceeds maximum value for type"); splay_tree_remove (cases, node->key); outside_range_p = true; diff --git gcc/c-family/c.opt gcc/c-family/c.opt index 572cf186262..a4cf3bd623d 100644 --- gcc/c-family/c.opt +++ gcc/c-family/c.opt @@ -819,6 +819,10 @@ Wswitch-bool C ObjC C++ ObjC++ Var(warn_switch_bool) Warning Init(1) Warn about switches with boolean controlling expression. +Wswitch-outside-range +C ObjC C++ ObjC++ Var(warn_switch_outside_range) Warning Init(1) +Warn about switch values that are outside of the switch's type range. + Wtemplates C++ ObjC++ Var(warn_templates) Warning Warn on primary template declaration. diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi index eaef4cd63d2..210535cb84a 100644 --- gcc/doc/invoke.texi +++ gcc/doc/invoke.texi @@ -5390,6 +5390,13 @@ switch ((int) (a == 4)) @end smallexample This warning is enabled by default for C and C++ programs. +@item -Wswitch-outside-range +@opindex Wswitch-outside-range +@opindex Wno-switch-outside-range +Warn whenever a @code{switch} state has a value that is outside of its +respective type range. This warning is enabled by default for +C and C++ progarams. + @item -Wswitch-unreachable @opindex Wswitch-unreachable @opindex Wno-switch-unreachable diff --git gcc/testsuite/c-c++-common/Wswitch-outside-range-1.c gcc/testsuite/c-c++-common/Wswitch-outside-range-1.c new file mode 100644 index 00000000000..29e56f3ba2d --- /dev/null +++ gcc/testsuite/c-c++-common/Wswitch-outside-range-1.c @@ -0,0 +1,8 @@ +// PR c++/90875 + +void f(char c) +{ + switch (c) + case 300: // { dg-warning "case label value exceeds maximum value for type" } + case -300:; // { dg-warning "case label value is less than minimum value for type" } +} diff --git gcc/testsuite/c-c++-common/Wswitch-outside-range-2.c gcc/testsuite/c-c++-common/Wswitch-outside-range-2.c new file mode 100644 index 00000000000..20cc019b209 --- /dev/null +++ gcc/testsuite/c-c++-common/Wswitch-outside-range-2.c @@ -0,0 +1,9 @@ +// PR c++/90875 +// { dg-options -Wno-switch-outside-range } + +void f(char c) +{ + switch (c) + case 300: //{ dg-bogus "case label value is less than minimum value for type" } + case -300:; // { dg-bogus "case label value is less than minimum value for type" } +} diff --git gcc/testsuite/c-c++-common/Wswitch-outside-range-3.c gcc/testsuite/c-c++-common/Wswitch-outside-range-3.c new file mode 100644 index 00000000000..baf15561af0 --- /dev/null +++ gcc/testsuite/c-c++-common/Wswitch-outside-range-3.c @@ -0,0 +1,9 @@ +// PR c++/90875 +// { dg-options -Wno-pedantic } + +void f(char c) +{ + switch (c) + + case -300 ... 300:; // { dg-warning "lower value in case label range less than minimum value for type|upper value in case label range exceeds maximum value for type" } +} diff --git gcc/testsuite/c-c++-common/Wswitch-outside-range-4.c gcc/testsuite/c-c++-common/Wswitch-outside-range-4.c new file mode 100644 index 00000000000..d9bd756dc50 --- /dev/null +++ gcc/testsuite/c-c++-common/Wswitch-outside-range-4.c @@ -0,0 +1,9 @@ +// PR c++/90875 +// { dg-options "-Wno-pedantic -Wno-switch-outside-range" } + +void f(char c) +{ + switch (c) + + case -300 ... 300:; // { dg-bogus "lower value in case label range less than minimum value for type|upper value in case label range exceeds maximum value for type" } +}