Ping. On Thu, Aug 23, 2018 at 04:38:03PM -0400, Marek Polacek wrote: > The C++ standard says that [[fallthrough]]; at the end of a switch statement > is ill-formed: <http://eel.is/c++draft/dcl.attr.fallthrough> > > Currently we do check that the statement after a fallthrough statement is > a labeled statement, but we didn't warn if a fallthrough statement is at > the very end of a switch statement. This patch adds this warning. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2018-08-23 Marek Polacek <pola...@redhat.com> > > PR c++/87068 > * gimplify.c (expand_FALLTHROUGH_r): If IFN_FALLTHROUGH was found > at the end of a seq, save its location to walk_stmt_info. > (expand_FALLTHROUGH): Warn if IFN_FALLTHROUGH is at the end of > a switch. > > * c-c++-common/Wimplicit-fallthrough-37.c: New test. > > diff --git gcc/gimplify.c gcc/gimplify.c > index e35137aec2c..04c15016f18 100644 > --- gcc/gimplify.c > +++ gcc/gimplify.c > @@ -2231,7 +2231,7 @@ maybe_warn_implicit_fallthrough (gimple_seq seq) > > static tree > expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, > - struct walk_stmt_info *) > + struct walk_stmt_info *wi) > { > gimple *stmt = gsi_stmt (*gsi_p); > > @@ -2250,11 +2250,14 @@ expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, > bool *handled_ops_p, > if (gimple_call_internal_p (stmt, IFN_FALLTHROUGH)) > { > gsi_remove (gsi_p, true); > + location_t loc = gimple_location (stmt); > if (gsi_end_p (*gsi_p)) > - return integer_zero_node; > + { > + wi->info = &loc; > + return integer_zero_node; > + } > > bool found = false; > - location_t loc = gimple_location (stmt); > > gimple_stmt_iterator gsi2 = *gsi_p; > stmt = gsi_stmt (gsi2); > @@ -2317,6 +2320,14 @@ expand_FALLTHROUGH (gimple_seq *seq_p) > struct walk_stmt_info wi; > memset (&wi, 0, sizeof (wi)); > walk_gimple_seq_mod (seq_p, expand_FALLTHROUGH_r, NULL, &wi); > + if (wi.callback_result == integer_zero_node) > + { > + /* We've found [[fallthrough]]; at the end of a switch, which the C++ > + standard says is ill-formed; see [dcl.attr.fallthrough]. */ > + location_t *loc = static_cast<location_t *>(wi.info); > + warning_at (*loc, 0, "attribute %<fallthrough%> not preceding " > + "a case label or default label"); > + } > } > > > diff --git gcc/testsuite/c-c++-common/Wimplicit-fallthrough-37.c > gcc/testsuite/c-c++-common/Wimplicit-fallthrough-37.c > index e69de29bb2d..644003af47d 100644 > --- gcc/testsuite/c-c++-common/Wimplicit-fallthrough-37.c > +++ gcc/testsuite/c-c++-common/Wimplicit-fallthrough-37.c > @@ -0,0 +1,13 @@ > +/* PR c++/87068 */ > +/* { dg-do compile } */ > + > +void > +f (int n) > +{ > + switch (n) > + { > + case 4: > + ++n; > + __attribute__((fallthrough)); /* { dg-warning "not preceding" } */ > + } > +}
Marek