public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Implement -Wswitch-fallthrough
@ 2016-07-11 19:43 Marek Polacek
  2016-07-11 19:46 ` Implement -Wswitch-fallthrough: core Marek Polacek
                   ` (29 more replies)
  0 siblings, 30 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:43 UTC (permalink / raw)
  To: GCC Patches

The switch fallthrough has been widely considered a design defect in C, a
misfeature or, to use Marshall Cline's definition, evil.  The overwhelming
majority of the time you don't want to fall through to the next case, but it is
easy to forget to "break" at the end of the case, making this far too error
prone.  Yet GCC (and probably other compilers, too) doesn't have the ability to
warn in this case.  A feature request for such warning was opened back in 2002,
but it's mostly been untouched since.  But then the [[fallthrough]] attribute was
approved for C++17 [1], and that's what has got me to do all this.

The following series attempts to implement the fabled -Wswitch-fallthrough
warning.  The warning would be quite easy to implement were it not for control
statements, nested scopes, gotos, and such.  I took great pains to try to
handle all of that before I succeeded in getting all the pieces in place.  So
GCC ought to do the right thing for e.g.:

  switch (n)
    {
    case 1:
      if (n > 20)
	break;
      else if (n > 10)
	{
	  foo (9);
	  __builtin_fallthrough ();
	}
      else
	foo (8); // warn here
    case 2:;
    }

Since approximately 3% of fall throughs are desirable, I added a new builtin,
__builtin_fallthrough, that prevents the warning from occurring.  It can only
be used in a switch; the compiler will issue an error otherwise.  The new C++
attribute can then be implemented in terms of this builtin.  There was an idea
floating around about not warning for /* FALLTHRU */ etc. comments but I
rejected this after I'd spent time thinking about it: the preprocessor can't
know that we're in a switch statement so we might reject valid programs, the
"falls through" comments vary wildly, occur even in if-statements, etc.  The
warning doesn't warn when the block is empty, e.g. on case 1: case 2: ...  The
warning does, inevitably, trigger on Duff's devices.  Too bad.  I guess I'd
suggest using #pragma GCC warning then.  (I think Perl uses the "continue"
keyword for exactly this purpose -- an interesting idea...)

After I'd completed the warning, I kicked off a bootstrap so as to add various
gcc_fallthrough calls.  There were a good amount of them, as expected.  I also
grepped various FALLTHRU/Falls through/...fall thru.../... comments in config/
and added gcc_fallthroughs to make it easier for people.  Wherever I wasn't
sure that the gcc_fallthrough was appropriate, I added an 'XXX' comment.  This 
must not be relied upon as I don't know most of the compiler code.  The same
goes for relevant libraries where I introduced various gomp_fallthrough
macros conditional on __GNUC__ (I'd tried to use a configure check but then
decided I won't put up with all the vagaries of autoconf).

This patch is accompanied by more than 2000 lines of new tests to get the
warning covered though I'm sure folks will come up with other test cases
that I hadn't considered (hi Martin S. ;).

This warning is enabled by default for C/C++.  I was more inclined to put this
into -Wall, but our common.opt machinery doesn't seem to allow that (ugh!).
The clang version I have installed doesn't have this warning so I couldn't
compare my implementation with others.

I plan to plunge into the C++ [[fallthrough]] thingie after this core part is
dealt with.

Since the patch is too large, I split it into various parts, the core and then
various __builtin_fallthrough additions.

This patch has been tested on powerpc64le-unknown-linux-gnu, aarch64-linux-gnu,
x86_64-redhat-linux, and also on powerpc-ibm-aix7.1.0.0, though due to PR71816
I was unable to bootstrap.

Thanks,

[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0188r0.pdf

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: core
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
@ 2016-07-11 19:46 ` Marek Polacek
  2016-07-11 19:50 ` Implement -Wswitch-fallthrough: c-family/ Marek Polacek
                   ` (28 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:46 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* builtins.c (expand_builtin): Handle BUILT_IN_FALLTHROUGH.
	* builtins.def: Add BUILT_IN_FALLTHROUGH.
	* common.opt (Wswitch-fallthrough): New option.
	* doc/extend.texi: Document __builtin_fallthrough.
	* doc/invoke.texi: Document -Wswitch-fallthrough.
	* gimple-low.c: Include "diagnostic-core.h" and "gimple-walk.h".
	(purge_builtin_fallthrough_r): New function.
	(purge_builtin_fallthrough): Likewise.
	(lower_stmt): Call purge_builtin_fallthrough.
	* gimplify.c (struct label_entry): New struct.
	(find_label_entry): New function.
	(last_stmt_in_scope): Likewise.
	(warn_switch_fallthrough_r): Likewise.
	(maybe_warn_switch_fallthrough): Likewise.
	(gimplify_switch_expr): Call maybe_warn_switch_fallthrough.
	(gimplify_label_expr): New function.
	(gimplify_case_label_expr): Set location.
	(gimplify_expr): Call gimplify_label_expr.
	* system.h (gcc_fallthrough): New macro.

	* c-c++-common/Wswitch-fallthrough-1.c: New test.
	* c-c++-common/Wswitch-fallthrough-10.c: New test.
	* c-c++-common/Wswitch-fallthrough-11.c: New test.
	* c-c++-common/Wswitch-fallthrough-12.c: New test.
	* c-c++-common/Wswitch-fallthrough-2.c: New test.
	* c-c++-common/Wswitch-fallthrough-3.c: New test.
	* c-c++-common/Wswitch-fallthrough-4.c: New test.
	* c-c++-common/Wswitch-fallthrough-5.c: New test.
	* c-c++-common/Wswitch-fallthrough-6.c: New test.
	* c-c++-common/Wswitch-fallthrough-7.c: New test.
	* c-c++-common/Wswitch-fallthrough-8.c: New test.
	* c-c++-common/Wswitch-fallthrough-9.c: New test.
	* c-c++-common/builtin-fallthrough-1.c: New test.
	* c-c++-common/builtin-fallthrough-2.c: New test.

diff --git gcc/gcc/builtins.c gcc/gcc/builtins.c
index 1465c60..c462bc5 100644
--- gcc/gcc/builtins.c
+++ gcc/gcc/builtins.c
@@ -6885,6 +6889,11 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
 	 folding.  */
       break;
 
+    case BUILT_IN_FALLTHROUGH:
+      /* We should have gotten rid of this during gimplification.  */
+      error ("%Kinvalid use of %<__builtin_fallthrough ()%>", exp);
+      return const0_rtx;
+
     default:	/* just do library call, if unknown builtin */
       break;
     }
diff --git gcc/gcc/builtins.def gcc/gcc/builtins.def
index 33a7626..c75f022 100644
--- gcc/gcc/builtins.def
+++ gcc/gcc/builtins.def
@@ -851,6 +851,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PUR
 DEF_GCC_BUILTIN        (BUILT_IN_VA_ARG_PACK_LEN, "va_arg_pack_len", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN        (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN	       (BUILT_IN_FALLTHROUGH, "fallthrough", BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
 
 /* Implementing nested functions.  */
 DEF_BUILTIN_STUB (BUILT_IN_INIT_TRAMPOLINE, "__builtin_init_trampoline")
diff --git gcc/gcc/common.opt gcc/gcc/common.opt
index a7c5125..741da8d 100644
--- gcc/gcc/common.opt
+++ gcc/gcc/common.opt
@@ -707,6 +707,10 @@ Wsuggest-final-methods
 Common Var(warn_suggest_final_methods) Warning
 Warn about C++ virtual methods where adding final keyword would improve code quality.
 
+Wswitch-fallthrough
+Common Var(warn_switch_fallthrough) Warning Init(1)
+Warn when a switch case falls through.
+
 Wswitch-unreachable
 Common Var(warn_switch_unreachable) Warning Init(1)
 Warn about statements between switch's controlling expression and the first
diff --git gcc/gcc/doc/extend.texi gcc/gcc/doc/extend.texi
index 5b9e617..5fc129d 100644
--- gcc/gcc/doc/extend.texi
+++ gcc/gcc/doc/extend.texi
@@ -11127,6 +11127,25 @@ if (__builtin_expect (ptr != NULL, 1))
 when testing pointer or floating-point values.
 @end deftypefn
 
+@deftypefn {Built-in Function} void __builtin_fallthrough (void)
+When the @option{-Wswitch-fallthrough} command-line options is enabled, the
+compiler warns when a switch case statement falls through.  To suppress
+this warning in a case where the fall through is desirable, it is possible
+to use this function as in the below:
+
+@smallexample
+switch (cond)
+  @{
+  case 1:
+    bar (0);
+    /* FALLTHRU */
+    __builtin_fallthrough ();
+  default:
+    @dots{}
+  @}
+@end smallexample
+@end deftypefn
+
 @deftypefn {Built-in Function} void __builtin_trap (void)
 This function causes the program to exit abnormally.  GCC implements
 this function by using a target-dependent mechanism (such as
diff --git gcc/gcc/doc/invoke.texi gcc/gcc/doc/invoke.texi
index ba44951..0244643 100644
--- gcc/gcc/doc/invoke.texi
+++ gcc/gcc/doc/invoke.texi
@@ -300,7 +300,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wsuggest-final-types @gol -Wsuggest-final-methods -Wsuggest-override @gol
 -Wmissing-format-attribute -Wsubobject-linkage @gol
 -Wswitch  -Wswitch-bool  -Wswitch-default  -Wswitch-enum @gol
--Wswitch-unreachable  -Wsync-nand @gol
+-Wswitch-fallthrough  -Wswitch-unreachable  -Wsync-nand @gol
 -Wsystem-headers  -Wtautological-compare  -Wtrampolines  -Wtrigraphs @gol
 -Wtype-limits  -Wundef @gol
 -Wuninitialized  -Wunknown-pragmas  -Wunsafe-loop-optimizations @gol
@@ -4194,6 +4194,69 @@ switch ((int) (a == 4))
 @end smallexample
 This warning is enabled by default for C and C++ programs.
 
+@item -Wswitch-fallthrough
+@opindex Wswitch-fallthrough
+@opindex Wno-switch-fallthrough
+Warn when a switch case falls through.  For example:
+
+@smallexample
+@group
+switch (cond)
+  @{
+  case 1:
+    a = 1;
+    break;
+  case 2:
+    a = 2;
+  case 3:
+    a = 3;
+    break;
+  @}
+@end group
+@end smallexample
+
+This warning does not warn when the last statement of a case cannot
+fall through, e.g. when there is a return statement of a function
+declared with the noreturn attribute.  @option{-Wswitch-fallthrough}
+also takes into account control flow statements, such as ifs, and only
+warns when appropriate.  E.g.@:
+
+@smallexample
+@group
+switch (cond)
+  @{
+  case 1:
+    if (i > 3) @{
+      bar (5);
+      break;
+    @} else if (i < 1) @{
+      bar (0);
+    @} else
+      return;
+  default:
+    @dots{}
+  @}
+@end group
+@end smallexample
+
+Since there are occasions where a switch case fall through is desirable,
+GCC provides a built-in function, @samp{__builtin_fallthrough}, which can
+be used to suppres this warning what would normally occur:
+
+@smallexample
+@group
+switch (cond)
+  @{
+  case 1:
+    bar (0);
+    /* FALLTHRU */
+    __builtin_fallthrough ();
+  default:
+    @dots{}
+  @}
+@end group
+@end smallexample
+
 @item -Wswitch-unreachable
 @opindex Wswitch-unreachable
 @opindex Wno-switch-unreachable
diff --git gcc/gcc/gimple-low.c gcc/gcc/gimple-low.c
index 9ea17af..70c957b 100644
--- gcc/gcc/gimple-low.c
+++ gcc/gcc/gimple-low.c
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "calls.h"
 #include "gimple-iterator.h"
 #include "gimple-low.h"
+#include "diagnostic-core.h"
+#include "gimple-walk.h"
 
 /* The differences between High GIMPLE and Low GIMPLE are the
    following:
@@ -220,6 +222,56 @@ lower_omp_directive (gimple_stmt_iterator *gsi, struct lower_data *data)
   gsi_next (gsi);
 }
 
+/* Callback for walk_gimple_seq.  */
+
+static tree
+purge_builtin_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
+			     struct walk_stmt_info *)
+{
+  gimple *stmt = gsi_stmt (*gsi_p);
+
+  *handled_ops_p = true;
+  switch (gimple_code (stmt))
+    {
+    case GIMPLE_TRY:
+    case GIMPLE_BIND:
+    case GIMPLE_CATCH:
+    case GIMPLE_EH_FILTER:
+    case GIMPLE_TRANSACTION:
+      /* Walk the sub-statements.  */
+      *handled_ops_p = false;
+      break;
+    case GIMPLE_CALL:
+      if (gimple_call_builtin_p (stmt, BUILT_IN_FALLTHROUGH))
+	{
+	  location_t bfloc = gimple_location (stmt);
+	  gsi_remove (gsi_p, true);
+	  if (gsi_end_p (*gsi_p))
+	    return integer_zero_node;
+	  else if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL
+		   || (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
+		       && !gimple_has_location (gsi_stmt (*gsi_p))))
+	    /* This usage is OK.  */;
+	  else
+	    warning_at (bfloc, 0, "%<__builtin_fallthrough ()%> not "
+			"preceding a label");
+	}
+      break;
+    default:
+      break;
+    }
+  return NULL_TREE;
+}
+
+/* Remove all __builtin_fallthrough calls in SEQ.  */
+
+static void
+purge_builtin_fallthrough (gimple_seq *seq_p)
+{
+  struct walk_stmt_info wi;
+  memset (&wi, 0, sizeof (wi));
+  walk_gimple_seq_mod (seq_p, purge_builtin_fallthrough_r, NULL, &wi);
+}
 
 /* Lower statement GSI.  DATA is passed through the recursion.  We try to
    track the fallthruness of statements and get rid of unreachable return
@@ -242,9 +294,13 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
       /* Propagate fallthruness.  */
       return;
 
+    case GIMPLE_SWITCH:
+      /* Get rid of __builtin_fallthrough.  If they occur outside a case
+	 sequence, we will complain later.  */
+      purge_builtin_fallthrough (&gsi->ptr);
+      gcc_fallthrough ();
     case GIMPLE_COND:
     case GIMPLE_GOTO:
-    case GIMPLE_SWITCH:
       data->cannot_fallthru = true;
       gsi_next (gsi);
       return;
diff --git gcc/gcc/gimplify.c gcc/gcc/gimplify.c
index 47c4d25..3b01cb4 100644
--- gcc/gcc/gimplify.c
+++ gcc/gcc/gimplify.c
@@ -1626,6 +1627,254 @@ maybe_warn_switch_unreachable (gimple_seq seq)
     }
 }
 
+
+/* A label entry that pairs label and a location.  */
+struct label_entry
+{
+  tree label;
+  location_t loc;
+};
+
+/* Find LABEL in vector of label entries VEC.  */
+
+static struct label_entry *
+find_label_entry (const auto_vec <struct label_entry> *vec, tree label)
+{
+  unsigned int i;
+  struct label_entry *l;
+
+  FOR_EACH_VEC_ELT (*vec, i, l)
+    if (l->label == label)
+      return l;
+  return NULL;
+}
+
+/* Find the last statement in a scope STMT.  */
+
+static gimple *
+last_stmt_in_scope (gimple *stmt)
+{
+  if (!stmt)
+    return NULL;
+
+  switch (gimple_code (stmt))
+    {
+    case GIMPLE_BIND:
+      {
+	gbind *bind = as_a <gbind *> (stmt);
+	return last_stmt_in_scope (
+		 gimple_seq_last_stmt (gimple_bind_body (bind)));
+      }
+
+    case GIMPLE_TRY:
+      {
+	gtry *try_stmt = as_a <gtry *> (stmt);
+	return last_stmt_in_scope (
+		 gimple_seq_last_stmt (gimple_try_eval (try_stmt)));
+      }
+
+    default:
+      return stmt;
+    }
+}
+
+/* Callback for walk_gimple_seq.  */
+
+static tree
+warn_switch_fallthrough_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
+			   struct walk_stmt_info *)
+{
+  gimple *stmt = gsi_stmt (*gsi_p);
+
+  *handled_ops_p = true;
+  switch (gimple_code (stmt))
+    {
+    case GIMPLE_TRY:
+    case GIMPLE_BIND:
+    case GIMPLE_CATCH:
+    case GIMPLE_EH_FILTER:
+    case GIMPLE_TRANSACTION:
+      /* Walk the sub-statements.  */
+      *handled_ops_p = false;
+      break;
+
+    /* Find a sequence of form:
+
+       GIMPLE_LABEL
+       [...]
+       <may fallthru stmt>
+       GIMPLE_LABEL
+
+       and possibly warn.  */
+    case GIMPLE_LABEL:
+      {
+	/* Found a label.  Skip all immediately following labels.  */
+	while (!gsi_end_p (*gsi_p)
+	       && gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
+	  gsi_next (gsi_p);
+
+	/* There might be no more statements.  */
+	if (gsi_end_p (*gsi_p))
+	  return integer_zero_node;
+
+	/* Next statements, if any, are non-label.  */
+	gimple *prev = NULL;
+	/* Vector of labels that fall through.  */
+	auto_vec <struct label_entry> labels;
+
+	do
+	  {
+	    if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_BIND
+		|| gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_TRY)
+	      {
+		/* Nested scope.  Only look at the last statement of
+		   the innermost scope.  */
+		location_t bind_loc = gimple_location (gsi_stmt (*gsi_p));
+		gimple *last = last_stmt_in_scope (gsi_stmt (*gsi_p));
+		if (last)
+		  {
+		    prev = last;
+		    /* It might be a label without a location.  Use the
+		       location of the scope then.  */
+		    if (!gimple_has_location (prev))
+		      gimple_set_location (prev, bind_loc);
+		  }
+		gsi_next (gsi_p);
+		continue;
+	      }
+	    /* If's are tricky.  */
+	    if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_COND)
+	      {
+		gcond *cond_stmt = as_a <gcond *> (gsi_stmt (*gsi_p));
+		tree false_lab = gimple_cond_false_label (cond_stmt);
+		location_t if_loc = gimple_location (cond_stmt);
+
+		/* If we have e.g.
+		   if (i > 1) goto <D.2259>; else goto D;
+		   we can't do much with the else-branch.  */
+		if (!DECL_ARTIFICIAL (false_lab))
+		  break;
+
+		/* Go on until the false label, then one step back.  */
+		for (; !gsi_end_p (*gsi_p); gsi_next (gsi_p))
+		  {
+		    stmt = gsi_stmt (*gsi_p);
+		    if (gimple_code (stmt) == GIMPLE_LABEL
+			&& gimple_label_label (as_a <glabel *> (stmt))
+			     == false_lab)
+		      break;
+		  }
+
+		/* Not found?  Oops.  */
+		if (gsi_end_p (*gsi_p))
+		  break;
+
+		{
+		  struct label_entry l = { false_lab, if_loc };
+		  labels.safe_push (l);
+		}
+
+		/* Go to the last statement of the then branch.  */
+		gsi_prev (gsi_p);
+
+		/* if (i != 0) goto <D.1759>; else goto <D.1760>;
+		   <D.1759>:
+		   <stmt>;
+		   goto <D.1761>;
+		   <D.1760>:
+		 */
+		if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
+		    && !gimple_has_location (gsi_stmt (*gsi_p)))
+		  {
+		    /* Look at the statement before, it might be
+		       __builtin_fallthrough, in which case don't
+		       warn.  */
+		    gsi_prev (gsi_p);
+		    bool fallthru_before_dest
+		      = gimple_call_builtin_p (gsi_stmt (*gsi_p),
+					       BUILT_IN_FALLTHROUGH);
+		    gsi_next (gsi_p);
+		    tree goto_dest = gimple_goto_dest (gsi_stmt (*gsi_p));
+		    if (!fallthru_before_dest)
+		      {
+			struct label_entry l = { goto_dest, if_loc };
+			labels.safe_push (l);
+		      }
+		  }
+		/* And move back.  */
+		gsi_next (gsi_p);
+	      }
+	    /* Remember the last statement.  Skip labels that are of no
+	       interest to us.  */
+	    if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
+	      {
+		tree label
+		  = gimple_label_label (as_a <glabel *> (gsi_stmt (*gsi_p)));
+		if (find_label_entry (&labels, label))
+		  prev = gsi_stmt (*gsi_p);
+	      }
+	    else
+	      prev = gsi_stmt (*gsi_p);
+	    gsi_next (gsi_p);
+	  }
+	while (!gsi_end_p (*gsi_p)
+	       /* Stop if we find a case or a user-defined label.  */
+	       && (gimple_code (gsi_stmt (*gsi_p)) != GIMPLE_LABEL
+		   || !gimple_has_location (gsi_stmt (*gsi_p))));
+
+	/* There might be no more statements.  */
+	if (gsi_end_p (*gsi_p))
+	  return integer_zero_node;
+
+	gimple *next = gsi_stmt (*gsi_p);
+	/* If what follows is a label, then we may have a fallthrough.  */
+	if (gimple_code (next) == GIMPLE_LABEL
+	    && gimple_has_location (next)
+	    && prev != NULL)
+	  {
+	    tree label;
+	    struct label_entry *l;
+	    if (gimple_code (prev) == GIMPLE_LABEL
+		&& (label = gimple_label_label (as_a <glabel *> (prev)))
+		&& (l = find_label_entry (&labels, label))
+		&& warning_at (l->loc, OPT_Wswitch_fallthrough,
+			       "this statement may fall through"))
+	      inform (gimple_location (next), "here");
+	    else if (!gimple_call_builtin_p (prev, BUILT_IN_FALLTHROUGH)
+		     /* Try to be clever and don't warn when the statement
+			can't actually fall through.  */
+		     && gimple_stmt_may_fallthru (prev)
+		     && gimple_has_location (prev)
+		     && warning_at (gimple_location (prev),
+				    OPT_Wswitch_fallthrough,
+				    "this statement may fall through"))
+	      inform (gimple_location (next), "here");
+
+	    /* So that next warn_switch_fallthrough_r will start looking for
+	       a new sequence starting with this label.  */
+	    gsi_prev (gsi_p);
+	  }
+      }
+      break;
+   default:
+      break;
+    }
+  return NULL_TREE;
+}
+
+/* Warn when a switch case falls through.  */
+
+static void
+maybe_warn_switch_fallthrough (gimple_seq seq)
+{
+  if (!warn_switch_fallthrough || lang_GNU_Fortran ())
+    return;
+
+  struct walk_stmt_info wi;
+  memset (&wi, 0, sizeof (wi));
+  walk_gimple_seq (seq, warn_switch_fallthrough_r, NULL, &wi);
+}
+
 \f
 /* Gimplify a SWITCH_EXPR, and collect the vector of labels it can
    branch to.  */
@@ -1664,6 +1913,7 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
       gimplify_stmt (&SWITCH_BODY (switch_expr), &switch_body_seq);
 
       maybe_warn_switch_unreachable (switch_body_seq);
+      maybe_warn_switch_fallthrough (switch_body_seq);
 
       labels = gimplify_ctxp->case_labels;
       gimplify_ctxp->case_labels = saved_labels;
@@ -1694,6 +1944,21 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
   return GS_ALL_DONE;
 }
 
+/* Gimplify the LABEL_EXPR pointed to by EXPR_P.  */
+
+static enum gimplify_status
+gimplify_label_expr (tree *expr_p, gimple_seq *pre_p)
+{
+  gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
+	      == current_function_decl);
+
+  glabel *label_stmt = gimple_build_label (LABEL_EXPR_LABEL (*expr_p));
+  gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
+  gimplify_seq_add_stmt (pre_p, label_stmt);
+
+  return GS_ALL_DONE;
+}
+
 /* Gimplify the CASE_LABEL_EXPR pointed to by EXPR_P.  */
 
 static enum gimplify_status
@@ -1711,6 +1976,7 @@ gimplify_case_label_expr (tree *expr_p, gimple_seq *pre_p)
       break;
 
   label_stmt = gimple_build_label (CASE_LABEL (*expr_p));
+  gimple_set_location (label_stmt, EXPR_LOCATION (*expr_p));
   ctxp->case_labels.safe_push (*expr_p);
   gimplify_seq_add_stmt (pre_p, label_stmt);
 
@@ -10668,11 +10954,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  break;
 
 	case LABEL_EXPR:
-	  ret = GS_ALL_DONE;
-	  gcc_assert (decl_function_context (LABEL_EXPR_LABEL (*expr_p))
-		      == current_function_decl);
-	  gimplify_seq_add_stmt (pre_p,
-			  gimple_build_label (LABEL_EXPR_LABEL (*expr_p)));
+	  ret = gimplify_label_expr (expr_p, pre_p);
 	  break;
 
 	case CASE_LABEL_EXPR:
diff --git gcc/gcc/system.h gcc/gcc/system.h
index 78a7da6..14e4a1e 100644
--- gcc/gcc/system.h
+++ gcc/gcc/system.h
@@ -746,6 +746,12 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
 #define gcc_unreachable() (fancy_abort (__FILE__, __LINE__, __FUNCTION__))
 #endif
 
+#if GCC_VERSION >= 7000
+# define gcc_fallthrough() __builtin_fallthrough ()
+#else
+# define gcc_fallthrough()
+#endif
+
 #if GCC_VERSION >= 3001
 #define STATIC_CONSTANT_P(X) (__builtin_constant_p (X) && (X))
 #else
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-1.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-1.c
index e69de29..dc77bcc 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-1.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-1.c
@@ -0,0 +1,38 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+/* Test taken from
+   <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0188r0.pdf>.  */
+
+extern void f (int);
+
+void
+foo (int n)
+{
+  switch (n)
+    {
+    case 22:
+    case 33:
+      f (1);  /* { dg-warning "statement may fall through" } */
+    case 44:
+      f (2);
+      __builtin_fallthrough ();
+    case 55:
+      if (n > 10)
+	{
+	  f (3);
+	  break;
+	}
+      else
+	{
+	  f (4);
+	  __builtin_fallthrough ();
+	}
+    case 66:
+      f (5);
+     __builtin_fallthrough (); /* { dg-warning "not preceding" } */
+      f (6); /* { dg-warning "statement may fall through" } */
+    case 77:
+       f (7);
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-10.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-10.c
index e69de29..47e8894 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-10.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-10.c
@@ -0,0 +1,227 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+extern void bar (int);
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  break;
+	}
+      else if (i > 10)
+	{
+	  bar (1);
+	  __builtin_fallthrough ();
+	}
+      else
+	break;
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	bar (2);
+      else if (i > 10)
+	{
+	  bar (3);
+	  __builtin_fallthrough ();
+	}
+      else
+	break;
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  break;
+	}
+      else if (i > 10) /* { dg-warning "statement may fall through" } */
+	{
+	  bar (1);
+	}
+      else
+	break;
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  break;
+	}
+      else if (i > 10)
+	{
+	  bar (1);
+	  break;
+	}
+      else
+	break;
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  break;
+	}
+      else if (i > 10)
+	{
+	  bar (1);
+	  break;
+	}
+      else
+	bar (2); /* { dg-warning "statement may fall through" } */
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  __builtin_fallthrough ();
+	}
+      else if (i > 10)
+	{
+	  bar (1);
+	  break;
+	}
+      else
+	bar (2); /* { dg-warning "statement may fall through" } */
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  __builtin_fallthrough ();
+	}
+      else if (i > 10)
+	{
+	  bar (1);
+	  __builtin_fallthrough ();
+	}
+      else
+	break;
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  __builtin_fallthrough ();
+	}
+      else if (i > 10)
+	{
+	  bar (1);
+	  __builtin_fallthrough ();
+	}
+      else
+	bar (2); /* { dg-warning "statement may fall through" } */
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  __builtin_fallthrough ();
+	}
+      else if (i > 10) /* { dg-warning "statement may fall through" } */
+	{
+	  bar (1);
+	  bar (2);
+	}
+      else
+	__builtin_fallthrough ();
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)  /* { dg-warning "statement may fall through" } */
+	{
+	  bar (0);
+	}
+      else if (i > 10)
+	{
+	  bar (1);
+	}
+      else
+	{
+	  bar (1);
+	  __builtin_fallthrough ();
+	}
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  __builtin_fallthrough ();
+	}
+      else if (i > 10)
+	{
+	  bar (1);
+	  break;
+	}
+      else
+	{
+	  bar (1);
+	  __builtin_fallthrough ();
+	}
+      case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	  bar (0);
+	  break;
+	}
+      else if (i > 10) /* { dg-warning "statement may fall through" } */
+	{
+	  bar (1);
+	}
+      else
+	{
+	  bar (1);
+	  __builtin_fallthrough ();
+	}
+      case 2:;
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-11.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-11.c
index e69de29..a204e75 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-11.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-11.c
@@ -0,0 +1,23 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough -O2" } */
+
+/* Prevent false positive with optimizations.  */
+
+extern void g (int);
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i > 10)
+	g (0);
+      else
+	goto L;
+      break;
+L:
+    case 2:;
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-12.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-12.c
index e69de29..7861a37 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-12.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-12.c
@@ -0,0 +1,26 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough -O2" } */
+
+/* Don't let optimizations preclude the warning.  */
+
+extern void bar (int);
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i > 1)
+	bar (1);
+      else
+	goto D;
+      break;
+    case 2:
+      bar (2); /* { dg-warning "statement may fall through" } */
+    D:
+    default:
+      bar (33);
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-2.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-2.c
index e69de29..d8cd826 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-2.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-2.c
@@ -0,0 +1,223 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+extern void bar (int);
+
+/* Test if without else.  */
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	bar (1);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	return;
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)  /* { dg-warning "statement may fall through" } */
+	goto L1;
+    case 2:
+L1:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)  /* { dg-warning "statement may fall through" } */
+	goto L2;
+L2:
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	goto L3;
+      break;
+    case 2:
+L3:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	goto L4;
+      break;
+L4:
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)  /* { dg-warning "statement may fall through" } */
+	if (i > 9)
+	  bar (1);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	if (i > 9)
+	  bar (1);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      { int a; }
+      {
+      if (i)  /* { dg-warning "statement may fall through" } */
+	if (i > 9)
+	  bar (1);
+      }
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      bar (2); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      bar (2);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	return;
+      bar (2); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	return;
+      bar (2);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      if (i)
+	bar (2);
+      if (i)
+	bar (3);
+      bar (4); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      if (i)
+	bar (2);
+      if (i) /* { dg-warning "statement may fall through" } */
+	bar (3);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      if (i)
+	bar (2);
+      if (i)
+	bar (3);
+      bar (4);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      if (i)
+	bar (2);
+      if (i)
+	bar (3);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-3.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-3.c
index e69de29..a4d62d9 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-3.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-3.c
@@ -0,0 +1,543 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+extern void bar (int);
+
+/* Test if with else.  */
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	bar (1);
+      else
+	bar (2);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      else
+	bar (2);
+      bar (3); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        return;
+      else
+	bar (2); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        return;
+      else
+	bar (2);
+      bar (3); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+        bar (1);
+      else
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      else
+	return;
+      bar (3); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	return;
+      else
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	return;
+      else
+	return;
+      bar (3); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	{
+          bar (1);
+          bar (2);
+          bar (3);
+          bar (4);
+	}
+      else
+	{
+          bar (5);
+          bar (6);
+          bar (7);
+          bar (8);
+	}
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+          bar (1);
+          bar (2);
+          bar (3);
+          bar (4);
+	}
+      else
+	{
+          bar (5);
+          bar (6);
+          bar (7);
+          bar (8);
+	}
+      bar (9); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+        {
+	}
+      else
+	bar (2);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	bar (1);
+      else
+	{
+	}
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	{
+	}
+      else
+	{
+	}
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	return;
+      else
+	{
+	}
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	{
+	}
+      else
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        goto L1;
+      else
+	bar (2); /* { dg-warning "statement may fall through" } */
+    case 2:
+L1:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        goto L2;
+      else
+	bar (2); /* { dg-warning "statement may fall through" } */
+L2:
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	bar (1);
+      else
+        goto L3;
+    case 2:
+L3:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i) /* { dg-warning "statement may fall through" } */
+	bar (1);
+      else
+        goto L4;
+L4:
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        goto L5;
+      else
+        goto L5;
+L5:
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        bar (1);
+      else
+	bar (2);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        bar (1);
+      else
+	bar (2);
+      bar (3);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        return;
+      else
+	bar (2);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        return;
+      else
+	bar (2);
+      bar (3);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        bar (1);
+      else
+	return;
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      else
+	return;
+      bar (3);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	return;
+      else
+	return;
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	return;
+      else
+	return;
+      bar (3);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+          bar (1);
+          bar (2);
+          bar (3);
+          bar (4);
+	}
+      else
+	{
+          bar (5);
+          bar (6);
+          bar (7);
+          bar (8);
+	}
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+          bar (1);
+          bar (2);
+          bar (3);
+          bar (4);
+	}
+      else
+	{
+          bar (5);
+          bar (6);
+          bar (7);
+          bar (8);
+	}
+      bar (9);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        {
+	}
+      else
+	bar (2);
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      else
+	{
+	}
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	}
+      else
+	{
+	}
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	return;
+      else
+	{
+	}
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	{
+	}
+      else
+	return;
+      break;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        goto L6;
+      else
+	bar (2);
+      break;
+    case 2:
+L6:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        goto L7;
+      else
+	bar (2);
+      break;
+L7:
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      else
+        goto L8;
+      break;
+    case 2:
+L8:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+	bar (1);
+      else
+        goto L9;
+      break;
+L9:
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i)
+        goto L10;
+      else
+        goto L10;
+      break;
+L10:
+    case 2:
+      __builtin_abort ();
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-4.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-4.c
index e69de29..7229cde 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-4.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-4.c
@@ -0,0 +1,250 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+extern void bar (int);
+
+/* Test if with more elses.  */
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i > 5) /* { dg-warning "statement may fall through" } */
+        bar (1);
+      else if (i > 10)
+	bar (2);
+      else if (i > 15)
+	bar (3);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5) /* { dg-warning "statement may fall through" } */
+	bar (1);
+      else if (i > 10)
+	bar (2);
+      else if (i > 15)
+	bar (3);
+      else
+	bar (4);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+        return;
+      else if (i > 10) /* { dg-warning "statement may fall through" } */
+	bar (2);
+      else if (i > 15)
+	bar (3);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+        return;
+      else if (i > 10) /* { dg-warning "statement may fall through" } */
+	bar (2);
+      else if (i > 15)
+	bar (3);
+      else
+	bar (4);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5) /* { dg-warning "statement may fall through" } */
+        bar (1);
+      else if (i > 10)
+	return;
+      else if (i > 15)
+	bar (3);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5) /* { dg-warning "statement may fall through" } */
+        bar (1);
+      else if (i > 10)
+	return;
+      else if (i > 15)
+	bar (3);
+      else
+	bar (4);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5) /* { dg-warning "statement may fall through" } */
+        bar (1);
+      else if (i > 10)
+	bar (4);
+      else if (i > 15)
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5) /* { dg-warning "statement may fall through" } */
+        bar (1);
+      else if (i > 10)
+	bar (4);
+      else if (i > 15)
+	return;
+      else
+	bar (4);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+        return;
+      else if (i > 10)
+	return;
+      else if (i > 15) /* { dg-warning "statement may fall through" } */
+	bar (3);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+        return;
+      else if (i > 10)
+	return;
+      else if (i > 15) /* { dg-warning "statement may fall through" } */
+	bar (3);
+      else
+	bar (4);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+        return;
+      else if (i > 10) /* { dg-warning "statement may fall through" } */
+	bar (2);
+      else if (i > 15)
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+        return;
+      else if (i > 10) /* { dg-warning "statement may fall through" } */
+	bar (2);
+      else if (i > 15)
+	return;
+      else
+	bar (4);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5) /* { dg-warning "statement may fall through" } */
+        bar (1);
+      else if (i > 10)
+	return;
+      else if (i > 15)
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5) /* { dg-warning "statement may fall through" } */
+        bar (1);
+      else if (i > 10)
+	return;
+      else if (i > 15)
+	return;
+      else
+	bar (4);
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+       return;
+      else if (i > 10)
+	return;
+      else if (i > 15) /* { dg-warning "statement may fall through" } */
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+       return;
+      else if (i > 10)
+	return;
+      else if (i > 15)
+	return;
+      else
+	bar (4); /* { dg-warning "statement may fall through" } */
+    case 2:
+      __builtin_abort ();
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 5)
+       return;
+      else if (i > 10)
+	return;
+      else if (i > 15)
+	return;
+      else
+	return;
+    case 2:
+      __builtin_abort ();
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-5.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-5.c
index e69de29..d11a413 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-5.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-5.c
@@ -0,0 +1,109 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+extern void bar (int);
+extern void die (void) __attribute__((noreturn));
+
+/* Test may_fallthru-ness.  */
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      bar (0);
+      __builtin_fallthrough ();
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      bar (0);
+      return;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      bar (0);
+      break;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      bar (0);
+      goto L1;
+L1:
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      bar (0);
+      die ();
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int i, j, k;
+	bar (0);
+	__builtin_fallthrough ();
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int i, j, k;
+        bar (0);
+        return;
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int i, j, k;
+        bar (0);
+        break;
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int i, j, k;
+        bar (0);
+        goto L2;
+      }
+L2:
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int i, j, k;
+        bar (0);
+        die ();
+      }
+    case 2:;
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-6.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-6.c
index e69de29..2e16218 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-6.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-6.c
@@ -0,0 +1,284 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+extern void bar (int);
+
+/* Test nested scopes.  */
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      {
+	int j;
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 10; /* { dg-warning "statement may fall through" } */
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int k = 9;
+	k++;
+	{
+	  int j = 10;
+	  j++; /* { dg-warning "statement may fall through" } */
+	}
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int k = 9;
+	k++;
+	{
+	  int j = 10;
+	  j++;
+	  {
+	    bar (1); /* { dg-warning "statement may fall through" } */
+	  }
+	}
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	__builtin_fallthrough ();
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	{
+	  int k = j + 5;
+	  bar (k);
+	  __builtin_fallthrough ();
+	}
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	return;
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	goto L1;
+      }
+L1:
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      { /* { dg-warning "statement may fall through" "" { target c } 112 } */
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  return; /* { dg-warning "statement may fall through" "" { target c++ } 116 } */
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  return;
+	else
+	  return;
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      { /* { dg-warning "statement may fall through" "" { target c } 138 } */
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  bar (1);
+	else
+	  return; /* { dg-warning "statement may fall through" "" { target c++ } 144 } */
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  return;
+	else
+	  bar (2); /* { dg-warning "statement may fall through" } */
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      { /* { dg-warning "statement may fall through" "" { target c } 166 } */
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  bar (1);
+	else
+	  bar (2); /* { dg-warning "statement may fall through" "" { target c++ } 172 } */
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  return;
+      }
+      break;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  return;
+	else
+	  return;
+      }
+      break;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  bar (1);
+	else
+	  return;
+      }
+      break;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  return;
+	else
+	  bar (2);
+      }
+      break;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  bar (1);
+	else
+	  bar (2);
+      }
+      break;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 9;
+	while (1);
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      { /* { dg-warning "statement may fall through" "" { target c } 263 } */
+	int j = 9;
+	switch (j); /* { dg-warning "statement may fall through" "" { target c++ } 265 } */
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int j = 0;
+	bar (j);
+	if (j == 8)
+	  bar (1);
+	else
+	  bar (2);
+	__builtin_fallthrough ();
+      }
+    case 2:;
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-7.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-7.c
index e69de29..f864669 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-7.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-7.c
@@ -0,0 +1,114 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+extern void bar (int);
+extern int bar2 (void);
+extern int *map;
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 1:
+      bar (0); /* { dg-warning "statement may fall through" } */
+      static int i = 10;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	int a[i]; /* { dg-warning "statement may fall through" } */
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      for (int j = 0; j < 10; j++) /* { dg-warning "statement may fall through" "" { target c } 31 } */
+	map[j] = j; /* { dg-warning "statement may fall through" "" { target c++ } 32 } */
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      do /* { dg-warning "statement may fall through" "" { target c++ } 39 } */
+	bar (2);
+      while (--i); /* { dg-warning "statement may fall through" "" { target c } 41 } */
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      {
+	switch (i + 2)
+	  case 4:
+	    bar (1); /* { dg-warning "statement may fall through" } */
+	  case 5:
+	    return;
+      }
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:;
+    case 2:;
+    }
+
+  switch (i)
+    {
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i & 1) /* { dg-warning "statement may fall through" } */
+	{
+	  bar (23);
+	  break;
+	}
+    case 2:;
+    }
+
+  switch (i)
+    {
+    case 1:
+      if (i > 9) /* { dg-warning "statement may fall through" } */
+	{
+	  bar (9);
+	  if (i == 10)
+	    {
+	      bar (10);
+	      break;
+	    }
+	}
+    case 2:;
+    }
+
+  int r;
+  switch (i)
+    {
+      case 1:
+	r = bar2 ();
+	if (r) /* { dg-warning "statement may fall through" } */
+	  break;
+      case 2:;
+    }
+
+  switch (i)
+    {
+      case 1:
+	r = bar2 ();
+	if (r)
+	  return;
+	if (!i) /* { dg-warning "statement may fall through" } */
+	  return;
+      case 2:;
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-8.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-8.c
index e69de29..508303d 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-8.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-8.c
@@ -0,0 +1,99 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+extern void grace (int);
+
+int
+fn1 (int i)
+{
+  switch (i)
+    case 1:
+    if (i == 5)
+      grace (0);
+    else
+      goto done;
+done:;
+}
+
+int
+fn2 (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i == 5) /* { dg-warning "statement may fall through" } */
+	grace (0);
+      else
+	goto done;
+    case 2:
+      --i;
+    }
+done:;
+}
+
+int
+fn3 (int i)
+{
+  switch (i)
+    {
+    case 1:
+    if (i == 5)
+      goto done;
+    else
+      goto done;
+    }
+done:;
+}
+
+int
+fn4 (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i == 5)
+	{
+	  grace (1);
+	  goto done;
+	}
+      else
+	goto done;
+    case 2:;
+    }
+done:;
+}
+
+int
+fn5 (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i == 5)
+	{
+	  grace (1);
+	  goto done;
+	}
+      else
+	grace (4); /* { dg-warning "statement may fall through" } */
+    case 2:;
+    }
+done:;
+}
+
+int
+fn6 (int i)
+{
+  switch (i)
+    {
+    case 1:
+      if (i == 5) /* { dg-warning "statement may fall through" } */
+	{
+	  grace (1);
+	  goto done;
+	}
+    case 2:;
+    }
+done:;
+}
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-9.c gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-9.c
index e69de29..b241009 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-9.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-fallthrough-9.c
@@ -0,0 +1,26 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-fallthrough" } */
+
+/* Test we don't remove __builtin_fallthrough too early.  */
+
+extern void h (int);
+
+void
+g (int i)
+{
+  switch (i)
+    {
+    case 1:
+      {
+	switch (i)
+	  {
+	    case 3:
+	      h (7);
+	      __builtin_fallthrough ();
+	    case 4:;
+	  }
+      }
+    case 2:;
+    }
+}
diff --git gcc/gcc/testsuite/c-c++-common/builtin-fallthrough-1.c gcc/gcc/testsuite/c-c++-common/builtin-fallthrough-1.c
index e69de29..6424278 100644
--- gcc/gcc/testsuite/c-c++-common/builtin-fallthrough-1.c
+++ gcc/gcc/testsuite/c-c++-common/builtin-fallthrough-1.c
@@ -0,0 +1,44 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+/* { dg-options "-Wno-switch-unreachable" } */
+
+extern void g (int);
+void
+f1 (int i)
+{
+  switch (i)
+    {
+      __builtin_fallthrough (); /* { dg-warning "not preceding" } */
+      g (3);
+    case 5:
+      g (5);
+      __builtin_fallthrough (); /* { dg-warning "not preceding" } */
+      g (7);
+      break;
+      __builtin_fallthrough ();
+    case 4:
+      g (9);
+      __builtin_fallthrough ();
+    case 51:
+      {
+	int l;
+        __builtin_fallthrough ();
+      }
+    case 52:
+      __builtin_fallthrough ();
+    }
+}
+
+void
+f2 (int i)
+{
+  if (i)
+    __builtin_fallthrough (); /* { dg-error "invalid use" } */
+}
+
+void
+f3 (int i)
+{
+  switch (i)
+  __builtin_fallthrough ();
+}
diff --git gcc/gcc/testsuite/c-c++-common/builtin-fallthrough-2.c gcc/gcc/testsuite/c-c++-common/builtin-fallthrough-2.c
index e69de29..dd4be9f 100644
--- gcc/gcc/testsuite/c-c++-common/builtin-fallthrough-2.c
+++ gcc/gcc/testsuite/c-c++-common/builtin-fallthrough-2.c
@@ -0,0 +1,16 @@
+/* PR c/7652 */
+/* { dg-do compile } */
+
+extern void g (int);
+
+void
+f (int i)
+{
+  switch (i)
+    {
+    case 5:
+      g (5);
+      __builtin_fallthrough (1); /* { dg-error "too many" } */
+    default:;
+    }
+}

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: c-family/
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
  2016-07-11 19:46 ` Implement -Wswitch-fallthrough: core Marek Polacek
@ 2016-07-11 19:50 ` Marek Polacek
  2016-07-11 19:50 ` Implement -Wswitch-fallthrough: c/ Marek Polacek
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:50 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* c-ada-spec.c (print_ada_macros): Add gcc_fallthrough.
	(to_ada_name): Likewise.
	(dump_generic_ada_node): Likewise.
	(dump_nested_type): Likewise.
	* c-common.c (warn_if_unused_value): Likewise.
	(sizeof_pointer_memaccess_warning): Likewise.
	(c_common_truthvalue_conversion): Likewise.
	(handle_tm_attribute): Likewise.
	(c_cpp_error): Likewise.
	(resolve_overloaded_builtin): Likewise.
	(scalar_to_vector): Likewise.
	* c-gimplify.c (c_gimplify_expr):  Likewise.
	* c-lex.c (c_lex_with_flags): Likewise.
	(lex_string): Likewise.
	* c-omp.c (c_finish_omp_for): Likewise.
	* c-opts.c (c_common_handle_option): Likewise.
	* c-pragma.c (handle_pragma_pack): Likewise.
	* c-pretty-print.c (c_pretty_printer::postfix_expression): Likewise.
	* cilk.c (extract_free_variables): Likewise.

diff --git gcc/gcc/c-family/c-ada-spec.c gcc/gcc/c-family/c-ada-spec.c
index e33fdff..04a918f 100644
--- gcc/gcc/c-family/c-ada-spec.c
+++ gcc/gcc/c-family/c-ada-spec.c
@@ -288,6 +288,7 @@ print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros)
 		        break;
 		      }
 		    /* fallthrough */
+		    gcc_fallthrough ();
 
 		  case CPP_RSHIFT:
 		  case CPP_COMPL:
@@ -1182,6 +1183,7 @@ to_ada_name (const char *name, int *space_found)
 	  if (len2 && s[len2 - 1] == '_')
 	    s[len2++] = 'u';
 	  /* fall through */
+	  gcc_fallthrough ();
 
 	default:
 	  s[len2++] = name[j];
@@ -1862,6 +1864,8 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
     case TREE_BINFO:
       dump_generic_ada_node
 	(buffer, BINFO_TYPE (node), type, spc, limited_access, name_only);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     case TREE_VEC:
       pp_string (buffer, "--- unexpected node: TREE_VEC");
@@ -2585,6 +2589,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
 	      pp_string (buffer, ");");
 	    }
 	}
+      gcc_fallthrough ();
 
     default:
       break;
diff --git gcc/gcc/c-family/c-common.c gcc/gcc/c-family/c-common.c
index 936ddfb..0f5f65a 100644
--- gcc/gcc/c-family/c-common.c
+++ gcc/gcc/c-family/c-common.c
@@ -1506,6 +1506,7 @@ warn_if_unused_value (const_tree exp, location_t locus)
 	  goto restart;
 	}
       /* Fall through.  */
+     gcc_fallthrough ();
 
     default:
       /* Referencing a volatile value is a side effect, so don't warn.  */
@@ -1518,6 +1519,7 @@ warn_if_unused_value (const_tree exp, location_t locus)
 	 but front ends may define such.  */
       if (EXPRESSION_CLASS_P (exp) && TREE_OPERAND_LENGTH (exp) == 0)
 	return false;
+      gcc_fallthrough ();
 
     warn:
       return warning_at (locus, OPT_Wunused_value, "value computed is not used");
@@ -1629,6 +1631,7 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
     case BUILT_IN_STRNCASECMP:
       cmp = true;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_STRNCPY:
     case BUILT_IN_STRNCPY_CHK:
     case BUILT_IN_STRNCAT:
@@ -1637,6 +1640,7 @@ sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
     case BUILT_IN_STPNCPY_CHK:
       strop = true;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_MEMCPY:
     case BUILT_IN_MEMCPY_CHK:
     case BUILT_IN_MEMMOVE:
@@ -4468,6 +4472,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
     case FUNCTION_DECL:
       expr = build_unary_op (location, ADDR_EXPR, expr, 0);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case ADDR_EXPR:
       {
@@ -8739,6 +8744,7 @@ handle_tm_attribute (tree *node, tree name, tree args,
       if (tm_attr_to_mask (name) & ~(TM_ATTR_SAFE | TM_ATTR_CALLABLE))
 	goto ignored;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case FUNCTION_TYPE:
     case METHOD_TYPE:
@@ -8782,11 +8788,13 @@ handle_tm_attribute (tree *node, tree name, tree args,
 	  }
       }
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     default:
       /* If a function is next, pass it on to be tried next.  */
       if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
 	return tree_cons (name, args, NULL);
+      gcc_fallthrough ();
 
     ignored:
       warning (OPT_Wattributes, "%qE attribute ignored", name);
@@ -10253,6 +10261,7 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
 	return false;
       global_dc->dc_warn_system_headers = 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case CPP_DL_WARNING:
       if (flag_no_output)
 	return false;
@@ -11450,6 +11459,7 @@ resolve_overloaded_builtin (location_t loc, tree function,
       {
 	fetch_op = false;
 	/* Fallthrough to further processing.  */
+	gcc_fallthrough ();
       }
     case BUILT_IN_ATOMIC_ADD_FETCH_N:
     case BUILT_IN_ATOMIC_SUB_FETCH_N:
@@ -11466,6 +11476,7 @@ resolve_overloaded_builtin (location_t loc, tree function,
       {
         orig_format = false;
 	/* Fallthru for parameter processing.  */
+	gcc_fallthrough ();
       }
     case BUILT_IN_SYNC_FETCH_AND_ADD_N:
     case BUILT_IN_SYNC_FETCH_AND_SUB_N:
@@ -12623,6 +12634,7 @@ scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1,
       case BIT_AND_EXPR:
 	integer_only_op = true;
 	/* ... fall through ...  */
+	gcc_fallthrough ();
 
       case VEC_COND_EXPR:
 
@@ -12678,6 +12690,7 @@ scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1,
 	      }
 	    return ret;
 	  }
+	gcc_fallthrough ();
       default:
 	break;
     }
diff --git gcc/gcc/c-family/c-gimplify.c gcc/gcc/c-family/c-gimplify.c
index c18b057..a7a7189 100644
--- gcc/gcc/c-family/c-gimplify.c
+++ gcc/gcc/c-family/c-gimplify.c
@@ -295,6 +295,7 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
 	  cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p);
 	  return (enum gimplify_status) gimplify_cilk_spawn (expr_p);
 	}
+      gcc_fallthrough ();
 
     default:;
     }
diff --git gcc/gcc/c-family/c-lex.c gcc/gcc/c-family/c-lex.c
index 8f33d86..634cd20 100644
--- gcc/gcc/c-family/c-lex.c
+++ gcc/gcc/c-family/c-lex.c
@@ -493,6 +493,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
 		  break;
 		}
 	      /* FALLTHROUGH */
+	      gcc_fallthrough ();
 
 	    default:
 	      /* ... or not.  */
@@ -504,6 +505,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
 	}
 
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case CPP_HASH:
     case CPP_PASTE:
       {
@@ -1127,6 +1129,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
 	  goto retry;
 	}
       /* FALLTHROUGH */
+      gcc_fallthrough ();
 
     default:
       break;
@@ -1142,6 +1145,8 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
 	  else
 	    error ("unsupported non-standard concatenation of string literals");
 	}
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     case CPP_STRING:
       if (!concats)
diff --git gcc/gcc/c-family/c-omp.c gcc/gcc/c-family/c-omp.c
index 1691c40..c0a3e9a 100644
--- gcc/gcc/c-family/c-omp.c
+++ gcc/gcc/c-family/c-omp.c
@@ -634,6 +634,7 @@ c_finish_omp_for (location_t locus, enum tree_code code, tree declv,
 		break;
 	      incr = TREE_OPERAND (incr, 1);
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 	    case MODIFY_EXPR:
 	      if (TREE_OPERAND (incr, 0) != decl)
 		break;
diff --git gcc/gcc/c-family/c-opts.c gcc/gcc/c-family/c-opts.c
index ff6339c..cb7728d 100644
--- gcc/gcc/c-family/c-opts.c
+++ gcc/gcc/c-family/c-opts.c
@@ -437,6 +437,7 @@ c_common_handle_option (size_t scode, const char *arg, int value,
     case OPT_ffreestanding:
       value = !value;
       /* Fall through....  */
+      gcc_fallthrough ();
     case OPT_fhosted:
       flag_hosted = value;
       flag_no_builtin = !value;
@@ -479,6 +480,7 @@ c_common_handle_option (size_t scode, const char *arg, int value,
       if (value)
 	value = 2;
       /* Fall Through.  */
+      gcc_fallthrough ();
 
     case OPT_ftrack_macro_expansion_:
       if (arg && *arg != '\0')
diff --git gcc/gcc/c-family/c-pragma.c gcc/gcc/c-family/c-pragma.c
index 277bc56..6d38358 100644
--- gcc/gcc/c-family/c-pragma.c
+++ gcc/gcc/c-family/c-pragma.c
@@ -214,6 +214,8 @@ handle_pragma_pack (cpp_reader * ARG_UNUSED (dummy))
 	    align = maximum_field_alignment;
 	    break;
 	  }
+	/* XXX Really fallthru?  */
+	gcc_fallthrough ();
       default:
 	GCC_BAD2 ("alignment must be a small power of two, not %d", align);
       }
diff --git gcc/gcc/c-family/c-pretty-print.c gcc/gcc/c-family/c-pretty-print.c
index 704d21d..c9ff725 100644
--- gcc/gcc/c-family/c-pretty-print.c
+++ gcc/gcc/c-family/c-pretty-print.c
@@ -1643,6 +1643,7 @@ c_pretty_printer::postfix_expression (tree e)
     case COMPOUND_LITERAL_EXPR:
       e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
       /* Fall through.  */
+      gcc_fallthrough ();
     case CONSTRUCTOR:
       initializer (e);
       break;
@@ -1663,6 +1664,7 @@ c_pretty_printer::postfix_expression (tree e)
 	  break;
 	}
       /* else fall through.  */
+      gcc_fallthrough ();
 
     default:
       primary_expression (e);
diff --git gcc/gcc/c-family/cilk.c gcc/gcc/c-family/cilk.c
index 8f34cd6..87ba9f6 100644
--- gcc/gcc/c-family/cilk.c
+++ gcc/gcc/c-family/cilk.c
@@ -1096,6 +1096,7 @@ extract_free_variables (tree t, struct wrapper_data *wd,
     case RESULT_DECL:
       if (wd->type != CILK_BLOCK_SPAWN)
 	TREE_ADDRESSABLE (t) = 1;
+      gcc_fallthrough ();
     case VAR_DECL:
     case PARM_DECL:
       if (!is_global_var (t))

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: c/
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
  2016-07-11 19:46 ` Implement -Wswitch-fallthrough: core Marek Polacek
  2016-07-11 19:50 ` Implement -Wswitch-fallthrough: c-family/ Marek Polacek
@ 2016-07-11 19:50 ` Marek Polacek
  2016-07-11 19:51 ` Implement -Wswitch-fallthrough: cp/ Marek Polacek
                   ` (26 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:50 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* c-array-notation.c (expand_array_notations): Add gcc_fallthrough.
	* c-decl.c (pop_scope): Likewise.
	(grokdeclarator): Likewise.
	(get_parm_info): Likewise.
	* c-objc-common.c (c_tree_printer): Likewise.
	* c-parser.c (c_parser_external_declaration): Likewise.
	(c_parser_declspecs): Likewise.
	(c_parser_statement_after_labels): Likewise.
	(c_parser_postfix_expression): Likewise.
	(c_parser_check_literal_zero): Likewise.
	(c_parser_omp_variable_list): Likewise.
	(c_parser_omp_for_loop): Likewise.
	* c-typeck.c (composite_type): Likewise.
	(build_unary_op): Likewise.
	(c_mark_addressable): Likewise.
	(build_binary_op): Likewise.
	(c_finish_omp_clauses): Likewise.

diff --git gcc/gcc/c/c-array-notation.c gcc/gcc/c/c-array-notation.c
index c7cf66a..cf91b21 100644
--- gcc/gcc/c/c-array-notation.c
+++ gcc/gcc/c/c-array-notation.c
@@ -1303,6 +1303,7 @@ expand_array_notations (tree *tp, int *walk_subtrees, void *)
 	 A[x:y];
 	 Replace those with just void zero node.  */
       *tp = void_node;
+      gcc_fallthrough ();
     default:
       break;
     }
diff --git gcc/gcc/c/c-decl.c gcc/gcc/c/c-decl.c
index 8b966fe..d3d3bda 100644
--- gcc/gcc/c/c-decl.c
+++ gcc/gcc/c/c-decl.c
@@ -1284,6 +1284,7 @@ pop_scope (void)
 	    }
 
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case TYPE_DECL:
 	case CONST_DECL:
 	common_symbol:
@@ -1329,6 +1330,7 @@ pop_scope (void)
 	    }
 
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	  /* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have
 	     already been put there by store_parm_decls.  Unused-
 	     parameter warnings are handled by function.c.
@@ -5564,6 +5566,7 @@ grokdeclarator (const struct c_declarator *declarator,
 	case cdk_array:
 	  loc = decl->id_loc;
 	  /* FALL THRU.  */
+	  gcc_fallthrough ();
 
 	case cdk_function:
 	case cdk_pointer:
@@ -7250,6 +7253,7 @@ get_parm_info (bool ellipsis, tree expr)
 	  DECL_CHAIN (decl) = others;
 	  others = decl;
 	  /* fall through */
+	  gcc_fallthrough ();
 
 	case ERROR_MARK:
 	set_shadowed:
diff --git gcc/gcc/c/c-objc-common.c gcc/gcc/c/c-objc-common.c
index 20dc024..21c0e2c 100644
--- gcc/gcc/c/c-objc-common.c
+++ gcc/gcc/c/c-objc-common.c
@@ -112,6 +112,7 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
 	    }
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 'F':
       if (DECL_NAME (t))
diff --git gcc/gcc/c/c-parser.c gcc/gcc/c/c-parser.c
index 1a50dea..0a33728 100644
--- gcc/gcc/c/c-parser.c
+++ gcc/gcc/c/c-parser.c
@@ -1546,6 +1546,7 @@ c_parser_external_declaration (c_parser *parser)
 	}
       /* Else fall through, and yield a syntax error trying to parse
 	 as a declaration or function definition.  */
+      gcc_fallthrough ();
     default:
     decl_or_fndef:
       /* A declaration or a function definition (or, in Objective-C,
@@ -2517,6 +2518,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
 	  if (!auto_type_ok)
 	    goto out;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case RID_UNSIGNED:
 	case RID_LONG:
 	case RID_SHORT:
@@ -5339,6 +5341,7 @@ c_parser_statement_after_labels (c_parser *parser, bool *if_p,
     default:
     expr_stmt:
       stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
+      gcc_fallthrough ();
     expect_semicolon:
       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
       break;
@@ -8174,6 +8177,7 @@ c_parser_postfix_expression (c_parser *parser)
 	  break;
 	}
       /* Else fall through to report error.  */
+      gcc_fallthrough ();
     default:
       c_parser_error (parser, "expected expression");
       expr.set_error ();
@@ -8578,6 +8582,7 @@ c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
 	  && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
 	      || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
 	*literal_zero_mask |= 1U << idx;
+      gcc_fallthrough ();
     default:
       break;
     }
@@ -10672,6 +10677,7 @@ c_parser_omp_variable_list (c_parser *parser,
 		  break;
 		}
 	      /* FALLTHROUGH  */
+	      gcc_fallthrough ();
 	    case OMP_CLAUSE_MAP:
 	    case OMP_CLAUSE_FROM:
 	    case OMP_CLAUSE_TO:
@@ -10693,6 +10699,7 @@ c_parser_omp_variable_list (c_parser *parser,
 		  t = build_component_ref (op_loc, t, ident, comp_loc);
 		}
 	      /* FALLTHROUGH  */
+	      gcc_fallthrough ();
 	    case OMP_CLAUSE_DEPEND:
 	    case OMP_CLAUSE_REDUCTION:
 	      while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
@@ -14394,6 +14401,7 @@ restart:
       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
 	code = OMP_ATOMIC_CAPTURE_OLD;
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case PREINCREMENT_EXPR:
       lhs = TREE_OPERAND (lhs, 0);
       unfolded_lhs = NULL_TREE;
@@ -14405,6 +14413,7 @@ restart:
       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
 	code = OMP_ATOMIC_CAPTURE_OLD;
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case PREDECREMENT_EXPR:
       lhs = TREE_OPERAND (lhs, 0);
       unfolded_lhs = NULL_TREE;
@@ -14423,6 +14432,7 @@ restart:
 	/* Undo effects of boolean_increment for post {in,de}crement.  */
 	lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
     case MODIFY_EXPR:
       if (TREE_CODE (lhs) == MODIFY_EXPR
 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
@@ -14458,6 +14468,7 @@ restart:
 	    }
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     default:
       if (!lvalue_p (unfolded_lhs))
 	lhs = non_lvalue (lhs);
@@ -14863,6 +14874,7 @@ c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
 	      if (code == CILK_SIMD || code == CILK_FOR)
 		break;
 	      /* FALLTHRU.  */
+	      gcc_fallthrough ();
 	    default:
 	      /* Can't be cond = error_mark_node, because we want to preserve
 		 the location until c_finish_omp_for.  */
diff --git gcc/gcc/c/c-typeck.c gcc/gcc/c/c-typeck.c
index bafd0d2..4c1d775 100644
--- gcc/gcc/c/c-typeck.c
+++ gcc/gcc/c/c-typeck.c
@@ -607,6 +607,7 @@ composite_type (tree t1, tree t2)
 	t1 = qualify_type (t1, t2);
 	/* ... falls through ...  */
       }
+    gcc_fallthrough ();
 
     default:
       return build_type_attribute_variant (t1, attributes);
@@ -4494,6 +4495,7 @@ build_unary_op (location_t location,
 	    }
 
 	  /* ... fall through ...  */
+	  gcc_fallthrough ();
 
 	case ARRAY_REF:
 	  if (TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (TREE_OPERAND (arg, 0))))
@@ -4512,6 +4514,7 @@ build_unary_op (location_t location,
 			    "address of array with reverse scalar storage "
 			    "order requested");
 	    }
+	  gcc_fallthrough ();
 
 	default:
 	  break;
@@ -4696,9 +4699,11 @@ c_mark_addressable (tree exp)
 	  }
 
 	/* drops in */
+	gcc_fallthrough ();
       case FUNCTION_DECL:
 	TREE_ADDRESSABLE (x) = 1;
 	/* drops out */
+	gcc_fallthrough ();
       default:
 	return true;
     }
@@ -11464,6 +11469,7 @@ build_binary_op (location_t location, enum tree_code code,
 		  op1 = c_save_expr (op1);
 		  imag = build2 (resultcode, real_type, imag, op1);
 		  /* Fall through.  */
+		  gcc_fallthrough ();
 		case PLUS_EXPR:
 		case MINUS_EXPR:
 		  real = build2 (resultcode, real_type, real, op1);
@@ -11485,6 +11491,7 @@ build_binary_op (location_t location, enum tree_code code,
 		  op0 = c_save_expr (op0);
 		  imag = build2 (resultcode, real_type, op0, imag);
 		  /* Fall through.  */
+		  gcc_fallthrough ();
 		case PLUS_EXPR:
 		  real = build2 (resultcode, real_type, op0, real);
 		  break;
@@ -12944,6 +12951,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 
 	check_dup_generic:
 	  t = OMP_CLAUSE_DECL (c);
+	  gcc_fallthrough ();
 	check_dup_generic_t:
 	  if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
 	    {

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: cp/
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (2 preceding siblings ...)
  2016-07-11 19:50 ` Implement -Wswitch-fallthrough: c/ Marek Polacek
@ 2016-07-11 19:51 ` Marek Polacek
  2016-07-11 19:52 ` Implement -Wswitch-fallthrough: fortran/ Marek Polacek
                   ` (25 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:51 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* call.c (add_builtin_candidate): Add gcc_fallthrough.
	(add_builtin_candidates): Likewise.
	(build_integral_nontype_arg_conv): Likewise.
	(build_new_op_1): Likewise.
	(convert_like_real): Likewise.
	* cfns.h (libc_name::hash): Likewise.
	* class.c (fixed_type_or_null): Likewise.
	(instantiate_type): Likewise.
	* constexpr.c (cxx_eval_constant_expression): Likewise.
	(potential_constant_expression_1): Likewise.
	* cp-gimplify.c (cp_gimplify_expr): Likewise.
	(cp_genericize_r): Likewise.
	(cp_fold): Likewise.
	* cp-ubsan.c (cp_ubsan_check_member_access_r): Likewise.
	* cvt.c (build_expr_type_conversion): Likewise.
	* cxx-pretty-print.c (pp_cxx_unqualified_id): Likewise.
	(pp_cxx_qualified_id): Likewise.
	(cxx_pretty_printer::constant): Likewise.
	(cxx_pretty_printer::primary_expression): Likewise.
	(cxx_pretty_printer::unary_expression): Likewise.
	(pp_cxx_pm_expression): Likewise.
	(cxx_pretty_printer::expression): Likewise.
	(cxx_pretty_printer::function_specifier): Likewise.
	(cxx_pretty_printer::declaration_specifiers): Likewise.
	(pp_cxx_type_specifier_seq): Likewise.
	(pp_cxx_ptr_operator): Likewise.
	* decl.c (grokdeclarator): Likewise.
	* decl2.c (coerce_new_type): Likewise.
	(coerce_delete_type): Likewise.
	* dump.c (cp_dump_tree): Likewise.
	* error.c (dump_type): Likewise.
	(dump_type_prefix): Likewise.
	(dump_type_suffix): Likewise.
	(dump_decl): Likewise.
	(dump_expr): Likewise.
	* expr.c (cplus_expand_constant): Likewise.
	* mangle.c (write_type): Likewise.
	(write_expression): Likewise.
	* method.c (synthesized_method_walk): Likewise.
	* name-lookup.c (begin_scope): Likewise.
	(arg_assoc_type): Likewise.
	* parser.c (cp_lexer_print_token): Likewise.
	(cp_parser_skip_to_end_of_statement): Likewise.
	(cp_parser_primary_expression): Likewise.
	(cp_parser_id_expression): Likewise.
	(cp_parser_unqualified_id): Likewise.
	(cp_parser_unary_expression): Likewise.
	(cp_parser_builtin_offsetof): Likewise.
	(cp_parser_jump_statement): Likewise.
	(cp_parser_storage_class_specifier_opt): Likewise.
	(cp_parser_operator): Likewise.
	(cp_parser_type_specifier): Likewise.
	(cp_parser_skip_to_end_of_template_parameter_list): Likewise.
	(cp_parser_cache_defarg): Likewise.
	(cp_parser_objc_declaration): Likewise.
	(cp_parser_omp_var_list_no_open): Likewise.
	(cp_parser_omp_atomic): Likewise.
	(cp_parser_omp_for_cond): Likewise.
	* pt.c (check_explicit_specialization): Likewise.
	(find_parameter_packs_r): Likewise.
	(coerce_template_template_parm): Likewise.
	(for_each_template_parm_r): Likewise.
	(tsubst_aggr_type): Likewise.
	(tsubst_copy): Likewise.
	(tsubst_omp_clauses): Likewise.
	(tsubst_omp_for_iterator): Likewise.
	(tsubst_expr): Likewise.
	(tsubst_copy_and_build): Likewise.
	(unify): Likewise.
	(value_dependent_expression_p): Likewise.
	* rtti.c (build_dynamic_cast_1): Likewise.
	(involves_incomplete_p): Likewise.
	* gcc/cp/semantics.c (finish_omp_clauses): Likewise.
	(finish_decltype_type): Likewise.
	* tree.c (lvalue_kind): Likewise.
	(strip_typedefs_expr): Likewise.
	(no_linkage_check): Likewise.
	(bot_manip): Likewise.
	* typeck.c (structural_comptypes): Likewise.
	(is_bitfield_expr_with_lowered_type): Likewise.
	(cp_build_binary_op): Likewise.
	(cp_build_addr_expr_1): Likewise.
	(cxx_mark_addressable): Likewise.
	(cp_build_modify_expr): Likewise.
	* typeck2.c (split_nonconstant_init_1): Likewise.

diff --git gcc/gcc/cp/call.c gcc/gcc/cp/call.c
index d77092b..4e8d89b 100644
--- gcc/gcc/cp/call.c
+++ gcc/gcc/cp/call.c
@@ -2418,6 +2418,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
     case PREDECREMENT_EXPR:
       if (TREE_CODE (type1) == BOOLEAN_TYPE)
 	return;
+      gcc_fallthrough ();
     case POSTINCREMENT_EXPR:
     case PREINCREMENT_EXPR:
       if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1))
@@ -2454,6 +2455,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
     case UNARY_PLUS_EXPR: /* unary + */
       if (TYPE_PTR_P (type1))
 	break;
+      gcc_fallthrough ();
     case NEGATE_EXPR:
       if (ARITHMETIC_TYPE_P (type1))
 	break;
@@ -2539,6 +2541,8 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
 	  type2 = ptrdiff_type_node;
 	  break;
 	}
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case MULT_EXPR:
     case TRUNC_DIV_EXPR:
       if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
@@ -2561,6 +2565,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case LT_EXPR:
     case GT_EXPR:
     case LE_EXPR:
@@ -2591,6 +2596,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
     case PLUS_EXPR:
       if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
 	break;
+      gcc_fallthrough ();
     case ARRAY_REF:
       if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && TYPE_PTROB_P (type2))
 	{
@@ -2671,6 +2677,8 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
 	      type2 = ptrdiff_type_node;
 	      break;
 	    }
+	  /* XXX Really fallthru?  */
+	  gcc_fallthrough ();
 	case MULT_EXPR:
 	case TRUNC_DIV_EXPR:
 	  if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
@@ -2899,6 +2907,8 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
     case GE_EXPR:
       enum_p = 1;
       /* Fall through.  */
+      gcc_fallthrough ();
+
 
     default:
       ref1 = 0;
@@ -3952,6 +3962,7 @@ build_integral_nontype_arg_conv (tree type, tree expr, tsubst_flags_t complain)
 	  error_at (loc, "conversion from %qT to %qT not considered for "
 		    "non-type template argument", t, type);
 	/* and fall through.  */
+	gcc_fallthrough ();
 
       default:
 	conv = NULL;
@@ -5477,6 +5488,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
     case MODIFY_EXPR:
       if (code2 != NOP_EXPR)
 	break;
+      gcc_fallthrough ();
     case COMPONENT_REF:
     case ARRAY_REF:
       memonly = true;
@@ -5821,6 +5833,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
 			       code_orig_arg1, arg1,
 			       code_orig_arg2, arg2);
       /* Fall through.  */
+      gcc_fallthrough ();
     case GT_EXPR:
     case LT_EXPR:
     case GE_EXPR:
@@ -5834,6 +5847,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
       if (complain & tf_warning && warn_tautological_compare)
 	warn_tautological_cmp (loc, code, arg1, arg2);
       /* Fall through.  */
+      gcc_fallthrough ();
     case PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
@@ -6646,6 +6660,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
       if (! MAYBE_CLASS_TYPE_P (totype))
 	return expr;
       /* Else fall through.  */
+      gcc_fallthrough ();
     case ck_base:
       if (convs->kind == ck_base && !convs->need_temporary_p)
 	{
diff --git gcc/gcc/cp/cfns.h gcc/gcc/cp/cfns.h
index 9a37249..50241ca 100644
--- gcc/gcc/cp/cfns.h
+++ gcc/gcc/cp/cfns.h
@@ -96,18 +96,23 @@ libc_name::hash (register const char *str, register unsigned int len)
       default:
         hval += asso_values[(unsigned char)str[5]+1];
       /*FALLTHROUGH*/
+      gcc_fallthrough ();
       case 5:
         hval += asso_values[(unsigned char)str[4]];
       /*FALLTHROUGH*/
+      gcc_fallthrough ();
       case 4:
         hval += asso_values[(unsigned char)str[3]];
       /*FALLTHROUGH*/
+      gcc_fallthrough ();
       case 3:
         hval += asso_values[(unsigned char)str[2]];
       /*FALLTHROUGH*/
+      gcc_fallthrough ();
       case 2:
         hval += asso_values[(unsigned char)str[1]];
       /*FALLTHROUGH*/
+      gcc_fallthrough ();
       case 1:
         hval += asso_values[(unsigned char)str[0]];
         break;
diff --git gcc/gcc/cp/class.c gcc/gcc/cp/class.c
index 31fa4b0..58c88fb 100644
--- gcc/gcc/cp/class.c
+++ gcc/gcc/cp/class.c
@@ -7392,6 +7392,7 @@ fixed_type_or_null (tree instance, int *nonnull, int *cdtorp)
 	  return TREE_TYPE (TREE_TYPE (instance));
 	}
       /* fall through...  */
+      gcc_fallthrough ();
     case TARGET_EXPR:
     case PARM_DECL:
     case RESULT_DECL:
@@ -8276,6 +8277,7 @@ instantiate_type (tree lhstype, tree rhs, tsubst_flags_t complain)
       gcc_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR);
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case TEMPLATE_ID_EXPR:
       {
diff --git gcc/gcc/cp/constexpr.c gcc/gcc/cp/constexpr.c
index ba40435..3097f24 100644
--- gcc/gcc/cp/constexpr.c
+++ gcc/gcc/cp/constexpr.c
@@ -3842,6 +3842,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       if (r)
 	break;
       /* else fall through */
+      gcc_fallthrough ();
 
     case PLUS_EXPR:
     case MINUS_EXPR:
@@ -4661,6 +4662,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
 		case IFN_SUB_OVERFLOW:
 		case IFN_MUL_OVERFLOW:
 		  bail = false;
+		  gcc_fallthrough ();
 
 		default:
 		  break;
@@ -4976,6 +4978,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
       if (TYPE_P (TREE_OPERAND (t, 0)))
 	return true;
       /* else fall through.  */
+      gcc_fallthrough ();
 
     case REALPART_EXPR:
     case IMAGPART_EXPR:
@@ -5050,6 +5053,8 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
 	    }
 	  return false;
 	}
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case INIT_EXPR:
       return RECUR (TREE_OPERAND (t, 1), rval);
 
@@ -5127,6 +5132,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     case TRUTH_OR_EXPR:
     case TRUTH_ORIF_EXPR:
       tmp = boolean_false_node;
+      gcc_fallthrough ();
     truth:
       {
 	tree op = TREE_OPERAND (t, 0);
@@ -5167,6 +5173,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
     case COMPLEX_EXPR:
       want_rval = true;
       /* Fall through.  */
+      gcc_fallthrough ();
     case ARRAY_REF:
     case ARRAY_RANGE_REF:
     case MEMBER_REF:
@@ -5201,6 +5208,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
 	  return false;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case IF_STMT:
     case VEC_COND_EXPR:
       /* If the condition is a known constant, we know which of the legs we
diff --git gcc/gcc/cp/cp-gimplify.c gcc/gcc/cp/cp-gimplify.c
index 97b043a..6359b6d 100644
--- gcc/gcc/cp/cp-gimplify.c
+++ gcc/gcc/cp/cp-gimplify.c
@@ -631,6 +631,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
       if (TREE_CODE (*expr_p) != INIT_EXPR)
 	return GS_OK;
       /* Otherwise fall through.  */
+      gcc_fallthrough ();
     case MODIFY_EXPR:
     modify_expr_case:
       {
@@ -810,6 +811,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
 	  goto modify_expr_case;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
@@ -1345,6 +1347,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
 	  case OMP_CLAUSE_DEFAULT:
 	    if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
 	      omp_ctx.default_shared = true;
+	    gcc_fallthrough ();
 	  default:
 	    break;
 	  }
@@ -2006,6 +2009,7 @@ cp_fold (tree x)
 
     case VIEW_CONVERT_EXPR:
       rval_ops = false;
+      gcc_fallthrough ();
     case CONVERT_EXPR:
     case NOP_EXPR:
     case NON_LVALUE_EXPR:
@@ -2054,6 +2058,7 @@ cp_fold (tree x)
     case REALPART_EXPR:
     case IMAGPART_EXPR:
       rval_ops = false;
+      gcc_fallthrough ();
     case CONJ_EXPR:
     case FIX_TRUNC_EXPR:
     case FLOAT_EXPR:
@@ -2106,6 +2111,7 @@ cp_fold (tree x)
     case COMPOUND_EXPR:
     case MODIFY_EXPR:
       rval_ops = false;
+      gcc_fallthrough ();
     case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
     case MINUS_EXPR:
diff --git gcc/gcc/cp/cp-ubsan.c gcc/gcc/cp/cp-ubsan.c
index 9c8f6e6..0c1512f 100644
--- gcc/gcc/cp/cp-ubsan.c
+++ gcc/gcc/cp/cp-ubsan.c
@@ -210,6 +210,7 @@ cp_ubsan_check_member_access_r (tree *stmt_p, int *walk_subtrees, void *data)
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     default:
       if (ucmd->is_addr && handled_component_p (stmt))
 	{
diff --git gcc/gcc/cp/cvt.c gcc/gcc/cp/cvt.c
index 2e2bac7..e98086f 100644
--- gcc/gcc/cp/cvt.c
+++ gcc/gcc/cp/cvt.c
@@ -1664,6 +1664,7 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
 	if ((desires & WANT_NULL) && null_ptr_cst_p (expr))
 	  return expr;
 	/* else fall through...  */
+	gcc_fallthrough ();
 
       case BOOLEAN_TYPE:
 	return (desires & WANT_INT) ? expr : NULL_TREE;
diff --git gcc/gcc/cp/cxx-pretty-print.c gcc/gcc/cp/cxx-pretty-print.c
index 3b52a35..c414f00 100644
--- gcc/gcc/cp/cxx-pretty-print.c
+++ gcc/gcc/cp/cxx-pretty-print.c
@@ -139,6 +139,7 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
 
     case OVERLOAD:
       t = OVL_CURRENT (t);
+      gcc_fallthrough ();
     case VAR_DECL:
     case PARM_DECL:
     case CONST_DECL:
@@ -150,6 +151,7 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
     case USING_DECL:
     case TEMPLATE_DECL:
       t = DECL_NAME (t);
+      gcc_fallthrough ();
 
     case IDENTIFIER_NODE:
       if (t == NULL)
@@ -277,6 +279,7 @@ pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
 	 functions and some function templates.  */
     case OVERLOAD:
       t = OVL_CURRENT (t);
+      gcc_fallthrough ();
     case FUNCTION_DECL:
       if (DECL_FUNCTION_MEMBER_P (t))
 	pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
@@ -329,6 +332,7 @@ cxx_pretty_printer::constant (tree t)
 	  break;
 	}
       /* else fall through.  */
+      gcc_fallthrough ();
 
     default:
       c_pretty_printer::constant (t);
@@ -414,6 +418,7 @@ cxx_pretty_printer::primary_expression (tree t)
 
     case BASELINK:
       t = BASELINK_FUNCTIONS (t);
+      gcc_fallthrough ();
     case VAR_DECL:
     case PARM_DECL:
     case FIELD_DECL:
@@ -784,6 +789,7 @@ cxx_pretty_printer::unary_expression (tree t)
 	  break;
 	}
       /* Fall through  */
+      gcc_fallthrough ();
 
     case ALIGNOF_EXPR:
       pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
@@ -870,6 +876,7 @@ pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
 	  break;
 	}
       /* Else fall through.  */
+      gcc_fallthrough ();
     case MEMBER_REF:
     case DOTSTAR_EXPR:
       pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
@@ -1054,6 +1061,7 @@ cxx_pretty_printer::expression (tree t)
 
     case OVERLOAD:
       t = OVL_CURRENT (t);
+      gcc_fallthrough ();
     case VAR_DECL:
     case PARM_DECL:
     case FIELD_DECL:
@@ -1208,6 +1216,7 @@ cxx_pretty_printer::function_specifier (tree t)
 	pp_cxx_ws_string (this, "explicit");
       else
         c_pretty_printer::function_specifier (t);
+      gcc_fallthrough ();
 
     default:
       break;
@@ -1250,8 +1259,11 @@ cxx_pretty_printer::declaration_specifiers (tree t)
       else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
 	declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
       else
-	default:
-        c_pretty_printer::declaration_specifiers (t);
+	{
+	  gcc_fallthrough ();
+	  default:
+	  c_pretty_printer::declaration_specifiers (t);
+	}
       break;
     }
 }
@@ -1348,6 +1360,7 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
 	  break;
 	}
       /* else fall through */
+      gcc_fallthrough ();
 
     default:
       if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
@@ -1389,6 +1402,7 @@ pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
 	  pp_star (pp);
 	  break;
 	}
+      gcc_fallthrough ();
     case OFFSET_TYPE:
       if (TYPE_PTRMEM_P (t))
 	{
@@ -1400,6 +1414,7 @@ pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
 	  break;
 	}
       /* else fall through.  */
+      gcc_fallthrough ();
 
     default:
       pp_unsupported_tree (pp, t);
diff --git gcc/gcc/cp/decl.c gcc/gcc/cp/decl.c
index c86a131..505ee12 100644
--- gcc/gcc/cp/decl.c
+++ gcc/gcc/cp/decl.c
@@ -9446,6 +9446,7 @@ grokdeclarator (const cp_declarator *declarator,
 		    }
 		}
 		/* Fall through.  */
+		gcc_fallthrough ();
 
 	      case IDENTIFIER_NODE:
 		if (identifier_p (decl))
diff --git gcc/gcc/cp/decl2.c gcc/gcc/cp/decl2.c
index 22f9ede..64b1d0d 100644
--- gcc/gcc/cp/decl2.c
+++ gcc/gcc/cp/decl2.c
@@ -1687,11 +1687,13 @@ coerce_new_type (tree type)
     case 2:
       args = tree_cons (NULL_TREE, size_type_node, args);
       /* Fall through.  */
+      gcc_fallthrough ();
     case 1:
       type = build_exception_variant
 	      (build_function_type (ptr_type_node, args),
 	       TYPE_RAISES_EXCEPTIONS (type));
       /* Fall through.  */
+      gcc_fallthrough ();
     default:;
   }
   return type;
@@ -1725,11 +1727,13 @@ coerce_delete_type (tree type)
     case 2:
       args = tree_cons (NULL_TREE, ptr_type_node, args);
       /* Fall through.  */
+      gcc_fallthrough ();
     case 1:
       type = build_exception_variant
 	      (build_function_type (void_type_node, args),
 	       TYPE_RAISES_EXCEPTIONS (type));
       /* Fall through.  */
+      gcc_fallthrough ();
     default:;
   }
 
diff --git gcc/gcc/cp/dump.c gcc/gcc/cp/dump.c
index 12c2549..d5b93c0 100644
--- gcc/gcc/cp/dump.c
+++ gcc/gcc/cp/dump.c
@@ -253,6 +253,7 @@ cp_dump_tree (void* dump_info, tree t)
 	  return true;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case UNION_TYPE:
       /* Is it a type used as a base? */
diff --git gcc/gcc/cp/error.c gcc/gcc/cp/error.c
index d5a7d0f..ab90d7d 100644
--- gcc/gcc/cp/error.c
+++ gcc/gcc/cp/error.c
@@ -451,6 +451,7 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags)
 	  break;
 	}
       /* Else fall through.  */
+      gcc_fallthrough ();
 
     case TEMPLATE_DECL:
     case NAMESPACE_DECL:
@@ -576,6 +577,7 @@ dump_type (cxx_pretty_printer *pp, tree t, int flags)
     default:
       pp_unsupported_tree (pp, t);
       /* Fall through to error.  */
+      gcc_fallthrough ();
 
     case ERROR_MARK:
       pp_string (pp, M_("<type error>"));
@@ -815,6 +817,7 @@ dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags)
     default:
       pp_unsupported_tree (pp, t);
       /* fall through.  */
+      gcc_fallthrough ();
     case ERROR_MARK:
       pp_string (pp, M_("<typeprefixerror>"));
       break;
@@ -932,6 +935,7 @@ dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
 
     default:
       pp_unsupported_tree (pp, t);
+      gcc_fallthrough ();
     case ERROR_MARK:
       /* Don't mark it here, we should have already done in
 	 dump_type_prefix.  */
@@ -1061,6 +1065,7 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
 	  break;
 	}
       /* Else fall through.  */
+      gcc_fallthrough ();
     case FIELD_DECL:
     case PARM_DECL:
       dump_simple_decl (pp, t, TREE_TYPE (t), flags);
@@ -1181,6 +1186,7 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
 	 FUNCTION_DECL.  */
       t = OVL_CURRENT (t);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case FUNCTION_DECL:
       if (! DECL_LANG_SPECIFIC (t))
@@ -1272,6 +1278,7 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
     default:
       pp_unsupported_tree (pp, t);
       /* Fall through to error.  */
+      gcc_fallthrough ();
 
     case ERROR_MARK:
       pp_string (pp, M_("<declaration error>"));
@@ -2496,6 +2503,7 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
       goto cast;
     case DYNAMIC_CAST_EXPR:
       pp_cxx_ws_string (pp, "dynamic_cast");
+      gcc_fallthrough ();
     cast:
       pp_cxx_begin_template_argument_list (pp);
       dump_type (pp, TREE_TYPE (t), flags);
@@ -2758,6 +2766,7 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
     default:
       pp_unsupported_tree (pp, t);
       /* fall through to ERROR_MARK...  */
+      gcc_fallthrough ();
     case ERROR_MARK:
       pp_string (pp, M_("<expression error>"));
       break;
diff --git gcc/gcc/cp/expr.c gcc/gcc/cp/expr.c
index e879f3c..081f62a 100644
--- gcc/gcc/cp/expr.c
+++ gcc/gcc/cp/expr.c
@@ -76,6 +76,7 @@ cplus_expand_constant (tree cst)
 	unsigned HOST_WIDE_INT idx;
 	FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt)
 	  elt->value = cplus_expand_constant (elt->value);
+	gcc_fallthrough ();
       }
 
     default:
diff --git gcc/gcc/cp/mangle.c gcc/gcc/cp/mangle.c
index 0e44409..bab20c6 100644
--- gcc/gcc/cp/mangle.c
+++ gcc/gcc/cp/mangle.c
@@ -2052,6 +2052,7 @@ write_type (tree type)
 		  break;
 		}
 	      /* else fall through.  */
+	      gcc_fallthrough ();
 	    case TEMPLATE_PARM_INDEX:
 	      write_template_param (type);
 	      break;
@@ -3074,6 +3075,7 @@ write_expression (tree expr)
 	  if (abi_warn_or_compat_version_crosses (6))
 	    G.need_abi_warning = 1;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	default:
 	  /* In the middle-end, some expressions have more operands than
diff --git gcc/gcc/cp/method.c gcc/gcc/cp/method.c
index cd8faaf..72c9717 100644
--- gcc/gcc/cp/method.c
+++ gcc/gcc/cp/method.c
@@ -1402,6 +1402,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
     case sfk_move_constructor:
     case sfk_move_assignment:
       move_p = true;
+      gcc_fallthrough ();
     case sfk_copy_constructor:
     case sfk_copy_assignment:
       copy_arg_p = true;
diff --git gcc/gcc/cp/name-lookup.c gcc/gcc/cp/name-lookup.c
index cbd5209..bcd3b92 100644
--- gcc/gcc/cp/name-lookup.c
+++ gcc/gcc/cp/name-lookup.c
@@ -1575,6 +1575,7 @@ begin_scope (scope_kind kind, tree entity)
       scope->explicit_spec_p = true;
       kind = sk_template_parms;
       /* Fall through.  */
+      gcc_fallthrough ();
     case sk_template_parms:
     case sk_block:
     case sk_try:
@@ -5547,6 +5548,7 @@ arg_assoc_type (struct arg_lookup *k, tree type)
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (type))
 	return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
+      gcc_fallthrough ();
     case UNION_TYPE:
       return arg_assoc_class (k, type);
     case POINTER_TYPE:
diff --git gcc/gcc/cp/parser.c gcc/gcc/cp/parser.c
index ef35aa9..26386fa 100644
--- gcc/gcc/cp/parser.c
+++ gcc/gcc/cp/parser.c
@@ -1258,6 +1258,7 @@ cp_lexer_print_token (FILE * stream, cp_token *token)
       if (!identifier_p (token->u.value))
 	break;
       /* else fall through */
+      gcc_fallthrough ();
     case CPP_NAME:
       fputs (IDENTIFIER_POINTER (token->u.value), stream);
       break;
@@ -3467,6 +3468,7 @@ cp_parser_skip_to_end_of_statement (cp_parser* parser)
 	      cp_lexer_consume_token (parser->lexer);
 	      return;
 	    }
+	  gcc_fallthrough ();
 
 	case CPP_OPEN_BRACE:
 	  ++nesting_depth;
@@ -5118,6 +5120,7 @@ cp_parser_primary_expression (cp_parser *parser,
 	      cp_parser_skip_to_end_of_block_or_statement (parser);
 	      return error_mark_node;
 	    }
+	  gcc_fallthrough ();
 	default:
 	  cp_parser_error (parser, "expected primary-expression");
 	  return error_mark_node;
@@ -5447,6 +5450,7 @@ cp_parser_id_expression (cp_parser *parser,
 	  if (token->keyword == RID_OPERATOR)
 	    return cp_parser_operator_function_id (parser);
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	default:
 	  cp_parser_error (parser, "expected id-expression");
@@ -5778,6 +5782,7 @@ cp_parser_unqualified_id (cp_parser* parser,
 	  return id;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       if (optional_p)
@@ -7935,6 +7940,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
 	case ADDR_EXPR:
 	   non_constant_p = NIC_ADDR;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case BIT_NOT_EXPR:
 	  expression = build_x_unary_op (loc, unary_operator,
 					 cast_expression,
@@ -7949,6 +7955,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
 	  non_constant_p = unary_operator == PREINCREMENT_EXPR
 			   ? NIC_PREINCREMENT : NIC_PREDECREMENT;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case NEGATE_EXPR:
 	  /* Immediately fold negation of a constant, unless the constant is 0
 	     (since -0 == 0) or it would overflow.  */
@@ -7967,6 +7974,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
 		}
 	    }
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case UNARY_PLUS_EXPR:
 	case TRUTH_NOT_EXPR:
 	  expression = finish_unary_op_expr (loc, unary_operator,
@@ -9410,6 +9418,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
 	  expr = grok_array_decl (token->location, expr,
 				  integer_zero_node, false);
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case CPP_DOT:
 	  /* offsetof-member-designator "." identifier */
@@ -11777,6 +11786,7 @@ cp_parser_jump_statement (cp_parser* parser)
 	  error_at (token->location,
 		    "continue statement within %<#pragma simd%> loop body");
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case IN_ITERATION_STMT:
 	case IN_OMP_FOR:
 	  statement = finish_continue_stmt ();
@@ -12854,6 +12864,7 @@ cp_parser_storage_class_specifier_opt (cp_parser* parser)
       if (cxx_dialect != cxx98)
         return NULL_TREE;
       /* Fall through for C++98.  */
+      gcc_fallthrough ();
 
     case RID_REGISTER:
     case RID_STATIC:
@@ -13973,6 +13984,7 @@ cp_parser_operator (cp_parser* parser)
     case CPP_UTF8STRING:
     case CPP_UTF8STRING_USERDEF:
       utf8 = true;
+      gcc_fallthrough ();
     case CPP_STRING:
     case CPP_WSTRING:
     case CPP_STRING16:
@@ -15854,12 +15866,14 @@ cp_parser_type_specifier (cp_parser* parser,
 	}
 
       /* Fall through.  */
+      gcc_fallthrough ();
     elaborated_type_specifier:
       /* We're declaring (not defining) a class or enum.  */
       if (declares_class_or_enum)
 	*declares_class_or_enum = 1;
 
       /* Fall through.  */
+      gcc_fallthrough ();
     case RID_TYPENAME:
       /* Look for an elaborated-type-specifier.  */
       type_spec
@@ -27083,6 +27097,7 @@ cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser)
 	    }
           /* Fall through for C++0x, so we handle the second `>' in
              the `>>'.  */
+	  gcc_fallthrough ();
 
 	case CPP_GREATER:
 	  if (!nesting_depth && level-- == 0)
@@ -27500,6 +27515,7 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
 	      parser->in_template_argument_list_p = saved_italp;
 	      break;
 	    }
+	  gcc_fallthrough ();
 	case CPP_CLOSE_PAREN:
 	case CPP_ELLIPSIS:
 	  /* If we run into a non-nested `;', `}', or `]',
@@ -27538,6 +27554,7 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
 	  /* Fall through for C++0x, which treats the `>>'
 	     operator like two `>' tokens in certain
 	     cases.  */
+	  gcc_fallthrough ();
 
 	case CPP_GREATER:
 	  if (depth == 0)
@@ -29068,6 +29085,7 @@ cp_parser_objc_declaration (cp_parser* parser, tree attributes)
 		      "prefix attributes are ignored before %<@%D%>",
 		      kwd->u.value);
 	  attributes = NULL;
+	  gcc_fallthrough ();
 	default:
 	  break;
       }
@@ -30010,6 +30028,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
 		  break;
 		}
 	      /* FALLTHROUGH.  */
+	      gcc_fallthrough ();
 	    case OMP_CLAUSE_MAP:
 	    case OMP_CLAUSE_FROM:
 	    case OMP_CLAUSE_TO:
@@ -30026,6 +30045,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
 							      &idk, loc);
 		}
 	      /* FALLTHROUGH.  */
+	      gcc_fallthrough ();
 	    case OMP_CLAUSE_DEPEND:
 	    case OMP_CLAUSE_REDUCTION:
 	      while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
@@ -32807,6 +32827,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
 	  if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
 	    goto saw_error;
 	}
+      gcc_fallthrough ();
     default:
       break;
     }
@@ -32823,6 +32844,7 @@ restart:
       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
 	code = OMP_ATOMIC_CAPTURE_OLD;
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case PREINCREMENT_EXPR:
       lhs = TREE_OPERAND (lhs, 0);
       opcode = PLUS_EXPR;
@@ -32833,6 +32855,7 @@ restart:
       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
 	code = OMP_ATOMIC_CAPTURE_OLD;
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case PREDECREMENT_EXPR:
       lhs = TREE_OPERAND (lhs, 0);
       opcode = MINUS_EXPR;
@@ -32850,6 +32873,7 @@ restart:
        /* Undo effects of boolean_increment for post {in,de}crement.  */
        lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
     case MODIFY_EXPR:
       if (TREE_CODE (lhs) == MODIFY_EXPR
 	 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
@@ -32869,6 +32893,7 @@ restart:
 	    }
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     default:
       switch (cp_lexer_peek_token (parser->lexer)->type)
 	{
@@ -33035,6 +33060,7 @@ restart:
 	    goto saw_error;
 	  goto stmt_done;
 	  /* FALLTHROUGH */
+	  gcc_fallthrough ();
 	default:
 	  cp_parser_error (parser,
 			   "invalid operator for %<#pragma omp atomic%>");
@@ -33180,6 +33206,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
       if (code == CILK_SIMD || code == CILK_FOR)
 	break;
       /* Fall through: OpenMP disallows NE_EXPR.  */
+      gcc_fallthrough ();
     default:
       return error_mark_node;
     }
diff --git gcc/gcc/cp/pt.c gcc/gcc/cp/pt.c
index c5f65a7..d667360 100644
--- gcc/gcc/cp/pt.c
+++ gcc/gcc/cp/pt.c
@@ -2689,6 +2689,7 @@ check_explicit_specialization (tree declarator,
       error ("template parameter list used in explicit instantiation");
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case tsk_expl_inst:
       if (have_def)
@@ -2709,6 +2710,7 @@ check_explicit_specialization (tree declarator,
 	      "%<template <>%>", decl);
 
       /* Fall through.  */
+      gcc_fallthrough ();
     case tsk_expl_spec:
       if (is_concept)
         error ("explicit specialization declared %<concept%>");
@@ -3453,6 +3455,7 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
 
     case TEMPLATE_TYPE_PARM:
       t = TYPE_MAIN_VARIANT (t);
+      gcc_fallthrough ();
     case TEMPLATE_TEMPLATE_PARM:
       /* If the placeholder appears in the decl-specifier-seq of a function
 	 parameter pack (14.6.3), or the type-specifier-seq of a type-id that
@@ -3540,6 +3543,7 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
       if (TYPE_PTRMEMFUNC_P (t))
 	return NULL_TREE;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case UNION_TYPE:
     case ENUMERAL_TYPE:
@@ -6748,6 +6752,7 @@ coerce_template_template_parm (tree parm,
 	  return 0;
       }
       /* Fall through.  */
+      gcc_fallthrough ();
       
     case TYPE_DECL:
       if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (arg))
@@ -8794,6 +8799,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       if (TYPE_PTRMEMFUNC_P (t))
 	break;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case UNION_TYPE:
     case ENUMERAL_TYPE:
@@ -8813,6 +8819,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
 	 explicitly here.  */
       WALK_SUBTREE (TYPE_METHOD_BASETYPE (t));
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case FUNCTION_TYPE:
       /* Check the return type.  */
@@ -8850,6 +8857,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
 	WALK_SUBTREE (DECL_TI_ARGS (t));
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case PARM_DECL:
     case CONST_DECL:
@@ -8864,6 +8872,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       /* Record template parameters such as `T' inside `TT<T>'.  */
       WALK_SUBTREE (TYPE_TI_ARGS (t));
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case TEMPLATE_TEMPLATE_PARM:
     case TEMPLATE_TYPE_PARM:
@@ -11435,6 +11444,7 @@ tsubst_aggr_type (tree t,
 	return tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl);
 
       /* Else fall through.  */
+      gcc_fallthrough ();
     case ENUMERAL_TYPE:
     case UNION_TYPE:
       if (TYPE_TEMPLATE_INFO (t) && uses_template_parms (t))
@@ -14246,6 +14256,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	  return r;
 	}
       /* Fall through */
+      gcc_fallthrough ();
 
     case INDIRECT_REF:
     case NEGATE_EXPR:
@@ -14464,6 +14475,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case USING_DECL:
       t = DECL_NAME (t);
       /* Fall through.  */
+      gcc_fallthrough ();
     case IDENTIFIER_NODE:
       if (IDENTIFIER_TYPENAME_P (t))
 	{
@@ -14621,6 +14633,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
 		= pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (nc));
 	    }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case OMP_CLAUSE_PRIVATE:
 	case OMP_CLAUSE_SHARED:
 	case OMP_CLAUSE_FIRSTPRIVATE:
@@ -14783,6 +14796,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
 			  && DECL_NAME (v) == this_identifier)
 			OMP_CLAUSE_DECL (nc) = TREE_OPERAND (t, 1);
 		      /* FALLTHRU */
+		      gcc_fallthrough ();
 		    default:
 		      v = NULL_TREE;
 		      break;
@@ -14933,6 +14947,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
 			decl = omp_privatize_field (decl, false);
 		      }
 		    /* FALLTHRU */
+		    gcc_fallthrough ();
 		  default:
 		    v = NULL_TREE;
 		    break;
@@ -15618,6 +15633,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
     case OMP_SECTIONS:
       omp_parallel_combined_clauses = NULL;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case OMP_SINGLE:
     case OMP_TEAMS:
     case OMP_CRITICAL:
@@ -16001,6 +16017,7 @@ tsubst_copy_and_build (tree t,
     case USING_DECL:
       t = DECL_NAME (t);
       /* Fall through.  */
+      gcc_fallthrough ();
     case IDENTIFIER_NODE:
       {
 	tree decl;
@@ -16294,6 +16311,7 @@ tsubst_copy_and_build (tree t,
 	  || ARGUMENT_PACK_P (TREE_OPERAND (t, 0)))
 	RETURN (tsubst_copy (t, args, complain, in_decl));
       /* Fall through */
+      gcc_fallthrough ();
       
     case ALIGNOF_EXPR:
       {
@@ -17067,6 +17085,7 @@ tsubst_copy_and_build (tree t,
 	  return RECUR (DECL_VALUE_EXPR (t));
 	}
       /* Fall through */
+      gcc_fallthrough ();
 
     case PARM_DECL:
       {
@@ -20206,12 +20225,14 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
 			strict, explain_p);
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     default:
       /* An unresolved overload is a nondeduced context.  */
       if (is_overloaded_fn (parm) || type_unknown_p (parm))
 	return unify_success (explain_p);
       gcc_assert (EXPR_P (parm));
+      gcc_fallthrough ();
     expr:
       /* We must be looking at an expression.  This can happen with
 	 something like:
@@ -22808,6 +22829,7 @@ value_dependent_expression_p (tree expression)
       if (SIZEOF_EXPR_TYPE_P (expression))
 	return dependent_type_p (TREE_TYPE (TREE_OPERAND (expression, 0)));
       /* FALLTHRU */
+      gcc_fallthrough ();
     case ALIGNOF_EXPR:
     case TYPEID_EXPR:
       /* A `sizeof' expression is value-dependent if the operand is
diff --git gcc/gcc/cp/rtti.c gcc/gcc/cp/rtti.c
index 43d5f15..2dcdcde 100644
--- gcc/gcc/cp/rtti.c
+++ gcc/gcc/cp/rtti.c
@@ -539,6 +539,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
       if (VOID_TYPE_P (TREE_TYPE (type)))
 	break;
       /* Fall through.  */
+      gcc_fallthrough ();
     case REFERENCE_TYPE:
       if (! MAYBE_CLASS_TYPE_P (TREE_TYPE (type)))
 	{
@@ -852,9 +853,11 @@ involves_incomplete_p (tree type)
       if (TYPE_PTRMEMFUNC_P (type))
 	goto ptrmem;
       /* Fall through.  */
+      gcc_fallthrough ();
     case UNION_TYPE:
       if (!COMPLETE_TYPE_P (type))
 	return true;
+      gcc_fallthrough ();
 
     default:
       /* All other types do not involve incomplete class types.  */
diff --git gcc/gcc/cp/semantics.c gcc/gcc/cp/semantics.c
index d1fb119..d3b753e 100644
--- gcc/gcc/cp/semantics.c
+++ gcc/gcc/cp/semantics.c
@@ -6007,6 +6007,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	    }
 	  else
 	    t = OMP_CLAUSE_DECL (c);
+	  gcc_fallthrough ();
 	check_dup_generic_t:
 	  if (t == current_class_ptr
 	      && (ort != C_ORT_OMP_DECLARE_SIMD
@@ -6062,6 +6063,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	    bitmap_set_bit (&generic_head, DECL_UID (t));
 	  if (!field_ok)
 	    break;
+	  gcc_fallthrough ();
 	handle_field_decl:
 	  if (!remove
 	      && TREE_CODE (t) == FIELD_DECL
@@ -6208,11 +6210,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	      OMP_CLAUSE_OPERAND (c, 1) = t;
 	    }
 	  /* Check operand 0, the num argument.  */
+	  gcc_fallthrough ();
 
 	case OMP_CLAUSE_WORKER:
 	case OMP_CLAUSE_VECTOR:
 	  if (OMP_CLAUSE_OPERAND (c, 0) == NULL_TREE)
 	    break;
+	  gcc_fallthrough ();
 
 	case OMP_CLAUSE_NUM_TASKS:
 	case OMP_CLAUSE_NUM_TEAMS:
@@ -6814,6 +6818,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 		  && TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF)
 		bitmap_set_bit (&map_field_head, DECL_UID (t));
 	    }
+	  gcc_fallthrough ();
 	handle_map_references:
 	  if (!remove
 	      && !processing_template_decl
@@ -7210,6 +7215,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
 	      continue;
 	    }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	default:
 	  pc = &OMP_CLAUSE_CHAIN (c);
 	  continue;
@@ -8875,6 +8881,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
               break;
             }
           /* Fall through for fields that aren't bitfields.  */
+	  gcc_fallthrough ();
 
         case FUNCTION_DECL:
         case VAR_DECL:
diff --git gcc/gcc/cp/tree.c gcc/gcc/cp/tree.c
index fa8db0a..d026c4a 100644
--- gcc/gcc/cp/tree.c
+++ gcc/gcc/cp/tree.c
@@ -141,11 +141,13 @@ lvalue_kind (const_tree ref)
 	 lvalues.  */
       if (! TREE_STATIC (ref))
 	return clk_none;
+      gcc_fallthrough ();
     case VAR_DECL:
       if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
 	  && DECL_LANG_SPECIFIC (ref)
 	  && DECL_IN_AGGR_P (ref))
 	return clk_none;
+      gcc_fallthrough ();
     case INDIRECT_REF:
     case ARROW_EXPR:
     case ARRAY_REF:
@@ -1708,6 +1710,7 @@ strip_typedefs_expr (tree t, bool *remove_attributes)
     case NEW_EXPR:
       type = strip_typedefs (type, remove_attributes);
       /* fallthrough */
+      gcc_fallthrough ();
 
     default:
       for (i = 0; i < n; ++i)
@@ -2343,10 +2346,12 @@ no_linkage_check (tree t, bool relaxed_p)
 	  && LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
 	return t;
       /* Fall through.  */
+      gcc_fallthrough ();
     case UNION_TYPE:
       if (!CLASS_TYPE_P (t))
 	return NULL_TREE;
       /* Fall through.  */
+      gcc_fallthrough ();
     case ENUMERAL_TYPE:
       /* Only treat anonymous types as having no linkage if they're at
 	 namespace scope.  This is core issue 966.  */
@@ -2548,6 +2553,7 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
 	  case BUILT_IN_FILE:
 	  case BUILT_IN_LINE:
 	    SET_EXPR_LOCATION (*tp, input_location);
+	    gcc_fallthrough ();
 	  default:
 	    break;
 	  }
diff --git gcc/gcc/cp/typeck.c gcc/gcc/cp/typeck.c
index fb6a16e..74f008c 100644
--- gcc/gcc/cp/typeck.c
+++ gcc/gcc/cp/typeck.c
@@ -1278,6 +1278,7 @@ structural_comptypes (tree t1, tree t2, int strict)
       /* Don't check inheritance.  */
       strict = COMPARE_STRICT;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case RECORD_TYPE:
     case UNION_TYPE:
@@ -1306,6 +1307,7 @@ structural_comptypes (tree t1, tree t2, int strict)
       if (TYPE_REF_IS_RVALUE (t1) != TYPE_REF_IS_RVALUE (t2))
 	return false;
       /* fall through to checks for pointer types */
+      gcc_fallthrough ();
 
     case POINTER_TYPE:
       if (TYPE_MODE (t1) != TYPE_MODE (t2)
@@ -1884,6 +1886,7 @@ is_bitfield_expr_with_lowered_type (const_tree exp)
 	  == TYPE_MAIN_VARIANT (TREE_TYPE (exp)))
 	return is_bitfield_expr_with_lowered_type (TREE_OPERAND (exp, 0));
       /* Fallthrough.  */
+      gcc_fallthrough ();
 
     default:
       return NULL_TREE;
@@ -4260,6 +4263,7 @@ cp_build_binary_op (location_t location,
 	}
       /* The pointer - int case is just like pointer + int; fall
 	 through.  */
+      gcc_fallthrough ();
     case PLUS_EXPR:
       if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
 	  && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
@@ -5040,6 +5044,7 @@ cp_build_binary_op (location_t location,
 		  op1 = save_expr (op1);
 		  imag = build2 (resultcode, real_type, imag, op1);
 		  /* Fall through.  */
+		  gcc_fallthrough ();
 		case PLUS_EXPR:
 		case MINUS_EXPR:
 		  real = build2 (resultcode, real_type, real, op1);
@@ -5059,6 +5064,7 @@ cp_build_binary_op (location_t location,
 		  op0 = save_expr (op0);
 		  imag = build2 (resultcode, real_type, op0, imag);
 		  /* Fall through.  */
+		  gcc_fallthrough ();
 		case PLUS_EXPR:
 		  real = build2 (resultcode, real_type, op0, real);
 		  break;
@@ -5693,6 +5699,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
     case BASELINK:
       arg = BASELINK_FUNCTIONS (arg);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case OVERLOAD:
       arg = OVL_CURRENT (arg);
@@ -6222,6 +6229,7 @@ cxx_mark_addressable (tree exp)
 	    return true;
 	  }
 	/* Fall through.  */
+      gcc_fallthrough ();
 
       case VAR_DECL:
 	/* Caller should not be trying to mark initialized
@@ -6231,6 +6239,7 @@ cxx_mark_addressable (tree exp)
 		    || TREE_STATIC (x)
 		    || DECL_EXTERNAL (x));
 	/* Fall through.  */
+      gcc_fallthrough ();
 
       case RESULT_DECL:
 	if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
@@ -7555,6 +7564,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
 		    TREE_OPERAND (lhs, 0),
 		    TREE_OPERAND (lhs, 1));
       /* Fall through.  */
+      gcc_fallthrough ();
 
       /* Handle (a ? b : c) used as an "lvalue".  */
     case COND_EXPR:
diff --git gcc/gcc/cp/typeck2.c gcc/gcc/cp/typeck2.c
index 65d91c9..47728f2 100644
--- gcc/gcc/cp/typeck2.c
+++ gcc/gcc/cp/typeck2.c
@@ -612,6 +612,7 @@ split_nonconstant_init_1 (tree dest, tree init)
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case RECORD_TYPE:
     case UNION_TYPE:

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: fortran/
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (3 preceding siblings ...)
  2016-07-11 19:51 ` Implement -Wswitch-fallthrough: cp/ Marek Polacek
@ 2016-07-11 19:52 ` Marek Polacek
  2016-07-11 19:52 ` Implement -Wswitch-fallthrough: gcc/ Marek Polacek
                   ` (24 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:52 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* arith.c (eval_intrinsic): Add gcc_fallthrough.
	* array.c (gfc_ref_dimen_size): Likewise.
	(gfc_array_dimen_size): Likewise.
	* cpp.c (gfc_cpp_handle_option): Likewise.
	(cb_cpp_error): Likewise.
	* decl.c (match_implicit_range): Likewise.
	(match_attr_spec): Likewise.
	* dependency.c (gfc_dep_resolver): Likewise.
	* dump-parse-tree.c (show_code_node): Likewise.
	* expr.c (simplify_const_ref): Likewise.
	* frontend-passes.c (optimize_op): Likewise.
	(gfc_expr_walker): Likewise.
	(gfc_code_walker): Likewise.
	* gfortranspec.c: Likewise.
	* interface.c (gfc_check_operator_interface): Likewise.
	* io.c (format_lex): Likewise.
	* openmp.c (resolve_omp_clauses): Likewise.
	* parse.c (next_fixed): Likewise.
	(parse_select_block): Likewise.
	(parse_select_type_block): Likewise.
	(parse_executable): Likewise.
	* primary.c (match_boz_constant): Likewise.
	(match_arg_list_function): Likewise.
	(gfc_match_rvalue): Likewise.
	(match_variable): Likewise.
	* resolve.c (resolve_operator): Likewise.
	(resolve_ref): Likewise.
	(fixup_charlen): Likewise.
	(resolve_allocate_expr): Likewise.
	(gfc_resolve_code): Likewise.
	(build_default_init_expr): Likewise.
	* target-memory.c (gfc_target_interpret_expr): Likewise.
	* trans-array.c (gfc_array_allocate): Likewise.
	* trans-expr.c (flatten_array_ctors_without_strlen): Likewise.
	(gfc_conv_power_op): Likewise.
	(gfc_conv_expr_op): Likewise.
	* trans-intrinsic.c (conv_caf_vector_subscript): Likewise.
	(conv_intrinsic_cobound): Likewise.
	(gfc_conv_intrinsic_len): Likewise.
	* trans-io.c (gfc_build_st_parameter): Likewise.
	(transfer_expr): Likewise.
	* trans-stmt.c (gfc_trans_where_2): Likewise.

diff --git gcc/gcc/fortran/arith.c gcc/gcc/fortran/arith.c
index 47a5504..a56b480 100644
--- gcc/gcc/fortran/arith.c
+++ gcc/gcc/fortran/arith.c
@@ -1504,6 +1504,7 @@ eval_intrinsic (gfc_intrinsic_op op,
 	}
 
     /* Fall through  */
+    gcc_fallthrough ();
     case INTRINSIC_EQ:
     case INTRINSIC_EQ_OS:
     case INTRINSIC_NE:
@@ -1523,6 +1524,7 @@ eval_intrinsic (gfc_intrinsic_op op,
 
     /* Fall through  */
     /* Numeric binary  */
+    gcc_fallthrough ();
     case INTRINSIC_PLUS:
     case INTRINSIC_MINUS:
     case INTRINSIC_TIMES:
diff --git gcc/gcc/fortran/array.c gcc/gcc/fortran/array.c
index 03c8b17..d020709 100644
--- gcc/gcc/fortran/array.c
+++ gcc/gcc/fortran/array.c
@@ -2323,6 +2323,7 @@ gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result, mpz_t *end)
 	  mpz_mul (*end, *end, stride);
 	  mpz_add (*end, *end, lower);
 	}
+      gcc_fallthrough ();
 
     cleanup:
       mpz_clear (upper);
@@ -2432,6 +2433,7 @@ gfc_array_dimen_size (gfc_expr *array, int dimen, mpz_t *result)
       }
 
       /* Fall through */
+      gcc_fallthrough ();
     default:
       if (array->shape == NULL)
 	return false;
diff --git gcc/gcc/fortran/cpp.c gcc/gcc/fortran/cpp.c
index 8ac8092..df81cbc 100644
--- gcc/gcc/fortran/cpp.c
+++ gcc/gcc/fortran/cpp.c
@@ -390,6 +390,7 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED
     case OPT_MM:
       gfc_cpp_option.deps_skip_system = 1;
       /* fall through */
+      gcc_fallthrough ();
 
     case OPT_M:
       gfc_cpp_option.deps = 1;
@@ -398,6 +399,7 @@ gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED
     case OPT_MMD:
       gfc_cpp_option.deps_skip_system = 1;
       /* fall through */
+      gcc_fallthrough ();
 
     case OPT_MD:
       gfc_cpp_option.deps = 1;
@@ -1037,6 +1039,7 @@ cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
     case CPP_DL_WARNING_SYSHDR:
       global_dc->dc_warn_system_headers = 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case CPP_DL_WARNING:
       dlevel = DK_WARNING;
       break;
diff --git gcc/gcc/fortran/decl.c gcc/gcc/fortran/decl.c
index 1b62833..3d6b7e4 100644
--- gcc/gcc/fortran/decl.c
+++ gcc/gcc/fortran/decl.c
@@ -3486,6 +3486,7 @@ match_implicit_range (void)
 	{
 	case ')':
 	  inner = 0;		/* Fall through.  */
+	  gcc_fallthrough ();
 
 	case ',':
 	  c2 = c1;
@@ -3911,6 +3912,7 @@ match_attr_spec (void)
 		      d = DECL_CODIMENSION;
 		      break;
 		    }
+		  gcc_fallthrough ();
 		case 'n':
 		  if (match_string_p ("tiguous"))
 		    {
diff --git gcc/gcc/fortran/dependency.c gcc/gcc/fortran/dependency.c
index f117de0..207825e 100644
--- gcc/gcc/fortran/dependency.c
+++ gcc/gcc/fortran/dependency.c
@@ -2199,6 +2199,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
 
 	      /* Overlap codes are in order of priority.  We only need to
 		 know the worst one.*/
+	      gcc_fallthrough ();
 
 	    update_fin_dep:
 	      if (this_dep > fin_dep)
diff --git gcc/gcc/fortran/dump-parse-tree.c gcc/gcc/fortran/dump-parse-tree.c
index f507434..1170948 100644
--- gcc/gcc/fortran/dump-parse-tree.c
+++ gcc/gcc/fortran/dump-parse-tree.c
@@ -1617,6 +1617,7 @@ show_code_node (int level, gfc_code *c)
     case EXEC_ERROR_STOP:
       fputs ("ERROR ", dumpfile);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case EXEC_STOP:
       fputs ("STOP ", dumpfile);
@@ -2162,6 +2163,7 @@ show_code_node (int level, gfc_code *c)
 
     case EXEC_FLUSH:
       fputs ("FLUSH", dumpfile);
+      gcc_fallthrough ();
 
     show_filepos:
       fp = c->ext.filepos;
@@ -2378,6 +2380,7 @@ show_code_node (int level, gfc_code *c)
 
     case EXEC_WRITE:
       fputs ("WRITE", dumpfile);
+      gcc_fallthrough ();
 
     show_dt:
       dt = c->ext.dt;
@@ -2468,6 +2471,7 @@ show_code_node (int level, gfc_code *c)
 	  fputs (" SIGN=", dumpfile);
 	  show_expr (dt->sign);
 	}
+      gcc_fallthrough ();
 
     show_dt_code:
       for (c = c->block->next; c; c = c->next)
diff --git gcc/gcc/fortran/expr.c gcc/gcc/fortran/expr.c
index 7328898..8557ff7 100644
--- gcc/gcc/fortran/expr.c
+++ gcc/gcc/fortran/expr.c
@@ -1646,6 +1646,7 @@ simplify_const_ref (gfc_expr *p)
 	      p->ref->u.ar.type = AR_FULL;
 
 	    /* Fall through.  */
+	    gcc_fallthrough ();
 
 	    case AR_FULL:
 	      if (p->ref->next != NULL
diff --git gcc/gcc/fortran/frontend-passes.c gcc/gcc/fortran/frontend-passes.c
index f02a52a..652ec89 100644
--- gcc/gcc/fortran/frontend-passes.c
+++ gcc/gcc/fortran/frontend-passes.c
@@ -1445,6 +1445,7 @@ optimize_op (gfc_expr *e)
       changed = optimize_comparison (e, op);
 
       /* Fall through */
+      gcc_fallthrough ();
       /* Look at array constructors.  */
     case INTRINSIC_PLUS:
     case INTRINSIC_MINUS:
@@ -3312,6 +3313,7 @@ gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
 
 	    /* Fall through to the variable case in order to walk the
 	       reference.  */
+	    gcc_fallthrough ();
 
 	  case EXPR_SUBSTRING:
 	  case EXPR_VARIABLE:
@@ -3345,6 +3347,7 @@ gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
 		    break;
 		  }
 	      }
+	    gcc_fallthrough ();
 
 	  default:
 	    break;
@@ -3600,6 +3603,7 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
 	      in_omp_workshare = true;
 
 	      /* Fall through  */
+	      gcc_fallthrough ();
 
 	    case EXEC_OMP_DISTRIBUTE:
 	    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
diff --git gcc/gcc/fortran/gfortranspec.c gcc/gcc/fortran/gfortranspec.c
index 8a0e19a..a09b167 100644
--- gcc/gcc/fortran/gfortranspec.c
+++ gcc/gcc/fortran/gfortranspec.c
@@ -395,10 +395,12 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
 	case 0:
 	  add_arg_libgfortran (static_lib && !static_linking);
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case 1:
 	  if (need_math)
 	    append_option (OPT_l, MATH_LIBRARY, 1);
+	  gcc_fallthrough ();
 	default:
 	  break;
 	}
diff --git gcc/gcc/fortran/interface.c gcc/gcc/fortran/interface.c
index 5bd1279..736112c 100644
--- gcc/gcc/fortran/interface.c
+++ gcc/gcc/fortran/interface.c
@@ -930,6 +930,7 @@ gfc_check_operator_interface (gfc_symbol *sym, gfc_intrinsic_op op,
       if (t1 == BT_CHARACTER && t2 == BT_CHARACTER)
 	goto bad_repl;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case INTRINSIC_PLUS:
     case INTRINSIC_MINUS:
diff --git gcc/gcc/fortran/io.c gcc/gcc/fortran/io.c
index 7c648e9..7b6f00f 100644
--- gcc/gcc/fortran/io.c
+++ gcc/gcc/fortran/io.c
@@ -242,6 +242,7 @@ format_lex (void)
     case '-':
       negative_flag = 1;
       /* Falls through.  */
+      gcc_fallthrough ();
 
     case '+':
       c = next_char_not_space (&error);
diff --git gcc/gcc/fortran/openmp.c gcc/gcc/fortran/openmp.c
index 865e0d9..cb08879 100644
--- gcc/gcc/fortran/openmp.c
+++ gcc/gcc/fortran/openmp.c
@@ -3762,6 +3762,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
 			gfc_error ("Cray pointee object %qs in %s clause at %L",
 				   n->sym->name, name, &n->where);
 		      /* FALLTHRU */
+		      gcc_fallthrough ();
 		  case OMP_LIST_DEVICE_RESIDENT:
 		    check_symbol_not_pointer (n->sym, n->where, name);
 		    check_array_not_assumed (n->sym, n->where, name);
diff --git gcc/gcc/fortran/parse.c gcc/gcc/fortran/parse.c
index d795225..65e7b8d 100644
--- gcc/gcc/fortran/parse.c
+++ gcc/gcc/fortran/parse.c
@@ -1235,6 +1235,7 @@ next_fixed (void)
 		}
 	    }
 	  /* FALLTHROUGH */
+	  gcc_fallthrough ();
 
 	  /* Comments have already been skipped by the time we get
 	     here so don't bother checking for them.  */
@@ -3609,6 +3610,7 @@ loop:
 	break;
 
       /* Fall through */
+      gcc_fallthrough ();
 
     case ST_USE:
     case ST_IMPORT:
@@ -3672,6 +3674,7 @@ declSt:
 	      break;
 	    }
 
+	  gcc_fallthrough ();
 	default:
 	  break;
 	}
@@ -4007,6 +4010,7 @@ parse_select_block (void)
 
 	  accept_statement (st);
 	  /* Fall through */
+	  gcc_fallthrough ();
 
 	case ST_END_SELECT:
 	  break;
@@ -4091,6 +4095,7 @@ parse_select_type_block (void)
 
 	  accept_statement (st);
 	  /* Fall through */
+	  gcc_fallthrough ();
 
 	case ST_END_SELECT:
 	  break;
@@ -5103,6 +5108,7 @@ parse_executable (gfc_statement st)
 	  gfc_notify_std (GFC_STD_F95_OBS, "DATA statement at %C after the "
 			  "first executable statement");
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case ST_FORMAT:
 	case ST_ENTRY:
diff --git gcc/gcc/fortran/primary.c gcc/gcc/fortran/primary.c
index c2faa0f..141cd86 100644
--- gcc/gcc/fortran/primary.c
+++ gcc/gcc/fortran/primary.c
@@ -366,12 +366,14 @@ match_boz_constant (gfc_expr **result)
     case 'x':
       x_hex = 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case 'z':
       radix = 16;
       post = 0;
       break;
     case '\'':
       /* Fall through.  */
+      gcc_fallthrough ();
     case '\"':
       delim = post;
       post = 1;
@@ -1686,18 +1688,21 @@ match_arg_list_function (gfc_actual_arglist *result)
 	      result->name = "%LOC";
 	      break;
 	    }
+	  gcc_fallthrough ();
 	case 'r':
 	  if (strncmp (name, "ref", 3) == 0)
 	    {
 	      result->name = "%REF";
 	      break;
 	    }
+	  gcc_fallthrough ();
 	case 'v':
 	  if (strncmp (name, "val", 3) == 0)
 	    {
 	      result->name = "%VAL";
 	      break;
 	    }
+	  gcc_fallthrough ();
 	default:
 	  m = MATCH_ERROR;
 	  goto cleanup;
@@ -3007,6 +3012,7 @@ gfc_match_rvalue (gfc_expr **result)
 	  m = gfc_match_varspec (e, 0, false, true);
 	  break;
 	}
+      gcc_fallthrough ();
 
     /* Match a function reference.  */
     function0:
@@ -3412,6 +3418,7 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag)
 	break;
 
       /* Fall through to error */
+      gcc_fallthrough ();
 
     default:
       gfc_error ("%qs at %C is not a variable", sym->name);
diff --git gcc/gcc/fortran/resolve.c gcc/gcc/fortran/resolve.c
index 4378313..debcd9e 100644
--- gcc/gcc/fortran/resolve.c
+++ gcc/gcc/fortran/resolve.c
@@ -3543,6 +3543,7 @@ resolve_operator (gfc_expr *e)
 	return false;
 
     /* Fall through...  */
+    gcc_fallthrough ();
 
     case INTRINSIC_NOT:
     case INTRINSIC_UPLUS:
@@ -3661,6 +3662,7 @@ resolve_operator (gfc_expr *e)
 	}
 
       /* Fall through...  */
+      gcc_fallthrough ();
 
     case INTRINSIC_EQ:
     case INTRINSIC_EQ_OS:
@@ -4688,6 +4690,7 @@ resolve_ref (gfc_expr *expr)
 		  break;
 		}
 	      /* Fall through.  */
+	      gcc_fallthrough ();
 	    case AR_SECTION:
 	      current_part_dimension = 1;
 	      break;
@@ -5419,14 +5422,17 @@ fixup_charlen (gfc_expr *e)
     {
     case EXPR_OP:
       gfc_resolve_character_operator (e);
+      gcc_fallthrough ();
 
     case EXPR_ARRAY:
       if (e->expr_type == EXPR_ARRAY)
 	gfc_resolve_character_array_constructor (e);
+      gcc_fallthrough ();
 
     case EXPR_SUBSTRING:
       if (!e->ts.u.cl && e->ref)
 	gfc_resolve_substring_charlen (e);
+      gcc_fallthrough ();
 
     default:
       if (!e->ts.u.cl)
@@ -7279,6 +7285,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code, bool *array_alloc_wo_spec)
 	    break;
 
 	  /* Fall Through...  */
+	  gcc_fallthrough ();
 
 	case DIMEN_UNKNOWN:
 	case DIMEN_VECTOR:
@@ -10432,6 +10439,7 @@ gfc_resolve_code (gfc_code *code, gfc_namespace *ns)
 	      omp_workshare_save = omp_workshare_flag;
 	      omp_workshare_flag = 1;
 	      /* FALL THROUGH */
+	      gcc_fallthrough ();
 	    default:
 	      gfc_resolve_blocks (code->block, ns);
 	      break;
@@ -11183,6 +11191,7 @@ build_default_init_expr (gfc_symbol *sym)
 	case GFC_INIT_REAL_SNAN:
 	  init_expr->is_snan = 1;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case GFC_INIT_REAL_NAN:
 	  mpfr_set_nan (init_expr->value.real);
 	  break;
@@ -11212,6 +11221,7 @@ build_default_init_expr (gfc_symbol *sym)
 	case GFC_INIT_REAL_SNAN:
 	  init_expr->is_snan = 1;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case GFC_INIT_REAL_NAN:
 	  mpfr_set_nan (mpc_realref (init_expr->value.complex));
 	  mpfr_set_nan (mpc_imagref (init_expr->value.complex));
diff --git gcc/gcc/fortran/target-memory.c gcc/gcc/fortran/target-memory.c
index 0c71c3c..ee1bd73 100644
--- gcc/gcc/fortran/target-memory.c
+++ gcc/gcc/fortran/target-memory.c
@@ -600,6 +600,7 @@ gfc_target_interpret_expr (unsigned char *buffer, size_t buffer_size,
     case BT_CLASS:
       result->ts = CLASS_DATA (result)->ts;
       /* Fall through.  */
+      gcc_fallthrough ();
     case BT_DERIVED:
       result->representation.length =
         gfc_interpret_derived (buffer, buffer_size, result);
diff --git gcc/gcc/fortran/trans-array.c gcc/gcc/fortran/trans-array.c
index e95c8dd..81c523d 100644
--- gcc/gcc/fortran/trans-array.c
+++ gcc/gcc/fortran/trans-array.c
@@ -4031,6 +4031,7 @@ done:
 		    continue;
 		  }
 		  /* Otherwise fall through GFC_SS_FUNCTION.  */
+		  gcc_fallthrough ();
 	      }
 	    case GFC_ISYM_LCOBOUND:
 	    case GFC_ISYM_UCOBOUND:
@@ -4040,6 +4041,7 @@ done:
 	    default:
 	      continue;
 	    }
+	  gcc_fallthrough ();
 
 	case GFC_SS_CONSTRUCTOR:
 	case GFC_SS_FUNCTION:
@@ -5451,6 +5453,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case AR_SECTION:
       lower = ref->u.ar.start;
diff --git gcc/gcc/fortran/trans-expr.c gcc/gcc/fortran/trans-expr.c
index b5731aa..54ad600 100644
--- gcc/gcc/fortran/trans-expr.c
+++ gcc/gcc/fortran/trans-expr.c
@@ -2102,6 +2102,7 @@ flatten_array_ctors_without_strlen (gfc_expr* e)
 	}
 
       /* Otherwise, fall through to handle constructor elements.  */
+      gcc_fallthrough ();
     case EXPR_STRUCTURE:
       for (c = gfc_constructor_first (e->value.constructor);
 	   c; c = gfc_constructor_next (c))
@@ -2936,6 +2937,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
 	  rse.expr = convert (gfc_int4_type_node, rse.expr);
 	  res_ikind_2 = ikind;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case 4:
 	  ikind = 0;
@@ -2964,6 +2966,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
 	  else
 	    gcc_unreachable ();
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case 4:
 	  kind = 0;
@@ -3202,6 +3205,7 @@ gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
 	}
 
       /* Fallthrough.  */
+      gcc_fallthrough ();
     case INTRINSIC_UPLUS:
       gfc_conv_expr (se, expr->value.op.op1);
       return;
diff --git gcc/gcc/fortran/trans-intrinsic.c gcc/gcc/fortran/trans-intrinsic.c
index c655540..9d20be3 100644
--- gcc/gcc/fortran/trans-intrinsic.c
+++ gcc/gcc/fortran/trans-intrinsic.c
@@ -1047,6 +1047,7 @@ conv_caf_vector_subscript (stmtblock_t *block, tree desc, gfc_array_ref *ar)
 	  stride = gfc_index_one_node;
 
 	/* Fall through.  */
+	gcc_fallthrough ();
       case DIMEN_ELEMENT:
 	if (ar->start[i])
 	  {
@@ -2136,6 +2137,7 @@ conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
 	  bound = fold_build2_loc (input_location, MINUS_EXPR,
 				   gfc_array_index_type, bound,
 				   gfc_index_one_node);
+	  gcc_fallthrough ();
 	case 1:
 	  break;
 	default:
@@ -5330,6 +5332,7 @@ gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
 	}
 
       /* Otherwise fall through.  */
+      gcc_fallthrough ();
 
     default:
       /* Anybody stupid enough to do this deserves inefficient code.  */
diff --git gcc/gcc/fortran/trans-io.c gcc/gcc/fortran/trans-io.c
index aefa96d..829db5d 100644
--- gcc/gcc/fortran/trans-io.c
+++ gcc/gcc/fortran/trans-io.c
@@ -194,6 +194,7 @@ gfc_build_st_parameter (enum ioparam_type ptype, tree *types)
 	  p->field = gfc_add_field_to_struct (t, get_identifier (p->name),
 					      pchar_type_node, &chain);
 	  /* FALLTHROUGH */
+	  gcc_fallthrough ();
 	case IOPARM_type_char2:
 	  len = strlen (p->name);
 	  gcc_assert (len <= sizeof (name) - sizeof ("_len"));
@@ -2194,6 +2195,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
 	  return;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case BT_HOLLERITH:
       if (se->string_length)
 	arg2 = se->string_length;
diff --git gcc/gcc/fortran/trans-stmt.c gcc/gcc/fortran/trans-stmt.c
index 5aa7778..8d527ed 100644
--- gcc/gcc/fortran/trans-stmt.c
+++ gcc/gcc/fortran/trans-stmt.c
@@ -4962,6 +4962,7 @@ gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
             case EXEC_ASSIGN:
               expr1 = cnext->expr1;
               expr2 = cnext->expr2;
+	      gcc_fallthrough ();
     evaluate:
               if (nested_forall_info != NULL)
                 {

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: gcc/
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (4 preceding siblings ...)
  2016-07-11 19:52 ` Implement -Wswitch-fallthrough: fortran/ Marek Polacek
@ 2016-07-11 19:52 ` Marek Polacek
  2016-07-11 19:53 ` Implement -Wswitch-fallthrough: aarch64 + arm Marek Polacek
                   ` (23 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:52 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* Makefile.in (insn-attrtab.o-warn, insn-dfatab.o-warn,
	insn-latencytab.o-warn, insn-output.o-warn, insn-emit.o-warn): Add
	-Wno-switch-fallthrough.
	* alias.c (find_base_value): Add gcc_fallthrough.
	(find_base_term): Likewise.
	* asan.c (get_mem_refs_of_builtin_call): Likewise.
	* auto-inc-dec.c (attempt_change): Likewise.
	* builtins.c (expand_builtin_int_roundingfn_2): Likewise.
	(fold_builtin_arith_overflow): Likewise.
	(expand_builtin): Likewise.
	* cfgexpand.c (expand_gimple_stmt_1): Likewise.
	(expand_debug_expr): Likewise.
	* cfgrtl.c (duplicate_insn_chain): Likewise.
	* combine.c (find_split_point): Likewise.
	(expand_compound_operation): Likewise.
	(make_compound_operation): Likewise.
	(canon_reg_for_combine): Likewise.
	(force_to_mode): Likewise.
	(try_widen_shift_mode): Likewise.
	(simplify_shift_const_1): Likewise.
	(simplify_compare_const): Likewise.
	(simplify_comparison): Likewise.
	* convert.c (convert_to_real_1): Likewise.
	(convert_to_integer_1): Likewise.
	* cse.c (fold_rtx): Likewise.
	(cse_process_notes_1): Likewise.
	* cselib.c (cselib_expand_value_rtx_1): Likewise.
	* dbxout.c (dbxout_expand_expr): Likewise.
	(dbxout_symbol): Likewise.
	* df-scan.c (df_notes_rescan): Likewise.
	(df_uses_record): Likewise.
	* dojump.c (do_jump): Likewise.
	* dwarf2cfi.c (output_cfi_directive): Likewise. 
	* dwarf2out.c (output_loc_operands): Likewise.
	(print_dw_val): Likewise.
	(copy_dwarf_procs_ref_in_attrs): Likewise.
	(value_format): Likewise.
	(mem_loc_descriptor): Likewise.
	(loc_descriptor): Likewise.
	(resolve_args_picking_1): Likewise.
	(loc_list_from_tree_1): Likewise.
	(add_const_value_attribute): Likewise.
	(rtl_for_decl_init): Likewise.
	(add_bound_info): Likewise.
	(gen_formal_parameter_die): Likewise.
	(output_macinfo): Likewise.
	(mark_base_types): Likewise.
	(hash_loc_operands): Likewise.
	(compare_loc_operands): Likewise.
	* expmed.c (expand_divmod): Likewise.
	(make_tree): Likewise.
	* expr.c (safe_from_p): Likewise.
	(expand_expr_addr_expr_1): Likewise.
	(expand_expr_real_2): Likewise.
	(expand_expr_real_1): Likewise.
	* final.c (output_alternate_entry_point): Likewise.
	(output_addr_const): Likewise.
	* fold-const.c (negate_expr_p): Likewise.
	(fold_negate_expr): Likewise.
	(const_binop): Likewise.
	(fold_convert_loc): Likewise.
	(operand_equal_p): Likewise.
	(fold_truth_not_expr): Likewise.
	(make_range_step): Likewise.
	(merge_ranges): Likewise.
	(fold_cond_expr_with_comparison): Likewise.
	(extract_muldiv_1): Likewise.
	(fold_binary_loc): Likewise.
	(contains_label_1): Likewise.
	(multiple_of_p): Likewise.
	* gcc.c (driver_handle_option): Likewise.
	(do_spec_1): Likewise.
	* gcov-tool.c (process_args): Likewise.
	* gcse.c (want_to_gcse_p): Likewise.
	* genattrtab.c (check_attr_test): Likewise.
	(check_attr_value): Likewise.
	(make_canonical): Likewise.
	(write_test_expr): Likewise.
	* genconfig.c (walk_insn_part): Likewise.
	* gengtype-parse.c (direct_declarator): Likewise.
	* gengtype.c (dbgprint_count_type_at): Likewise.
	* genmodes.c: Likewise.
	* genpreds.c (validate_exp): Likewise.
	(needs_variable): Likewise.
	* genrecog.c (find_operand): Likewise.
	(find_matching_operand): Likewise.
	(match_pattern_2): Likewise.
	* gensupport.c (process_rtx): Likewise.
	(get_alternatives_number): Likewise.
	(collect_insn_data): Likewise.
	(alter_predicate_for_insn): Likewise.
	(subst_dup): Likewise.
	(read_md_rtx): Likewise.
	* gimple-fold.c (gimple_fold_builtin_fputs): Likewise.
	(fold_stmt_1): Likewise.
	(and_comparisons_1): Likewise.
	(or_comparisons_1): Likewise.
	(fold_const_aggregate_ref_1): Likewise.
	* gimple-pretty-print.c (dump_gimple_assign): Likewise.
	* gimple-ssa-backprop.c (backprop::process_assign_use): Likewise.
	* gimple-ssa-strength-reduction.c
	(find_candidates_dom_walker::before_dom_children): Likewise.
	* gimple-streamer-in.c (input_gimple_stmt): Likewise.
	* gimple-streamer-out.c (output_gimple_stmt): Likewise.
	* gimple-walk.c (walk_gimple_stmt): Likewise.
	* gimple.c (gimple_copy): Likewise.
	* gimplify.c (warn_switch_unreachable_r): Likewise.
	(gimple_boolify): Likewise.
	(gimplify_modify_expr_rhs): Likewise.
	(gimplify_addr_expr): Likewise.
	(omp_default_clause): Likewise.
	(gimplify_scan_omp_clauses): Likewise.
	(find_combined_omp_for): Likewise.
	(gimplify_omp_for): Likewise.
	(goa_stabilize_expr): Likewise.
	(gimplify_expr): Likewise.
	* godump.c (go_define): Likewise.
	(go_format_type): Likewise.
	* graphite-isl-ast-to-gimple.c (substitute_ssa_name): Likewise.
	* haifa-sched.c (remove_notes): Likewise.
	* hsa-gen.c (get_address_from_value): Likewise.
	(gen_hsa_insn_for_internal_fn_call): Likewise.
	* internal-fn.c (expand_arith_overflow): Likewise.
	* ipa-icf.c (sem_function::hash_stmt): Likewise.
	* ira.c (ira_setup_alts): Likewise.
	(equiv_init_varies_p): Likewise.
	(equiv_init_movable_p): Likewise.
	* jump.c (rtx_renumbered_equal_p): Likewise.
	* lra-eliminations.c (lra_eliminate_regs_1): Likewise.
	* lto-streamer-in.c (lto_input_mode_table): Likewise.
	* lto-streamer-out.c (lto_output_tree_ref): Likewise.
	* lto-wrapper.c (merge_and_complain): Likewise.
	(run_gcc): Likewise.
	* mode-switching.c (create_pre_exit): Likewise.
	* omp-low.c (scan_sharing_clauses): Likewise.
	(check_omp_nesting_restrictions): Likewise.
	(lower_rec_input_clauses): Likewise.
	(expand_parallel_call): Likewise.
	(expand_omp_for): Likewise.
	(expand_omp_target): Likewise.
	(expand_omp): Likewise.
	(lower_omp_target): Likewise.
	(lower_omp_1): Likewise.
	* optabs.c (add_equal_note): Likewise.
	* opts.c (common_handle_option): Likewise.
	* plugin.c (register_callback): Likewise.
	(invoke_plugin_callbacks_full): Likewise.
	* postreload.c (reload_combine_note_use): Likewise.
	* pretty-print.c (pp_write_text_as_dot_label_to_stream): Likewise.
	(pp_format): Likewise.
	(pp_emit_prefix): Likewise.
	* print-rtl.c (print_rtx): Likewise.
	* read-rtl.c (read_rtx_code): Likewise.
	* real.c (do_compare): Likewise.
	(round_for_format): Likewise.
	* recog.c (asm_operand_ok): Likewise.
	* reg-stack.c (get_true_reg): Likewise.
	(subst_stack_regs_pat): Likewise.
	* reginfo.c (reg_scan_mark_refs): Likewise.
	* reload1.c (set_label_offsets): Likewise.
	(eliminate_regs_1): Likewise.
	(elimination_effects): Likewise.
	(reload_reg_reaches_end_p): Likewise.
	(choose_reload_regs): Likewise.
	* resource.c (mark_referenced_resources): Likewise.
	(find_dead_or_set_registers): Likewise.
	(mark_set_resources): Likewise.
	* rtlanal.c (rtx_unstable_p): Likewise.
	(rtx_varies_p): Likewise.
	(reg_overlap_mentioned_p): Likewise.
	(volatile_insn_p): Likewise.
	(volatile_refs_p): Likewise.
	(side_effects_p): Likewise.
	(commutative_operand_precedence): Likewise.
	(auto_inc_p): Likewise.
	(rtx_cost): Likewise.
	* sched-deps.c (sched_analyze_2): Likewise.
	* sched-ebb.c (add_deps_for_risky_insns): Likewise.
	* sched-rgn.c (is_exception_free): Likewise.
	* simplify-rtx.c (simplify_binary_operation_1): Likewise.
	(simplify_rtx): Likewise.
	* stmt.c (parse_input_constraint): Likewise.
	* stor-layout.c (int_mode_for_mode): Likewise.
	* toplev.c (print_to_asm_out_file): Likewise.
	(print_to_stderr): Likewise.
	* trans-mem.c (get_attrs_for): Likewise.
	(is_tm_pure): Likewise.
	(requires_barrier): Likewise.
	* tree-cfg.c (verify_expr): Likewise.
	(verify_gimple_assign_ternary): Likewise.
	(gimple_verify_flow_info): Likewise.
	(move_stmt_r): Likewise.
	* tree-chrec.c (chrec_fold_plus_1): Likewise.
	(chrec_fold_multiply): Likewise.
	(evolution_function_is_invariant_rec_p): Likewise.
	(for_each_scev_op): Likewise.
	* tree-complex.c (expand_complex_division): Likewise.
	* tree-data-ref.c (split_constant_offset_1): Likewise.
	(siv_subscript_p): Likewise.
	(get_references_in_stmt): Likewise.
	* tree-dfa.c (get_ref_base_and_extent): Likewise.
	* tree-dump.c (dequeue_and_dump): Likewise.
	* tree-eh.c (lower_eh_constructs_2): Likewise.
	* tree-emutls.c (lower_emutls_1): Likewise.
	* tree-inline.c (remap_gimple_stmt): Likewise.
	* tree-nested.c (convert_nonlocal_reference_op): Likewise.
	(convert_nonlocal_omp_clauses): Likewise.
	(convert_local_reference_op): Likewise.
	(convert_local_omp_clauses): Likewise.
	(convert_tramp_reference_stmt): Likewise.
	(convert_gimple_call): Likewise.
	* tree-object-size.c (alloc_object_size): Likewise.
	* tree-pretty-print.c (dump_omp_clause): Likewise.
	(dump_generic_node): Likewise.
	(print_call_name): Likewise.
	* tree-scalar-evolution.c (expression_expensive_p): Likewise.
	* tree-sra.c (build_access_from_expr_1): Likewise.
	(create_access_replacement): Likewise.
	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): Likewise.
	* tree-ssa-ccp.c (bit_value_binop_1): Likewise.
	(pass_fold_builtins::execute): Likewise.
	* tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
	* tree-ssa-loop-ivopts.c (contains_abnormal_ssa_name_p): Likewise.
	(find_deriving_biv_for_expr): Likewise.
	(create_new_iv): Likewise.
	* tree-ssa-loop-niter.c (split_to_var_and_offset): Likewise.
	(expand_simple_operations): Likewise.
	* tree-ssa-math-opts.c (pass_optimize_bswap::execute): Likewise.
	* tree-ssa-operands.c (get_expr_operands): Likewise.
	(parse_ssa_operands): Likewise.
	* tree-ssa-pre.c (fully_constant_expression): Likewise.
	(create_component_ref_by_pieces_1): Likewise.
	* tree-ssa-propagate.c (valid_gimple_rhs_p): Likewise.
	* tree-ssa-reassoc.c (init_range_entry): Likewise.
	* tree-ssa-sccvn.c (vn_get_stmt_kind): Likewise.
	(copy_reference_ops_from_ref): Likewise.
	(ao_ref_init_from_vn_reference): Likewise.
	* tree-ssa-strlen.c (get_string_length): Likewise.
	(find_equal_ptrs): Likewise.
	* tree-tailcall.c (process_assignment): Likewise.
	* tree-vect-patterns.c (adjust_bool_pattern): Likewise.
	* tree-vect-stmts.c (exist_non_indexing_operands_for_use_p): Likewise.
	(vectorizable_conversion): Likewise.
	* tree.c (wide_int_to_tree): Likewise.
	(cache_integer_cst): Likewise.
	(find_placeholder_in_expr): Likewise.
	(substitute_in_expr): Likewise.
	(omp_declare_simd_clauses_equal): Likewise.
	(type_cache_hasher::equal): Likewise.
	(add_expr): Likewise.
	(walk_type_fields): Likewise.
	(walk_tree_1): Likewise.
	(block_may_fallthru): Likewise.
	* tsan.c (instrument_builtin_call): Likewise.
	* var-tracking.c (adjust_mems): Likewise.
	(set_dv_changed): Likewise.
	* varasm.c (default_function_section): Likewise.
	(const_rtx_hash_1): Likewise.
	(output_constant_pool_1): Likewise.
	(output_addressed_constants): Likewise.
	(elf_record_gcc_switches): Likewise.

include/
	* libiberty.h (D_FALLTHRU): New macro.

diff --git gcc/gcc/Makefile.in gcc/gcc/Makefile.in
index 5e7422d..7970f4d 100644
--- gcc/gcc/Makefile.in
+++ gcc/gcc/Makefile.in
@@ -218,6 +218,11 @@ libgcov-merge-tool.o-warn = -Wno-error
 gimple-match.o-warn = -Wno-unused
 generic-match.o-warn = -Wno-unused
 dfp.o-warn = -Wno-strict-aliasing
+insn-attrtab.o-warn = -Wno-switch-fallthrough
+insn-dfatab.o-warn = -Wno-switch-fallthrough
+insn-latencytab.o-warn = -Wno-switch-fallthrough
+insn-output.o-warn = -Wno-switch-fallthrough
+insn-emit.o-warn = -Wno-switch-fallthrough
 
 # All warnings have to be shut off in stage1 if the compiler used then
 # isn't gcc; configure determines that.  WARN_CFLAGS will be either
diff --git gcc/gcc/alias.c gcc/gcc/alias.c
index dd1dfd3..28ce7a6 100644
--- gcc/gcc/alias.c
+++ gcc/gcc/alias.c
@@ -1399,6 +1399,7 @@ find_base_value (rtx src)
 	break;
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case PLUS:
     case MINUS:
@@ -1469,6 +1470,7 @@ find_base_value (rtx src)
       if (GET_MODE_SIZE (GET_MODE (src)) < GET_MODE_SIZE (Pmode))
 	break;
       /* Fall through.  */
+      gcc_fallthrough ();
     case HIGH:
     case PRE_INC:
     case PRE_DEC:
@@ -1893,6 +1895,7 @@ find_base_term (rtx x)
       if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (Pmode))
 	return 0;
       /* Fall through.  */
+      gcc_fallthrough ();
     case HIGH:
     case PRE_INC:
     case PRE_DEC:
@@ -1955,6 +1958,7 @@ find_base_term (rtx x)
       if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
 	return 0;
       /* Fall through.  */
+      gcc_fallthrough ();
     case PLUS:
     case MINUS:
       {
diff --git gcc/gcc/asan.c gcc/gcc/asan.c
index 71095fb..c321e74 100644
--- gcc/gcc/asan.c
+++ gcc/gcc/asan.c
@@ -600,6 +600,7 @@ get_mem_refs_of_builtin_call (const gcall *call,
     case BUILT_IN_ATOMIC_LOAD_16:
       is_store = false;
       /* fall through.  */
+      gcc_fallthrough ();
 
     case BUILT_IN_SYNC_FETCH_AND_ADD_1:
     case BUILT_IN_SYNC_FETCH_AND_ADD_2:
@@ -799,6 +800,7 @@ get_mem_refs_of_builtin_call (const gcall *call,
 	  gcc_unreachable ();
 
 	access_size = int_size_in_bytes (TREE_TYPE (dest));
+	gcc_fallthrough ();
       }
 
     default:
diff --git gcc/gcc/auto-inc-dec.c gcc/gcc/auto-inc-dec.c
index bf4959b..8c24bea 100644
--- gcc/gcc/auto-inc-dec.c
+++ gcc/gcc/auto-inc-dec.c
@@ -523,6 +523,7 @@ attempt_change (rtx new_addr, rtx inc_reg)
 	reg_next_inc_use[regno] = NULL;
 
       /* Fallthru.  */
+      gcc_fallthrough ();
     case FORM_PRE_INC:
       regno = REGNO (inc_insn.reg_res);
       reg_next_def[regno] = mem_insn.insn;
diff --git gcc/gcc/builtins.c gcc/gcc/builtins.c
index 1465c60..c462bc5 100644
--- gcc/gcc/builtins.c
+++ gcc/gcc/builtins.c
@@ -2592,6 +2592,7 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target)
     CASE_FLT_FN (BUILT_IN_IRINT):
       fallback_fn = BUILT_IN_LRINT;
       /* FALLTHRU */
+      gcc_fallthrough ();
     CASE_FLT_FN (BUILT_IN_LRINT):
     CASE_FLT_FN (BUILT_IN_LLRINT):
       builtin_optab = lrint_optab;
@@ -2600,6 +2601,7 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target)
     CASE_FLT_FN (BUILT_IN_IROUND):
       fallback_fn = BUILT_IN_LROUND;
       /* FALLTHRU */
+      gcc_fallthrough ();
     CASE_FLT_FN (BUILT_IN_LROUND):
     CASE_FLT_FN (BUILT_IN_LLROUND):
       builtin_optab = lround_optab;
@@ -5906,6 +5908,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
     CASE_FLT_FN (BUILT_IN_ILOGB):
       if (! flag_unsafe_math_optimizations)
 	break;
+      gcc_fallthrough ();
     CASE_FLT_FN (BUILT_IN_ISINF):
     CASE_FLT_FN (BUILT_IN_FINITE):
     case BUILT_IN_ISFINITE:
@@ -6864,6 +6867,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
 	    return const0_rtx;
 	}
       /* FALLTHROUGH */
+      gcc_fallthrough ();
 
     case BUILT_IN_CHKP_BNDMK:
     case BUILT_IN_CHKP_BNDSTX:
@@ -8080,9 +8089,11 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode,
     case BUILT_IN_ADD_OVERFLOW_P:
       ovf_only = true;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_ADD_OVERFLOW:
       opcode = PLUS_EXPR;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_SADD_OVERFLOW:
     case BUILT_IN_SADDL_OVERFLOW:
     case BUILT_IN_SADDLL_OVERFLOW:
@@ -8094,9 +8105,11 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode,
     case BUILT_IN_SUB_OVERFLOW_P:
       ovf_only = true;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_SUB_OVERFLOW:
       opcode = MINUS_EXPR;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_SSUB_OVERFLOW:
     case BUILT_IN_SSUBL_OVERFLOW:
     case BUILT_IN_SSUBLL_OVERFLOW:
@@ -8108,9 +8121,11 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode,
     case BUILT_IN_MUL_OVERFLOW_P:
       ovf_only = true;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_MUL_OVERFLOW:
       opcode = MULT_EXPR;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_SMUL_OVERFLOW:
     case BUILT_IN_SMULL_OVERFLOW:
     case BUILT_IN_SMULLL_OVERFLOW:
diff --git gcc/gcc/cfgexpand.c gcc/gcc/cfgexpand.c
index e4ddb3a..66be558 100644
--- gcc/gcc/cfgexpand.c
+++ gcc/gcc/cfgexpand.c
@@ -3661,9 +3661,11 @@ expand_gimple_stmt_1 (gimple *stmt)
 		case GIMPLE_TERNARY_RHS:
 		  ops.op2 = gimple_assign_rhs3 (assign_stmt);
 		  /* Fallthru */
+		  gcc_fallthrough ();
 		case GIMPLE_BINARY_RHS:
 		  ops.op1 = gimple_assign_rhs2 (assign_stmt);
 		  /* Fallthru */
+		  gcc_fallthrough ();
 		case GIMPLE_UNARY_RHS:
 		  ops.op0 = gimple_assign_rhs1 (assign_stmt);
 		  break;
@@ -4165,6 +4167,7 @@ expand_debug_expr (tree exp)
       if (!op2)
 	return NULL_RTX;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     binary:
     case tcc_binary:
@@ -4195,6 +4198,7 @@ expand_debug_expr (tree exp)
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     unary:
     case tcc_unary:
@@ -4234,6 +4238,7 @@ expand_debug_expr (tree exp)
 	  return op0;
 	}
       /* Fall through...  */
+      gcc_fallthrough ();
 
     case INTEGER_CST:
     case REAL_CST:
@@ -4301,6 +4306,7 @@ expand_debug_expr (tree exp)
 	}
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     adjust_mode:
     case PAREN_EXPR:
@@ -4368,6 +4374,7 @@ expand_debug_expr (tree exp)
 	    return expand_debug_expr (newexp);
 	}
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case INDIRECT_REF:
       inner_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
       op0 = expand_debug_expr (TREE_OPERAND (exp, 0));
@@ -4597,6 +4604,7 @@ expand_debug_expr (tree exp)
 				      GET_MODE (op1));
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case PLUS_EXPR:
       return simplify_gen_binary (PLUS, mode, op0, op1);
 
diff --git gcc/gcc/cfgrtl.c gcc/gcc/cfgrtl.c
index 3d8ed60..a6b7fbb 100644
--- gcc/gcc/cfgrtl.c
+++ gcc/gcc/cfgrtl.c
@@ -4123,6 +4123,7 @@ duplicate_insn_chain (rtx_insn *from, rtx_insn *to)
 	  if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn)) == LABEL_DECL)
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case INSN:
 	case CALL_INSN:
 	case JUMP_INSN:
diff --git gcc/gcc/combine.c gcc/gcc/combine.c
index 4db11b0..15e4b10 100644
--- gcc/gcc/combine.c
+++ gcc/gcc/combine.c
@@ -5122,6 +5122,7 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
 	      || (GET_CODE (XEXP (x, 0)) == ASHIFT
 		  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
         return loc;
+      gcc_fallthrough ();
 
     default:
       break;
@@ -5136,6 +5137,7 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
       if (split)
 	return split;
       /* ... fall through ...  */
+      gcc_fallthrough ();
     case RTX_BIN_ARITH:
     case RTX_COMM_ARITH:
     case RTX_COMPARE:
@@ -5144,6 +5146,7 @@ find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
       if (split)
 	return split;
       /* ... fall through ...  */
+      gcc_fallthrough ();
     case RTX_UNARY:
       /* Some machines have (and (shift ...) ...) insns.  If X is not
 	 an AND, but XEXP (X, 0) is, use it as our split point.  */
@@ -6955,6 +6958,7 @@ expand_compound_operation (rtx x)
     {
     case ZERO_EXTEND:
       unsignedp = 1;
+      gcc_fallthrough ();
     case SIGN_EXTEND:
       /* We can't necessarily use a const_int for a multiword mode;
 	 it depends on implicitly extending the value.
@@ -6998,6 +7002,7 @@ expand_compound_operation (rtx x)
       unsignedp = 1;
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case SIGN_EXTRACT:
       /* If the operand is a CLOBBER, just return it.  */
@@ -8034,6 +8039,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
 	}
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case ASHIFTRT:
       lhs = XEXP (x, 0);
@@ -8261,6 +8267,8 @@ canon_reg_for_combine (rtx x, rtx reg)
       if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1) || op2 != XEXP (x, 2))
 	return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
 				     GET_MODE (op0), op0, op1, op2);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     case RTX_OBJ:
       if (REG_P (x))
@@ -8273,6 +8281,7 @@ canon_reg_for_combine (rtx x, rtx reg)
 	}
 
       /* fall through */
+      gcc_fallthrough ();
 
     default:
       fmt = GET_RTX_FORMAT (code);
@@ -8528,6 +8537,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
       }
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case MULT:
       /* Substituting into the operands of a widening MULT is not likely to
@@ -8598,6 +8608,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
 				   XEXP (XEXP (x, 0), 1));
 	  return force_to_mode (x, mode, mask, next_select);
 	}
+      gcc_fallthrough ();
 
     binop:
       /* For most binary operations, just propagate into the operation and
@@ -8776,6 +8787,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
       if (mask == 1)
 	x = simplify_gen_binary (LSHIFTRT, GET_MODE (x),
 				 XEXP (x, 0), XEXP (x, 1));
+     gcc_fallthrough ();
 
     shiftrt:
 
@@ -8853,6 +8865,7 @@ force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
       /* (and (not FOO) CONST) is (not (or FOO (not CONST))), so we must
 	 use the full mask inside the NOT.  */
       mask = fuller_mask;
+      gcc_fallthrough ();
 
     unop:
       op0 = gen_lowpart_or_truncate (op_mode,
@@ -10155,6 +10168,7 @@ try_widen_shift_mode (enum rtx_code code, rtx op, int count,
 	    return mode;
 	}
       /* fall through */
+      gcc_fallthrough ();
 
     case ROTATE:
       return orig_mode;
@@ -10401,6 +10415,7 @@ simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
 	    }
 
 	  /* ... fall through ...  */
+	  gcc_fallthrough ();
 
 	case LSHIFTRT:
 	case ASHIFT:
@@ -11360,6 +11375,7 @@ simplify_compare_const (enum rtx_code code, machine_mode mode,
 	  const_op -= 1;
 	  code = LE;
 	  /* ... fall through to LE case below.  */
+	  gcc_fallthrough ();
 	}
       else
 	break;
@@ -11389,6 +11405,7 @@ simplify_compare_const (enum rtx_code code, machine_mode mode,
 	  const_op -= 1;
 	  code = GT;
 	  /* ... fall through to GT below.  */
+	  gcc_fallthrough ();
 	}
       else
 	break;
@@ -11418,6 +11435,7 @@ simplify_compare_const (enum rtx_code code, machine_mode mode,
 	  const_op -= 1;
 	  code = LEU;
 	  /* ... fall through ...  */
+	  gcc_fallthrough ();
 	}
       /* (unsigned) < 0x80000000 is equivalent to >= 0.  */
       else if (mode_width - 1 < HOST_BITS_PER_WIDE_INT
@@ -11452,6 +11470,7 @@ simplify_compare_const (enum rtx_code code, machine_mode mode,
 	  const_op -= 1;
 	  code = GTU;
 	  /* ... fall through ...  */
+	  gcc_fallthrough ();
 	}
 
       /* (unsigned) >= 0x80000000 is equivalent to < 0.  */
@@ -11727,6 +11746,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
 	    }
 
 	  /* ... fall through ...  */
+	  gcc_fallthrough ();
 
 	case SIGN_EXTRACT:
 	  tem = expand_compound_operation (op0);
@@ -11824,6 +11844,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
 	    }
 
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case ABS:
 	  /* ABS is ignorable inside an equality comparison with zero.  */
@@ -12334,6 +12355,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
 	    }
 
 	  /* ... fall through ...  */
+	  gcc_fallthrough ();
 	case LSHIFTRT:
 	  /* If we have (compare (xshiftrt FOO N) (const_int C)) and
 	     the low order N bits of FOO are known to be zero, we can do this
diff --git gcc/gcc/convert.c gcc/gcc/convert.c
index e6b4d29..c0cc391 100644
--- gcc/gcc/convert.c
+++ gcc/gcc/convert.c
@@ -164,6 +164,7 @@ convert_to_real_1 (tree type, tree expr, bool fold_p)
 	       -fmath-errno.  */
 	    if (flag_errno_math)
 	      break;
+	    gcc_fallthrough ();
 	  CASE_MATHFN (ACOS)
 	  CASE_MATHFN (ACOSH)
 	  CASE_MATHFN (ASIN)
@@ -184,6 +185,7 @@ convert_to_real_1 (tree type, tree expr, bool fold_p)
 	    /* The above functions are not safe to do this conversion.  */
 	    if (!flag_unsafe_math_optimizations)
 	      break;
+	    gcc_fallthrough ();
 	  CASE_MATHFN (SQRT)
 	  CASE_MATHFN (FABS)
 	  CASE_MATHFN (LOGB)
@@ -245,6 +247,8 @@ convert_to_real_1 (tree type, tree expr, bool fold_p)
 		    }
 		}
 	    }
+	  /* XXX Really fallthru?  */
+	  gcc_fallthrough ();
 	default:
 	  break;
 	}
@@ -517,6 +521,7 @@ convert_to_integer_1 (tree type, tree expr, bool dofold)
 	  if (flag_trapping_math)
 	    break;
 	  /* ... Fall through ...  */
+	  gcc_fallthrough ();
 	CASE_FLT_FN (BUILT_IN_RINT):
 	  /* Only convert in ISO C99 mode and with -fno-math-errno.  */
 	  if (!targetm.libc_has_function (function_c99_misc) || flag_errno_math)
diff --git gcc/gcc/cse.c gcc/gcc/cse.c
index c14f29d..2f3effc 100644
--- gcc/gcc/cse.c
+++ gcc/gcc/cse.c
@@ -3586,6 +3586,7 @@ fold_rtx (rtx x, rtx_insn *insn)
 	    }
 
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	from_plus:
 	case SMIN:    case SMAX:      case UMIN:    case UMAX:
@@ -6199,6 +6200,7 @@ cse_process_notes_1 (rtx x, rtx object, bool *changed)
       if (REG_NOTE_KIND (x) == REG_EQUAL)
 	XEXP (x, 0) = cse_process_notes (XEXP (x, 0), NULL_RTX, changed);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case INSN_LIST:
     case INT_LIST:
diff --git gcc/gcc/cselib.c gcc/gcc/cselib.c
index 14c7b32..24b1976 100644
--- gcc/gcc/cselib.c
+++ gcc/gcc/cselib.c
@@ -1619,6 +1619,8 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
 		return orig;
 	    }
       }
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     CASE_CONST_ANY:
     case SYMBOL_REF:
diff --git gcc/gcc/dbxout.c gcc/gcc/dbxout.c
index 25a03ef..79c5965 100644
--- gcc/gcc/dbxout.c
+++ gcc/gcc/dbxout.c
@@ -2460,12 +2460,14 @@ dbxout_expand_expr (tree expr)
 	    return NULL;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case PARM_DECL:
     case RESULT_DECL:
       if (DECL_HAS_VALUE_EXPR_P (expr))
 	return dbxout_expand_expr (DECL_VALUE_EXPR (expr));
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST_DECL:
       return DECL_RTL_IF_SET (expr);
@@ -2868,6 +2870,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
       gcc_assert (TREE_CODE (decl) == VAR_DECL);
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case RESULT_DECL:
     case VAR_DECL:
diff --git gcc/gcc/df-scan.c gcc/gcc/df-scan.c
index 19d8e0f..b30d569 100644
--- gcc/gcc/df-scan.c
+++ gcc/gcc/df-scan.c
@@ -1999,6 +1999,7 @@ df_notes_rescan (rtx_insn *insn)
 	      df_uses_record (&collection_rec,
 			      &XEXP (note, 0), DF_REF_REG_USE,
 			      bb, insn_info, DF_REF_IN_NOTE);
+	      gcc_fallthrough ();
 	    default:
 	      break;
 	    }
@@ -2876,6 +2877,7 @@ df_uses_record (struct df_collection_rec *collection_rec,
 	  return;
 	}
       /* ... Fall through ...  */
+      gcc_fallthrough ();
 
     case REG:
       df_ref_record (DF_REF_REGULAR, collection_rec,
@@ -2923,6 +2925,7 @@ df_uses_record (struct df_collection_rec *collection_rec,
 		  break;
 		}
 	      /* Fall through.  */
+	      gcc_fallthrough ();
 	    case REG:
 	    case PARALLEL:
 	    case SCRATCH:
@@ -3035,6 +3038,7 @@ df_uses_record (struct df_collection_rec *collection_rec,
                      flags | DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY);
 
       /* ... Fall through to handle uses ...  */
+      gcc_fallthrough ();
 
     default:
       break;
diff --git gcc/gcc/dojump.c gcc/gcc/dojump.c
index 6e0c01c..260c405 100644
--- gcc/gcc/dojump.c
+++ gcc/gcc/dojump.c
@@ -461,12 +461,16 @@ do_jump (tree exp, rtx_code_label *if_false_label,
           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
           || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
         goto normal;
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case CONVERT_EXPR:
       /* If we are narrowing the operand, we have to do the compare in the
          narrower mode.  */
       if ((TYPE_PRECISION (TREE_TYPE (exp))
            < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
         goto normal;
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case NON_LVALUE_EXPR:
     case ABS_EXPR:
     case NEGATE_EXPR:
@@ -510,6 +514,7 @@ do_jump (tree exp, rtx_code_label *if_false_label,
       code = NE_EXPR;
 
       /* FALLTHRU */
+      gcc_fallthrough ();
     case EQ_EXPR:
     case NE_EXPR:
     case LT_EXPR:
@@ -610,6 +615,7 @@ do_jump (tree exp, rtx_code_label *if_false_label,
 	goto normal;
 
       /* Boolean comparisons can be compiled as TRUTH_AND_EXPR.  */
+      gcc_fallthrough ();
 
     case TRUTH_AND_EXPR:
       /* High branch cost, expand as the bitwise AND of the conditions.
diff --git gcc/gcc/dwarf2cfi.c gcc/gcc/dwarf2cfi.c
index bcf79f5..71f645b 100644
--- gcc/gcc/dwarf2cfi.c
+++ gcc/gcc/dwarf2cfi.c
@@ -3306,6 +3306,7 @@ output_cfi_directive (FILE *f, dw_cfi_ref cfi)
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case DW_CFA_expression:
       if (f != asm_out_file)
 	{
diff --git gcc/gcc/dwarf2out.c gcc/gcc/dwarf2out.c
index 14dcdf9..e0f079d 100644
--- gcc/gcc/dwarf2out.c
+++ gcc/gcc/dwarf2out.c
@@ -1815,6 +1815,7 @@ output_loc_operands (dw_loc_descr_ref loc, int for_eh_or_skip)
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case DW_OP_const4s:
       dw2_asm_output_data (4, val1->v.val_int, NULL);
       break;
@@ -1828,6 +1829,7 @@ output_loc_operands (dw_loc_descr_ref loc, int for_eh_or_skip)
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case DW_OP_const8s:
       gcc_assert (HOST_BITS_PER_WIDE_INT >= 64);
       dw2_asm_output_data (8, val1->v.val_int, NULL);
@@ -5697,6 +5699,7 @@ print_dw_val (dw_val_node *val, bool recurse, FILE *outfile)
 	  if (node->dw_discr_next != NULL)
 	    fprintf (outfile, " | ");
 	}
+      gcc_fallthrough ();
     default:
       break;
     }
@@ -7788,6 +7791,7 @@ copy_dwarf_procs_ref_in_attrs (dw_die_ref die,
 	        = copy_dwarf_procedure (loc->dw_loc_oprnd1.v.val_die_ref.die,
 					type_node,
 					copied_dwarf_procs);
+	      gcc_fallthrough ();
 
 	    default:
 	      break;
@@ -8723,6 +8727,7 @@ value_format (dw_attr_node *a)
       if (dwarf_version >= 4)
 	return DW_FORM_sec_offset;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case dw_val_class_vms_delta:
     case dw_val_class_offset:
       switch (DWARF_OFFSET_SIZE)
@@ -13334,6 +13339,8 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
       if (!subreg_lowpart_p (rtl))
 	break;
       inner = SUBREG_REG (rtl);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case TRUNCATE:
       if (inner == NULL_RTX)
         inner = XEXP (rtl, 0);
@@ -13602,6 +13609,8 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
 						 initialized);
 	  break;
 	}
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     symref:
       mem_loc_result = new_addr_loc_descr (rtl, dtprel_false);
@@ -13672,6 +13681,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
 					mode));
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case PLUS:
     plus:
@@ -14023,6 +14033,7 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
       if (!SCALAR_INT_MODE_P (mode))
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case SMIN:
     case SMAX:
       mem_loc_result = minmax_loc_descriptor (rtl, mode, mem_mode);
@@ -14395,6 +14406,7 @@ loc_descriptor (rtx rtl, machine_mode mode,
 
       rtl = XEXP (rtl, 1);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case PARALLEL:
       {
@@ -14537,9 +14549,12 @@ loc_descriptor (rtx rtl, machine_mode mode,
 	  break;
 	}
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case SYMBOL_REF:
       if (!const_ok_for_output (rtl))
 	break;
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case LABEL_REF:
       if (mode != VOIDmode && GET_MODE_SIZE (mode) == DWARF2_ADDR_SIZE
 	  && (dwarf_version >= 4 || !dwarf_strict))
@@ -14563,6 +14578,7 @@ loc_descriptor (rtx rtl, machine_mode mode,
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     do_default:
     default:
       if ((SCALAR_INT_MODE_P (mode)
@@ -15598,6 +15614,7 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
 				       frame_offsets))
 	    return false;
 	  /* Fall through... */
+	  gcc_fallthrough ();
 
 	case DW_OP_skip:
 	  l = l->dw_loc_oprnd1.v.val_loc;
@@ -15936,6 +15953,7 @@ loc_list_from_tree_1 (tree loc, int want_address,
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case PARM_DECL:
       if (context != NULL && context->dpi != NULL
@@ -15961,12 +15979,14 @@ loc_list_from_tree_1 (tree loc, int want_address,
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case RESULT_DECL:
       if (DECL_HAS_VALUE_EXPR_P (loc))
 	return loc_list_from_tree_1 (DECL_VALUE_EXPR (loc),
 				     want_address, context);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case FUNCTION_DECL:
       {
@@ -16038,6 +16058,7 @@ loc_list_from_tree_1 (tree loc, int want_address,
 	  goto do_plus;
 	}
       /* Fallthru.  */
+      gcc_fallthrough ();
     case INDIRECT_REF:
       list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
       have_address = 1;
@@ -16351,6 +16372,7 @@ loc_list_from_tree_1 (tree loc, int want_address,
       }
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case COND_EXPR:
       {
@@ -17110,9 +17132,12 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
       if (CONSTANT_P (XEXP (rtl, 0)))
 	return add_const_value_attribute (die, XEXP (rtl, 0));
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case SYMBOL_REF:
       if (!const_ok_for_output (rtl))
 	return false;
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case LABEL_REF:
       if (dwarf_version >= 4 || !dwarf_strict)
 	goto rtl_addr;
@@ -17276,6 +17301,7 @@ rtl_for_decl_init (tree init, tree type)
 		  }
 	      }
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 
 	  default:
 	    return NULL;
@@ -18342,6 +18368,7 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr,
 	  return;
 
 	/* FALLTHRU */
+	gcc_fallthrough ();
 
       default:
 	/* Because of the complex interaction there can be with other GNAT
@@ -19652,6 +19679,7 @@ gen_formal_parameter_die (tree node, tree origin, bool emit_name_p,
 	}
       if (origin == NULL && DECL_ARTIFICIAL (node))
 	add_AT_flag (parm_die, DW_AT_artificial, 1);
+      gcc_fallthrough ();
     add_location:
       if (node && node != origin)
         equate_decl_number_to_die (node, parm_die);
@@ -25233,6 +25261,7 @@ output_macinfo (void)
 	     to optimize the whole block of predefined macros.  */
 	  if (i == 0)
 	    continue;
+	  gcc_fallthrough ();
 	default:
 	  break;
 	}
@@ -26132,6 +26161,7 @@ mark_base_types (dw_loc_descr_ref loc)
 	  if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const)
 	    continue;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case DW_OP_GNU_const_type:
 	  base_type = loc->dw_loc_oprnd1.v.val_die_ref.die;
 	  break;
@@ -26760,6 +26790,7 @@ hash_loc_operands (dw_loc_descr_ref loc, inchash::hash &hstate)
       if (loc->dtprel)
 	goto hash_addr;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case DW_OP_const1u:
     case DW_OP_const1s:
     case DW_OP_const2u:
@@ -26903,6 +26934,7 @@ hash_loc_operands (dw_loc_descr_ref loc, inchash::hash &hstate)
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case DW_OP_GNU_const_type:
       {
 	unsigned int byte_size
@@ -27009,6 +27041,7 @@ compare_loc_operands (dw_loc_descr_ref x, dw_loc_descr_ref y)
       if (x->dtprel)
 	goto hash_addr;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case DW_OP_const1u:
     case DW_OP_const1s:
     case DW_OP_const2u:
diff --git gcc/gcc/expmed.c gcc/gcc/expmed.c
index 6645a53..f4ecf0a 100644
--- gcc/gcc/expmed.c
+++ gcc/gcc/expmed.c
@@ -4473,6 +4473,7 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
 	      }
 	    break;
 	  }
+	gcc_fallthrough ();
       fail1:
 	delete_insns_since (last);
 	break;
@@ -5181,6 +5182,7 @@ make_tree (tree type, rtx x)
       if (t)
 	return fold_convert (type, build_fold_addr_expr (t));
       /* else fall through.  */
+      gcc_fallthrough ();
 
     default:
       t = build_decl (RTL_LOCATION (x), VAR_DECL, NULL_TREE, type);
diff --git gcc/gcc/expr.c gcc/gcc/expr.c
index 6547be1..3e5d3bc 100644
--- gcc/gcc/expr.c
+++ gcc/gcc/expr.c
@@ -7487,6 +7487,7 @@ safe_from_p (const_rtx x, tree exp, int top_p)
       if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
 	return 0;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case tcc_unary:
       return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
@@ -7799,6 +7800,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, machine_mode tmode,
 	return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp),
 					target, tmode, modifier, as);
       /* FALLTHRU */
+      gcc_fallthrough ();
     default:
       /* If the object is a DECL, then expand it for its rtl.  Don't bypass
 	 expand_expr, as that can have various side effects; LABEL_DECLs for
@@ -8422,6 +8424,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
 	 offset to have matching modes.  */
       else if (TYPE_PRECISION (sizetype) > TYPE_PRECISION (type))
 	treeop1 = fold_convert_loc (loc, type, treeop1);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     case PLUS_EXPR:
       /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
@@ -9057,6 +9061,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
 		  || (GET_MODE_PRECISION (TYPE_MODE (type))
 		      == TYPE_PRECISION (type)));
       /* fall through */
+      gcc_fallthrough ();
 
     case LSHIFT_EXPR:
     case RSHIFT_EXPR:
@@ -9590,10 +9595,17 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
     switch (TREE_CODE_LENGTH (code))
       {
 	default:
-	case 3: treeop2 = TREE_OPERAND (exp, 2);
-	case 2: treeop1 = TREE_OPERAND (exp, 1);
-	case 1: treeop0 = TREE_OPERAND (exp, 0);
-	case 0: break;
+	case 3:
+	  treeop2 = TREE_OPERAND (exp, 2);
+	  gcc_fallthrough ();
+	case 2:
+	  treeop1 = TREE_OPERAND (exp, 1);
+	  gcc_fallthrough ();
+	case 1:
+	  treeop0 = TREE_OPERAND (exp, 0);
+	  gcc_fallthrough ();
+	case 0:
+	  break;
       }
   ops.code = code;
   ops.type = type;
@@ -9717,6 +9729,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 	    case GIMPLE_TERNARY_RHS:
 	      ops.op2 = gimple_assign_rhs3 (g);
 	      /* Fallthru */
+	      gcc_fallthrough ();
 	    case GIMPLE_BINARY_RHS:
 	      ops.op1 = gimple_assign_rhs2 (g);
 
@@ -9729,6 +9742,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 		    break;
 		}
 	      /* Fallthru */
+	      gcc_fallthrough ();
 	    case GIMPLE_UNARY_RHS:
 	      ops.op0 = gimple_assign_rhs1 (g);
 	      ops.type = TREE_TYPE (gimple_assign_lhs (g));
@@ -9765,10 +9779,12 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 	layout_decl (exp, 0);
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case FUNCTION_DECL:
     case RESULT_DECL:
       decl_rtl = DECL_RTL (exp);
+      gcc_fallthrough ();
     expand_decl_rtl:
       gcc_assert (decl_rtl);
 
@@ -9973,6 +9989,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
 	}
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case STRING_CST:
       temp = expand_expr_constant (exp, 1, modifier);
diff --git gcc/gcc/final.c gcc/gcc/final.c
index 5b04311..b26d101 100644
--- gcc/gcc/final.c
+++ gcc/gcc/final.c
@@ -2096,9 +2096,13 @@ output_alternate_entry_point (FILE *file, rtx_insn *insn)
     case LABEL_WEAK_ENTRY:
 #ifdef ASM_WEAKEN_LABEL
       ASM_WEAKEN_LABEL (file, name);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 #endif
     case LABEL_GLOBAL_ENTRY:
       targetm.asm_out.globalize_label (file, name);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case LABEL_STATIC_ENTRY:
 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
       ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
@@ -3892,6 +3896,7 @@ output_addr_const (FILE *file, rtx x)
     case LABEL_REF:
       x = LABEL_REF_LABEL (x);
       /* Fall through.  */
+      gcc_fallthrough ();
     case CODE_LABEL:
       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
 #ifdef ASM_OUTPUT_LABEL_REF
diff --git gcc/gcc/fold-const.c gcc/gcc/fold-const.c
index f97b8bf..5d1f8e1 100644
--- gcc/gcc/fold-const.c
+++ gcc/gcc/fold-const.c
@@ -467,6 +467,7 @@ negate_expr_p (tree t)
 	break;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case RDIV_EXPR:
       if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (TREE_TYPE (t))))
@@ -641,6 +642,7 @@ fold_negate_expr (location_t loc, tree t)
         break;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case RDIV_EXPR:
       if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)))
@@ -1301,6 +1303,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
                                 /* do_nonfinite= */ folding_initializer,
 				mpc_div);
 	  /* Fallthru ... */
+	  gcc_fallthrough ();
 	case TRUNC_DIV_EXPR:
 	case CEIL_DIV_EXPR:
 	case FLOOR_DIV_EXPR:
@@ -2229,6 +2232,7 @@ fold_convert_loc (location_t loc, tree type, tree arg)
 	      != TYPE_ADDR_SPACE (TREE_TYPE (orig))))
 	return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, arg);
       /* fall through */
+      gcc_fallthrough ();
 
     case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
     case OFFSET_TYPE:
@@ -3031,6 +3035,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
 	    return 0;
 
 	/* Fallthru.  */
+	gcc_fallthrough ();
 	case REALPART_EXPR:
 	case VIEW_CONVERT_EXPR:
 	  return OP_SAME (0);
@@ -3141,6 +3146,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
 	    return 0;
 	  /* The multiplcation operands are commutative.  */
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case TRUTH_AND_EXPR:
 	case TRUTH_OR_EXPR:
@@ -3698,6 +3704,7 @@ fold_truth_not_expr (location_t loc, tree arg)
 	return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case FLOAT_EXPR:
       loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
@@ -4461,6 +4468,7 @@ make_range_step (location_t loc, enum tree_code code, tree arg0, tree arg1,
 
       if (TYPE_OVERFLOW_UNDEFINED (arg0_type))
 	*strict_overflow_p = true;
+      gcc_fallthrough ();
 
       normalize:
 	/* Check for an unsigned range which has wrapped around the maximum
@@ -4954,6 +4962,7 @@ merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
 			!= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (low0))))
 		      break;
 		    /* FALLTHROUGH */
+		    gcc_fallthrough ();
 		  case INTEGER_TYPE:
 		    if (tree_int_cst_equal (low0,
 					    TYPE_MIN_VALUE (TREE_TYPE (low0))))
@@ -4977,6 +4986,7 @@ merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
 			!= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (high1))))
 		      break;
 		    /* FALLTHROUGH */
+		    gcc_fallthrough ();
 		  case INTEGER_TYPE:
 		    if (tree_int_cst_equal (high1,
 					    TYPE_MAX_VALUE (TREE_TYPE (high1))))
@@ -5092,6 +5102,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
 	if (flag_trapping_math)
 	  break;
 	/* Fall through.  */
+	gcc_fallthrough ();
       case GE_EXPR:
       case GT_EXPR:
 	if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
@@ -5102,6 +5113,8 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
       case UNLT_EXPR:
 	if (flag_trapping_math)
 	  break;
+	/* Fall through.  */
+	gcc_fallthrough ();
       case LE_EXPR:
       case LT_EXPR:
 	if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
@@ -6121,6 +6134,7 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
       if (tree_int_cst_sgn (c) == -1)
         break;
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case NEGATE_EXPR:
       /* For division and modulus, type can't be unsigned, as e.g.
 	 (-(x / 2U)) / 2U isn't equal to -((x / 2U) / 2U) for x >= 2.
@@ -6284,6 +6298,7 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
 	}
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case TRUNC_DIV_EXPR:  case CEIL_DIV_EXPR:  case FLOOR_DIV_EXPR:
     case ROUND_DIV_EXPR:  case EXACT_DIV_EXPR:
@@ -9455,6 +9470,7 @@ fold_binary_loc (location_t loc,
                 }
             }
 	}
+      gcc_fallthrough ();
 
      bit_rotate:
       /* (A << C1) + (A >> C2) if A is unsigned and C1+C2 is the size of A
@@ -9544,6 +9560,7 @@ fold_binary_loc (location_t loc,
 	      }
 	  }
       }
+    gcc_fallthrough ();
 
     associate:
       /* In most languages, can't associate operations on floats through
@@ -10193,6 +10210,7 @@ fold_binary_loc (location_t loc,
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
 
     case ROUND_DIV_EXPR:
     case CEIL_DIV_EXPR:
@@ -10326,6 +10344,8 @@ fold_binary_loc (location_t loc,
       /* If first arg is constant zero, return it.  */
       if (integer_zerop (arg0))
 	return fold_convert_loc (loc, type, arg0);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case TRUTH_AND_EXPR:
       /* If either arg is constant true, drop it.  */
       if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
@@ -10381,6 +10401,8 @@ fold_binary_loc (location_t loc,
       /* If first arg is constant true, return it.  */
       if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
 	return fold_convert_loc (loc, type, arg0);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case TRUTH_OR_EXPR:
       /* If either arg is constant zero, drop it.  */
       if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
@@ -11226,6 +11248,7 @@ contains_label_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
       *walk_subtrees = 0;
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     default:
       return NULL_TREE;
@@ -12555,6 +12578,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom)
       if (!integer_pow2p (bottom))
 	return 0;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case MULT_EXPR:
       return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
@@ -12591,6 +12615,7 @@ multiple_of_p (tree type, const_tree top, const_tree bottom)
 	return 0;
 
       /* .. fall through ...  */
+      gcc_fallthrough ();
 
     case SAVE_EXPR:
       return multiple_of_p (type, TREE_OPERAND (top, 0), bottom);
diff --git gcc/gcc/gcc.c gcc/gcc/gcc.c
index 7460f6a..f431660 100644
--- gcc/gcc/gcc.c
+++ gcc/gcc/gcc.c
@@ -3857,6 +3857,7 @@ driver_handle_option (struct gcc_options *opts,
 
     case OPT_fcompare_debug_:
       compare_debug_replacement_opt = decoded->canonical_option[0];
+      gcc_fallthrough ();
     compare_debug_with_arg:
       gcc_assert (decoded->canonical_option_num_elements == 1);
       gcc_assert (arg != NULL);
@@ -5936,6 +5937,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
 	c = *p++;
 
 	/* Fall through.  */
+	gcc_fallthrough ();
       default:
 	/* Ordinary character: put it into the current argument.  */
 	obstack_1grow (&obstack, c);
diff --git gcc/gcc/gcov-tool.c gcc/gcc/gcov-tool.c
index f3da73c..28c9393 100644
--- gcc/gcc/gcov-tool.c
+++ gcc/gcc/gcov-tool.c
@@ -547,9 +547,11 @@ process_args (int argc, char **argv)
         case 'h':
           print_usage (false);
           /* Print_usage will exit.  */
+	  gcc_fallthrough ();
         case 'v':
           print_version ();
           /* Print_version will exit.  */
+	  gcc_fallthrough ();
         default:
           print_usage (true);
           /* Print_usage will exit.  */
diff --git gcc/gcc/gcse.c gcc/gcc/gcse.c
index a3a7dc3..56f8c14 100644
--- gcc/gcc/gcse.c
+++ gcc/gcc/gcse.c
@@ -783,6 +783,7 @@ want_to_gcse_p (rtx x, machine_mode mode, int *max_distance_ptr)
 	return 0;
 
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     default:
       if (doing_code_hoisting_p)
diff --git gcc/gcc/genattrtab.c gcc/gcc/genattrtab.c
index d39d4a7..689b4b8 100644
--- gcc/gcc/genattrtab.c
+++ gcc/gcc/genattrtab.c
@@ -888,6 +888,7 @@ check_attr_test (file_location loc, rtx exp, attr_desc *attr)
 	  ATTR_IND_SIMPLIFIED_P (exp) = 1;
 	  break;
 	}
+      gcc_fallthrough ();
     default:
       fatal_at (loc, "invalid operator `%s' in definition of attribute"
 		" `%s'", GET_RTX_NAME (GET_CODE (exp)), attr->name);
@@ -976,6 +977,7 @@ check_attr_value (file_location loc, rtx exp, struct attr_desc *attr)
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case IOR:
     case AND:
@@ -1218,6 +1220,7 @@ make_canonical (file_location loc, struct attr_desc *attr, rtx exp)
 
       exp = newexp;
       /* Fall through to COND case since this is now a COND.  */
+      gcc_fallthrough ();
 
     case COND:
       {
@@ -3453,11 +3456,14 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
     case LEU: case LTU:
       fprintf (outf, "(unsigned) ");
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case EQ: case NE:
     case GE: case GT:
     case LE: case LT:
       comparison_operator = FLG_BITWISE;
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
     case AND:    case IOR:    case XOR:
@@ -3613,6 +3619,7 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
 	}
 
       /* Otherwise, fall through to normal unary operator.  */
+      gcc_fallthrough ();
 
     /* Unary operators.  */
     case ABS:  case NEG:
diff --git gcc/gcc/genconfig.c gcc/gcc/genconfig.c
index 815e30d..ac65338 100644
--- gcc/gcc/genconfig.c
+++ gcc/gcc/genconfig.c
@@ -83,6 +83,8 @@ walk_insn_part (rtx part, int recog_p, int non_pc_set_src)
     case MATCH_OP_DUP:
     case MATCH_PAR_DUP:
       ++dup_operands_seen_this_insn;
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case MATCH_SCRATCH:
     case MATCH_PARALLEL:
     case MATCH_OPERATOR:
diff --git gcc/gcc/gengtype-parse.c gcc/gcc/gengtype-parse.c
index 954ac2a..2f635f5 100644
--- gcc/gcc/gengtype-parse.c
+++ gcc/gcc/gengtype-parse.c
@@ -662,6 +662,7 @@ direct_declarator (type_p ty, const char **namep, options_p *optsp,
     case GTY_TOKEN:
       *optsp = gtymarker ();
       /* fall through */
+      gcc_fallthrough ();
 
     case ID:
       *namep = require (ID);
diff --git gcc/gcc/gengtype.c gcc/gcc/gengtype.c
index 5479b8f..e73f5a2 100644
--- gcc/gcc/gengtype.c
+++ gcc/gcc/gengtype.c
@@ -175,6 +175,8 @@ dbgprint_count_type_at (const char *fil, int lin, const char *msg, type_p t)
 	{
 	case TYPE_UNDEFINED:
 	  nb_undefined++;
+	  /* XXX Really fallthru?  */
+	  gcc_fallthrough ();
 	case TYPE_SCALAR:
 	  nb_scalar++;
 	  break;
diff --git gcc/gcc/genmodes.c gcc/gcc/genmodes.c
index 788031b..3cafa33 100644
--- gcc/gcc/genmodes.c
+++ gcc/gcc/genmodes.c
@@ -267,6 +267,7 @@ enum requirement { SET, UNSET, OPTIONAL };
       if (val != unset)							\
 	error ("%s:%d: (%s) field %s must not be set",			\
 	       file, line, mname, fname);				\
+      gcc_fallthrough ();						\
     case OPTIONAL:							\
       break;								\
     }									\
diff --git gcc/gcc/genpreds.c gcc/gcc/genpreds.c
index dd7dbbf..83f6159 100644
--- gcc/gcc/genpreds.c
+++ gcc/gcc/genpreds.c
@@ -52,11 +52,13 @@ validate_exp (rtx exp, const char *name, file_location loc)
       if (validate_exp (XEXP (exp, 2), name, loc))
 	return true;
       /* else fall through */
+      gcc_fallthrough ();
     case AND:
     case IOR:
       if (validate_exp (XEXP (exp, 1), name, loc))
 	return true;
       /* else fall through */
+      gcc_fallthrough ();
     case NOT:
       return validate_exp (XEXP (exp, 0), name, loc);
 
@@ -75,6 +77,7 @@ validate_exp (rtx exp, const char *name, file_location loc)
 	  }
       }
       /* fall through */
+      gcc_fallthrough ();
 
       /* These need no special checking.  */
     case MATCH_OPERAND:
@@ -175,11 +178,13 @@ needs_variable (rtx exp, const char *var)
       if (needs_variable (XEXP (exp, 2), var))
 	return true;
       /* else fall through */
+      gcc_fallthrough ();
     case AND:
     case IOR:
       if (needs_variable (XEXP (exp, 1), var))
 	return true;
       /* else fall through */
+      gcc_fallthrough ();
     case NOT:
       return needs_variable (XEXP (exp, 0), var);
 
diff --git gcc/gcc/genrecog.c gcc/gcc/genrecog.c
index a9f5a4a..1ef3cd1 100644
--- gcc/gcc/genrecog.c
+++ gcc/gcc/genrecog.c
@@ -380,6 +380,7 @@ find_operand (rtx pattern, int n, rtx stop)
 	  if (! XVEC (pattern, i))
 	    break;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case 'E':
 	  for (j = 0; j < XVECLEN (pattern, i); j++)
@@ -432,6 +433,7 @@ find_matching_operand (rtx pattern, int n)
 	  if (! XVEC (pattern, i))
 	    break;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case 'E':
 	  for (j = 0; j < XVECLEN (pattern, i); j++)
@@ -3831,6 +3833,7 @@ match_pattern_2 (state *s, md_rtx_info *info, position *pos, rtx pattern)
 	  /* Use the same code check as the original operand.  */
 	  pattern = find_operand (info->def, XINT (pattern, 0), NULL_RTX);
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case MATCH_PARALLEL:
 	case MATCH_OPERAND:
diff --git gcc/gcc/gensupport.c gcc/gcc/gensupport.c
index 0eb4591..e1a084b 100644
--- gcc/gcc/gensupport.c
+++ gcc/gcc/gensupport.c
@@ -517,6 +517,7 @@ process_rtx (rtx desc, file_location loc)
     case DEFINE_SPECIAL_PREDICATE:
       process_define_predicate (desc, loc);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case DEFINE_CONSTRAINT:
     case DEFINE_REGISTER_CONSTRAINT:
@@ -1019,6 +1020,7 @@ get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
 		    XINT (pattern, 0));
 	  return 0;
 	}
+      gcc_fallthrough ();
 
     default:
       break;
@@ -1038,6 +1040,8 @@ get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
 	case 'V':
 	  if (XVEC (pattern, i) == NULL)
 	    break;
+	  /* XXX Really fallthru?  */
+	  gcc_fallthrough ();
 
 	case 'E':
 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
@@ -1073,6 +1077,7 @@ collect_insn_data (rtx pattern, int *palt, int *pmax)
       i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
       *palt = (i > *palt ? i : *palt);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case MATCH_OPERATOR:
     case MATCH_PARALLEL:
@@ -1099,6 +1104,7 @@ collect_insn_data (rtx pattern, int *palt, int *pmax)
 	  if (XVEC (pattern, i) == NULL)
 	    break;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case 'E':
 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
 	    collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
@@ -1153,6 +1159,7 @@ alter_predicate_for_insn (rtx pattern, int alt, int max_op,
 	  }
       }
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case MATCH_OPERATOR:
     case MATCH_SCRATCH:
@@ -2156,6 +2163,8 @@ subst_dup (rtx pattern, int n_alt, int n_subst_alt)
 	case 'V':
 	  if (XVEC (pattern, i) == NULL)
 	    break;
+	  /* XXX Really fallthru?  */
+	  gcc_fallthrough ();
 	case 'E':
 	  if (code != MATCH_DUP && code != MATCH_OP_DUP)
 	    for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
@@ -2596,6 +2605,7 @@ read_md_rtx (md_rtx_info *info)
       record_insn_name (insn_sequence_num, XSTR (def, 0));
 
       /* Fall through.  */
+      gcc_fallthrough ();
     case DEFINE_PEEPHOLE:
       counter = &insn_sequence_num;
       break;
diff --git gcc/gcc/gimple-fold.c gcc/gcc/gimple-fold.c
index 36c105f..83cbdbc 100644
--- gcc/gcc/gimple-fold.c
+++ gcc/gcc/gimple-fold.c
@@ -1669,6 +1669,7 @@ gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
 	  }
       }
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case 1: /* length is greater than 1, call fwrite.  */
       {
 	/* If optimizing for size keep fputs.  */
@@ -3820,6 +3821,7 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
 				  swap_tree_comparison (gimple_cond_code (gc)));
 	    changed = true;
 	  }
+	gcc_fallthrough ();
       }
     default:;
     }
@@ -4655,6 +4657,7 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 		}
 	      return result;
 	    }
+	  gcc_fallthrough ();
 
 	default:
 	  break;
@@ -5119,6 +5122,7 @@ or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
 		}
 	      return result;
 	    }
+	  gcc_fallthrough ();
 
 	default:
 	  break;
@@ -5795,6 +5799,7 @@ fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
 	    }
 	}
       /* Fallthru.  */
+      gcc_fallthrough ();
 
     case COMPONENT_REF:
     case BIT_FIELD_REF:
diff --git gcc/gcc/gimple-pretty-print.c gcc/gcc/gimple-pretty-print.c
index 48edacc..7c12f84 100644
--- gcc/gcc/gimple-pretty-print.c
+++ gcc/gcc/gimple-pretty-print.c
@@ -517,8 +517,10 @@ dump_gimple_assign (pretty_printer *buffer, gassign *gs, int spc, int flags)
 	{
 	case 4:
 	  arg3 = gimple_assign_rhs3 (gs);
+	  gcc_fallthrough ();
 	case 3:
 	  arg2 = gimple_assign_rhs2 (gs);
+	  gcc_fallthrough ();
 	case 2:
 	  arg1 = gimple_assign_rhs1 (gs);
 	  break;
diff --git gcc/gcc/gimple-ssa-backprop.c gcc/gcc/gimple-ssa-backprop.c
index d96bcca..61c5e59 100644
--- gcc/gcc/gimple-ssa-backprop.c
+++ gcc/gcc/gimple-ssa-backprop.c
@@ -434,6 +434,7 @@ backprop::process_assign_use (gassign *assign, tree rhs, usage_info *info)
 	  && gimple_assign_rhs2 (assign) == rhs)
 	info->flags.ignore_sign = true;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case NEGATE_EXPR:
     case RDIV_EXPR:
diff --git gcc/gcc/gimple-ssa-strength-reduction.c gcc/gcc/gimple-ssa-strength-reduction.c
index 0824f17..9edf3df 100644
--- gcc/gcc/gimple-ssa-strength-reduction.c
+++ gcc/gcc/gimple-ssa-strength-reduction.c
@@ -1695,6 +1695,7 @@ find_candidates_dom_walker::before_dom_children (basic_block bb)
 	    case MINUS_EXPR:
 	      rhs2 = gimple_assign_rhs2 (gs);
 	      /* Fall-through.  */
+	      gcc_fallthrough ();
 
 	    CASE_CONVERT:
 	    case MODIFY_EXPR:
diff --git gcc/gcc/gimple-streamer-in.c gcc/gcc/gimple-streamer-in.c
index f706db9..2aa7aff 100644
--- gcc/gcc/gimple-streamer-in.c
+++ gcc/gcc/gimple-streamer-in.c
@@ -145,6 +145,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
 	asm_stmt->string = TREE_STRING_POINTER (str);
       }
       /* Fallthru  */
+      gcc_fallthrough ();
 
     case GIMPLE_ASSIGN:
     case GIMPLE_CALL:
diff --git gcc/gcc/gimple-streamer-out.c gcc/gcc/gimple-streamer-out.c
index 35124bd..1632a73 100644
--- gcc/gcc/gimple-streamer-out.c
+++ gcc/gcc/gimple-streamer-out.c
@@ -121,6 +121,7 @@ output_gimple_stmt (struct output_block *ob, gimple *stmt)
 			       gimple_asm_string (asm_stmt), true);
       }
       /* Fallthru  */
+      gcc_fallthrough ();
 
     case GIMPLE_ASSIGN:
     case GIMPLE_CALL:
diff --git gcc/gcc/gimple-walk.c gcc/gcc/gimple-walk.c
index be501c5..18e9787 100644
--- gcc/gcc/gimple-walk.c
+++ gcc/gcc/gimple-walk.c
@@ -646,6 +646,7 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt,
 	return wi->callback_result;
 
       /* FALL THROUGH.  */
+      gcc_fallthrough ();
     case GIMPLE_OMP_CRITICAL:
     case GIMPLE_OMP_MASTER:
     case GIMPLE_OMP_TASKGROUP:
diff --git gcc/gcc/gimple.c gcc/gcc/gimple.c
index e275dfc..ca9ec11 100644
--- gcc/gcc/gimple.c
+++ gcc/gcc/gimple.c
@@ -1818,6 +1818,7 @@ gimple_copy (gimple *stmt)
 	  t = unshare_expr (gimple_omp_sections_control (stmt));
 	  gimple_omp_sections_set_control (copy, t);
 	  /* FALLTHRU  */
+	  gcc_fallthrough ();
 
 	case GIMPLE_OMP_SINGLE:
 	case GIMPLE_OMP_TARGET:
diff --git gcc/gcc/gimplify.c gcc/gcc/gimplify.c
index 47c4d25..3b01cb4 100644
--- gcc/gcc/gimplify.c
+++ gcc/gcc/gimplify.c
@@ -1580,6 +1580,7 @@ warn_switch_unreachable_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
 	  return integer_zero_node;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case GIMPLE_BIND:
     case GIMPLE_CATCH:
     case GIMPLE_EH_FILTER:
@@ -3035,6 +3301,7 @@ gimple_boolify (tree expr)
       /* Also boolify the arguments of truth exprs.  */
       TREE_OPERAND (expr, 1) = gimple_boolify (TREE_OPERAND (expr, 1));
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case TRUTH_NOT_EXPR:
       TREE_OPERAND (expr, 0) = gimple_boolify (TREE_OPERAND (expr, 0));
@@ -4570,6 +4837,7 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
 		return GS_OK;
 	      }
 	  }
+	gcc_fallthrough ();
 
 	default:
 	  break;
@@ -5154,6 +5422,7 @@ gimplify_addr_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
 	goto do_indirect_ref;
 
       /* ... fall through ... */
+      gcc_fallthrough ();
 
     default:
       /* If we see a call to a declared builtin or see its address
@@ -6076,6 +6345,7 @@ omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
 	error_at (ctx->location, "enclosing %s", rtype);
       }
       /* FALLTHRU */
+      gcc_fallthrough ();
     case OMP_CLAUSE_DEFAULT_SHARED:
       flags |= GOVD_SHARED;
       break;
@@ -6118,6 +6388,7 @@ omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
 	flags |= GOVD_FIRSTPRIVATE;
       else
 	flags |= GOVD_SHARED;
+      gcc_fallthrough ();
     found_outer:
       break;
 
@@ -6639,6 +6910,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
       case OMP_TARGET_EXIT_DATA:
       case OACC_HOST_DATA:
 	ctx->target_firstprivatize_array_bases = true;
+	gcc_fallthrough ();
       default:
 	break;
       }
@@ -6904,6 +7176,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 	    case OACC_DATA:
 	      if (TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE)
 		break;
+	      /* XXX Really fallthru?  */
+	      gcc_fallthrough ();
 	    case OMP_TARGET_DATA:
 	    case OMP_TARGET_ENTER_DATA:
 	    case OMP_TARGET_EXIT_DATA:
@@ -7388,6 +7662,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 
 	do_add:
 	  decl = OMP_CLAUSE_DECL (c);
+	  gcc_fallthrough ();
 	do_add_decl:
 	  if (error_operand_p (decl))
 	    {
@@ -7521,6 +7796,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 			  "copyprivate variable %qE is not threadprivate"
 			  " or private in outer context", DECL_NAME (decl));
 	    }
+	  gcc_fallthrough ();
 	do_notice:
 	  if (outer_ctx)
 	    omp_notice_variable (outer_ctx, decl, true);
@@ -7569,11 +7845,13 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 	      remove = true;
 	    }
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case OMP_CLAUSE_FINAL:
 	  OMP_CLAUSE_OPERAND (c, 0)
 	    = gimple_boolify (OMP_CLAUSE_OPERAND (c, 0));
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case OMP_CLAUSE_SCHEDULE:
 	case OMP_CLAUSE_NUM_THREADS:
@@ -8605,6 +8883,7 @@ find_combined_omp_for (tree *tp, int *walk_subtrees, void *)
     case OMP_FOR:
       *walk_subtrees = 1;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case OMP_SIMD:
       if (OMP_FOR_INIT (*tp) != NULL_TREE)
 	return *tp;
@@ -9197,6 +9476,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
 		}
 
 	      /* Fallthru.  */
+	      gcc_fallthrough ();
 	    case MINUS_EXPR:
 	    case POINTER_PLUS_EXPR:
 	      gcc_assert (TREE_OPERAND (t, 0) == decl);
@@ -9928,6 +10208,8 @@ goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
     case tcc_comparison:
       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p, lhs_addr,
 				     lhs_var);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case tcc_unary:
       saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p, lhs_addr,
 				     lhs_var);
@@ -9942,6 +10224,8 @@ goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
 	case TRUTH_XOR_EXPR:
 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
 					 lhs_addr, lhs_var);
+	  /* XXX Really fallthru?  */
+	  gcc_fallthrough ();
 	case TRUTH_NOT_EXPR:
 	  saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
 					 lhs_addr, lhs_var);
@@ -10376,6 +10660,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	      break;
 	    }
 	  /* Fallthru.  */
+	  gcc_fallthrough ();
 
 	case ARRAY_REF:
 	case ARRAY_RANGE_REF:
@@ -10529,6 +10814,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	  if (*expr_p != save_expr)
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case FIX_TRUNC_EXPR:
 	  /* unary_expr: ... | '(' cast ')' val | ...  */
@@ -11183,6 +11465,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 	    }
 
 	  recalculate_side_effects (*expr_p);
+	  gcc_fallthrough ();
 
 	dont_recalculate:
 	  break;
diff --git gcc/gcc/godump.c gcc/gcc/godump.c
index e3448a1..a63743e 100644
--- gcc/gcc/godump.c
+++ gcc/gcc/godump.c
@@ -224,6 +224,7 @@ go_define (unsigned int lineno, const char *buffer)
 	  if (!ISDIGIT (p[1]))
 	    goto unknown;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case '0': case '1': case '2': case '3': case '4':
 	case '5': case '6': case '7': case '8': case '9':
 	  {
@@ -893,6 +894,7 @@ go_format_type (struct godump_container *container, tree type,
     case UNION_TYPE:
       is_union = true;
       /* Fall through to RECORD_TYPE case.  */
+      gcc_fallthrough ();
     case RECORD_TYPE:
       {
 	unsigned int prev_field_end;
diff --git gcc/gcc/graphite-isl-ast-to-gimple.c gcc/gcc/graphite-isl-ast-to-gimple.c
index fb9c846..48353d3 100644
--- gcc/gcc/graphite-isl-ast-to-gimple.c
+++ gcc/gcc/graphite-isl-ast-to-gimple.c
@@ -1485,6 +1485,7 @@ substitute_ssa_name (tree exp, tree f, tree r)
 	  return r;
 
 	/* Fall through...  */
+	gcc_fallthrough ();
 
       case tcc_exceptional:
       case tcc_unary:
diff --git gcc/gcc/haifa-sched.c gcc/gcc/haifa-sched.c
index 1f1e763..f713ecb 100644
--- gcc/gcc/haifa-sched.c
+++ gcc/gcc/haifa-sched.c
@@ -4246,6 +4246,7 @@ remove_notes (rtx_insn *head, rtx_insn *tail)
 	      break;
 	    }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	default:
 	  remove_insn (insn);
diff --git gcc/gcc/hsa-gen.c gcc/gcc/hsa-gen.c
index cf7d434..5395d93 100644
--- gcc/gcc/hsa-gen.c
+++ gcc/gcc/hsa-gen.c
@@ -4520,6 +4520,7 @@ get_address_from_value (tree val, hsa_bb *hbb)
       if (tree_fits_shwi_p (val))
 	return new hsa_op_address (NULL, NULL, tree_to_shwi (val));
       /* Otherwise fall-through */
+      gcc_fallthrough ();
 
     default:
       HSA_SORRY_ATV (EXPR_LOCATION (val),
@@ -5039,6 +5040,7 @@ gen_hsa_insn_for_internal_fn_call (gcall *stmt, hsa_bb *hbb)
     case IFN_FMIN:
     case IFN_FMAX:
       gen_hsa_insns_for_call_of_internal_fn (stmt, hbb);
+      gcc_fallthrough ();
 
     default:
       HSA_SORRY_ATV (gimple_location (stmt),
diff --git gcc/gcc/internal-fn.c gcc/gcc/internal-fn.c
index 49f3495..7e51255 100644
--- gcc/gcc/internal-fn.c
+++ gcc/gcc/internal-fn.c
@@ -1834,6 +1834,7 @@ expand_arith_overflow (enum tree_code code, gimple *stmt)
 	      if (integer_zerop (arg0) && !unsr_p)
 		expand_neg_overflow (loc, lhs, arg1, false);
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 	    case PLUS_EXPR:
 	      expand_addsub_overflow (loc, code, lhs, arg0, arg1,
 				      unsr_p, unsr_p, unsr_p, false);
diff --git gcc/gcc/ipa-icf.c gcc/gcc/ipa-icf.c
index 3c04b5a..3760d55 100644
--- gcc/gcc/ipa-icf.c
+++ gcc/gcc/ipa-icf.c
@@ -1644,6 +1644,7 @@ sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
 	  break;
 	}
       /* ... fall through ... */
+      gcc_fallthrough ();
     case GIMPLE_CALL:
     case GIMPLE_ASM:
     case GIMPLE_COND:
@@ -1656,6 +1657,7 @@ sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
 	  if (gimple_op (stmt, i))
 	    add_type (TREE_TYPE (gimple_op (stmt, i)), hstate);
 	}
+      gcc_fallthrough ();
     default:
       break;
     }
diff --git gcc/gcc/ira.c gcc/gcc/ira.c
index c66bb9e..9274504 100644
--- gcc/gcc/ira.c
+++ gcc/gcc/ira.c
@@ -1832,6 +1832,7 @@ ira_setup_alts (rtx_insn *insn, HARD_REG_SET &alts)
 		  case '#':
 		  case ',':
 		    c = '\0';
+		    gcc_fallthrough ();
 		  case '\0':
 		    len = 0;
 		    break;
@@ -3045,6 +3046,7 @@ equiv_init_varies_p (rtx x)
 	return 1;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       break;
@@ -3110,6 +3112,7 @@ equiv_init_movable_p (rtx x, int regno)
 	return 0;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       break;
diff --git gcc/gcc/jump.c gcc/gcc/jump.c
index 5b433af..a3d8bc7 100644
--- gcc/gcc/jump.c
+++ gcc/gcc/jump.c
@@ -1889,6 +1889,7 @@ rtx_renumbered_equal_p (const_rtx x, const_rtx y)
 	  if (XEXP (x, i) != XEXP (y, i))
 	    return 0;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case '0':
 	  break;
 
diff --git gcc/gcc/lra-eliminations.c gcc/gcc/lra-eliminations.c
index 9ae5cfe..b21facf 100644
--- gcc/gcc/lra-eliminations.c
+++ gcc/gcc/lra-eliminations.c
@@ -485,6 +485,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
 	}
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case CALL:
     case COMPARE:
@@ -537,6 +538,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
 	}
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case INSN_LIST:
     case INT_LIST:
diff --git gcc/gcc/lto-streamer-in.c gcc/gcc/lto-streamer-in.c
index 00db94e..14b6916 100644
--- gcc/gcc/lto-streamer-in.c
+++ gcc/gcc/lto-streamer-in.c
@@ -1614,6 +1614,7 @@ lto_input_mode_table (struct lto_file_decl_data *file_data)
 		  break;
 		}
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 	    default:
 	      fatal_error (UNKNOWN_LOCATION, "unsupported mode %s\n", mname);
 	      break;
diff --git gcc/gcc/lto-streamer-out.c gcc/gcc/lto-streamer-out.c
index ed6f748..375264b 100644
--- gcc/gcc/lto-streamer-out.c
+++ gcc/gcc/lto-streamer-out.c
@@ -231,6 +231,7 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
     case VAR_DECL:
     case DEBUG_EXPR_DECL:
       gcc_assert (decl_function_context (expr) == NULL || TREE_STATIC (expr));
+      gcc_fallthrough ();
     case PARM_DECL:
       streamer_write_record_start (ob, LTO_global_decl_ref);
       lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
diff --git gcc/gcc/lto-wrapper.c gcc/gcc/lto-wrapper.c
index f240812..2c4aa11 100644
--- gcc/gcc/lto-wrapper.c
+++ gcc/gcc/lto-wrapper.c
@@ -234,6 +234,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
 	    break;
 
 	  /* Fallthru.  */
+	  gcc_fallthrough ();
 	case OPT_fdiagnostics_show_caret:
 	case OPT_fdiagnostics_show_option:
 	case OPT_fdiagnostics_show_location_:
@@ -1077,6 +1078,7 @@ run_gcc (unsigned argc, char *argv[])
 		parallel = 0;
 	    }
 	  /* Fallthru.  */
+	  gcc_fallthrough ();
 
 	case OPT_flto:
 	  lto_mode = LTO_MODE_WHOPR;
diff --git gcc/gcc/mode-switching.c gcc/gcc/mode-switching.c
index 121b970..e46f2f2 100644
--- gcc/gcc/mode-switching.c
+++ gcc/gcc/mode-switching.c
@@ -303,6 +303,7 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
 			  break;
 
 			/* Fall through.  */
+			gcc_fallthrough ();
 
 		      case ASM_INPUT:
 		      case UNSPEC_VOLATILE:
diff --git gcc/gcc/omp-low.c gcc/gcc/omp-low.c
index b89978f..386c453 100644
--- gcc/gcc/omp-low.c
+++ gcc/gcc/omp-low.c
@@ -1945,10 +1945,12 @@ scan_sharing_clauses (tree clauses, omp_context *ctx,
 	  if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case OMP_CLAUSE_FIRSTPRIVATE:
 	case OMP_CLAUSE_LINEAR:
 	  decl = OMP_CLAUSE_DECL (c);
+	  gcc_fallthrough ();
 	do_private:
 	  if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
 	       || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
@@ -2218,6 +2220,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx,
 	  if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case OMP_CLAUSE_FIRSTPRIVATE:
 	case OMP_CLAUSE_PRIVATE:
@@ -3360,6 +3363,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
 	    }
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case GIMPLE_CALL:
       if (is_gimple_call (stmt)
 	  && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
@@ -3466,6 +3470,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
 			      != GF_OMP_TARGET_KIND_REGION)
 			    continue;
 			  /* FALLTHRU */
+			  gcc_fallthrough ();
 			case GIMPLE_OMP_PARALLEL:
 			case GIMPLE_OMP_TEAMS:
 			  error_at (gimple_location (stmt),
@@ -3495,6 +3500,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
 	    }
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case GIMPLE_OMP_SECTIONS:
     case GIMPLE_OMP_SINGLE:
       for (; ctx != NULL; ctx = ctx->outer)
@@ -3505,6 +3511,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
 		&& gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
 	      break;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case GIMPLE_OMP_SECTIONS:
 	  case GIMPLE_OMP_SINGLE:
 	  case GIMPLE_OMP_ORDERED:
@@ -3549,6 +3556,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
 		&& gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_TASKLOOP)
 	      break;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case GIMPLE_OMP_SECTIONS:
 	  case GIMPLE_OMP_SINGLE:
 	  case GIMPLE_OMP_TASK:
@@ -3671,6 +3679,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
 		!= GF_OMP_TARGET_KIND_REGION)
 	      break;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case GIMPLE_OMP_PARALLEL:
 	  case GIMPLE_OMP_TEAMS:
 	    error_at (gimple_location (stmt),
@@ -4388,6 +4397,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 	  if (OMP_CLAUSE_LINEAR_ARRAY (c))
 	    max_vf = 1;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case OMP_CLAUSE_PRIVATE:
 	case OMP_CLAUSE_FIRSTPRIVATE:
 	case OMP_CLAUSE_LASTPRIVATE:
@@ -4432,6 +4442,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 			      || is_global_var (OMP_CLAUSE_DECL (c)));
 		  continue;
 		}
+	      gcc_fallthrough ();
 	    case OMP_CLAUSE_FIRSTPRIVATE:
 	    case OMP_CLAUSE_COPYIN:
 	      break;
@@ -4930,6 +4941,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 	      if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
 		break;
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 
 	    case OMP_CLAUSE_PRIVATE:
 	      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
@@ -4943,6 +4955,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 		}
 	      else
 		x = NULL;
+	      /* XXX Really fallthru?  */
+	      gcc_fallthrough ();
 	    do_private:
 	      tree nx;
 	      nx = lang_hooks.decls.omp_clause_default_ctor
@@ -4978,6 +4992,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 	      if (nx)
 		gimplify_and_add (nx, ilist);
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 
 	    do_dtor:
 	      x = lang_hooks.decls.omp_clause_dtor (c, new_var);
@@ -5015,6 +5030,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
 		      goto do_dtor;
 		    }
 		}
+	      /* XXX Really fallthru?  */
+	      gcc_fallthrough ();
 	    do_firstprivate:
 	      x = build_outer_var_ref (var, ctx);
 	      if (is_simd)
@@ -6535,6 +6552,7 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
 		  break;
 		}
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 	    default:
 	      start_ix2 = region->inner->sched_kind;
 	      break;
@@ -11602,6 +11620,7 @@ expand_omp_for (struct omp_region *region, gimple *inner_stmt)
 	      break;
 	    }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	default:
 	  fn_index = fd.sched_kind;
 	  break;
@@ -13246,6 +13265,7 @@ expand_omp_target (struct omp_region *region)
     case GF_OMP_TARGET_KIND_OACC_KERNELS:
       oacc_kernels_p = true;
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
       start_ix = BUILT_IN_GOACC_PARALLEL;
       break;
@@ -13406,6 +13426,7 @@ expand_omp_target (struct omp_region *region)
 	tagging = true;
       }
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BUILT_IN_GOACC_ENTER_EXIT_DATA:
     case BUILT_IN_GOACC_UPDATE:
       {
@@ -13830,6 +13851,7 @@ expand_omp (struct omp_region *region)
 	      }
 	  }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case GIMPLE_OMP_MASTER:
 	case GIMPLE_OMP_TASKGROUP:
 	case GIMPLE_OMP_CRITICAL:
@@ -16208,6 +16230,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 		      break;
 		    case GOMP_MAP_DELETE:
 		      tkind_zero = GOMP_MAP_DELETE_ZERO_LEN_ARRAY_SECTION;
+		      gcc_fallthrough ();
 		    default:
 		      break;
 		    }
@@ -17076,6 +17099,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 	    if (ctx == NULL)
 	      break;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case BUILT_IN_GOMP_CANCEL:
 	  case BUILT_IN_GOMP_CANCELLATION_POINT:
 	    omp_context *cctx;
@@ -17117,6 +17141,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 	    break;
 	  }
       /* FALLTHRU */
+      gcc_fallthrough ();
     default:
       if ((ctx || task_shared_vars)
 	  && walk_gimple_op (stmt, lower_omp_regimplify_p,
diff --git gcc/gcc/optabs.c gcc/gcc/optabs.c
index 2bd81db..7af4236 100644
--- gcc/gcc/optabs.c
+++ gcc/gcc/optabs.c
@@ -147,6 +147,7 @@ add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op
 	    break;
 	  }
 	/* FALLTHRU */
+	gcc_fallthrough ();
       default:
 	note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
 	break;
diff --git gcc/gcc/opts.c gcc/gcc/opts.c
index f09c520..7143f91 100644
--- gcc/gcc/opts.c
+++ gcc/gcc/opts.c
@@ -1979,6 +1979,7 @@ common_handle_option (struct gcc_options *opts,
       opts->x_flag_profile_use = true;
       value = true;
       /* No break here - do -fprofile-use processing. */
+      gcc_fallthrough ();
     case OPT_fprofile_use:
       enable_fdo_optimizations (opts, opts_set, value);
       if (!opts_set->x_flag_profile_reorder_functions)
@@ -1995,6 +1996,7 @@ common_handle_option (struct gcc_options *opts,
       opts->x_flag_auto_profile = true;
       value = true;
       /* No break here - do -fauto-profile processing. */
+      gcc_fallthrough ();
     case OPT_fauto_profile:
       enable_fdo_optimizations (opts, opts_set, value);
       if (!opts_set->x_flag_profile_correction)
@@ -2008,6 +2010,7 @@ common_handle_option (struct gcc_options *opts,
       opts->x_profile_data_prefix = xstrdup (arg);
       value = true;
       /* No break here - do -fprofile-generate processing. */
+      gcc_fallthrough ();
     case OPT_fprofile_generate:
       if (!opts_set->x_profile_arc_flag)
 	opts->x_profile_arc_flag = value;
@@ -2118,6 +2121,7 @@ common_handle_option (struct gcc_options *opts,
         value = opts->x_dwarf_version;
       
       /* FALLTHRU */
+      gcc_fallthrough ();
     case OPT_gdwarf_:
       if (value < 2 || value > 5)
 	error_at (loc, "dwarf version %d is not supported", value);
diff --git gcc/gcc/plugin.c gcc/gcc/plugin.c
index 60081a5..bc92b96 100644
--- gcc/gcc/plugin.c
+++ gcc/gcc/plugin.c
@@ -427,6 +427,7 @@ register_callback (const char *plugin_name,
 	    return;
 	  }
       /* Fall through.  */
+      gcc_fallthrough ();
       case PLUGIN_START_PARSE_FUNCTION:
       case PLUGIN_FINISH_PARSE_FUNCTION:
       case PLUGIN_FINISH_TYPE:
@@ -506,7 +507,8 @@ invoke_plugin_callbacks_full (int event, void *gcc_data)
       default:
 	gcc_assert (event >= PLUGIN_EVENT_FIRST_DYNAMIC);
 	gcc_assert (event < event_last);
-      /* Fall through.  */
+	/* Fall through.  */
+	gcc_fallthrough ();
       case PLUGIN_START_PARSE_FUNCTION:
       case PLUGIN_FINISH_PARSE_FUNCTION:
       case PLUGIN_FINISH_TYPE:
diff --git gcc/gcc/postreload.c gcc/gcc/postreload.c
index 61c1ce8..b6269da 100644
--- gcc/gcc/postreload.c
+++ gcc/gcc/postreload.c
@@ -1525,6 +1525,7 @@ reload_combine_note_use (rtx *xp, rtx_insn *insn, int ruid, rtx containing_mem)
       offset = XEXP (x, 1);
       x = XEXP (x, 0);
       /* Fall through.  */
+      gcc_fallthrough ();
     case REG:
       {
 	int regno = REGNO (x);
diff --git gcc/gcc/pretty-print.c gcc/gcc/pretty-print.c
index 325263e..f09bdae 100644
--- gcc/gcc/pretty-print.c
+++ gcc/gcc/pretty-print.c
@@ -187,6 +187,7 @@ pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record)
 	     backslash as last char in label.  Let's avoid triggering it.  */
 	  gcc_assert (*(p + 1) != '\0');
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case '"':
 	  escape_char = true;
 	  break;
@@ -372,6 +373,7 @@ pp_format (pretty_printer *pp, text_info *text)
 	    obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
 	  }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case '\'':
 	  obstack_grow (&buffer->chunk_obstack,
 			close_quote, strlen (close_quote));
@@ -788,6 +790,7 @@ pp_emit_prefix (pretty_printer *pp)
 	    }
 	  pp_indentation (pp) += 3;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
 	  {
diff --git gcc/gcc/print-rtl.c gcc/gcc/print-rtl.c
index a905127..b9d7cf4 100644
--- gcc/gcc/print-rtl.c
+++ gcc/gcc/print-rtl.c
@@ -217,6 +217,7 @@ print_rtx (const_rtx in_rtx)
       case 'S':
       case 's':
 	str = XSTR (in_rtx, i);
+	gcc_fallthrough ();
       string:
 
 	if (str == 0)
diff --git gcc/gcc/read-rtl.c gcc/gcc/read-rtl.c
index dc3a336..800f31d 100644
--- gcc/gcc/read-rtl.c
+++ gcc/gcc/read-rtl.c
@@ -1163,6 +1163,7 @@ read_rtx_code (const char *code_name)
 	    break;
 	  }
 	/* Now process the vector.  */
+	gcc_fallthrough ();
 
       case 'E':
 	{
diff --git gcc/gcc/real.c gcc/gcc/real.c
index fbebbf0..39900e5 100644
--- gcc/gcc/real.c
+++ gcc/gcc/real.c
@@ -928,6 +928,7 @@ do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
       if (a->decimal)
 	return decimal_do_compare (a, b, nan_result);
       /* Fall through.  */
+      gcc_fallthrough ();
     case CLASS2 (rvc_inf, rvc_zero):
     case CLASS2 (rvc_inf, rvc_normal):
       return (a->sign ? -1 : 1);
@@ -940,6 +941,7 @@ do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
       if (b->decimal)
 	return decimal_do_compare (a, b, nan_result);
       /* Fall through.  */
+      gcc_fallthrough ();
     case CLASS2 (rvc_zero, rvc_inf):
     case CLASS2 (rvc_normal, rvc_inf):
       return (b->sign ? 1 : -1);
@@ -2667,6 +2669,7 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
     {
     underflow:
       get_zero (r, r->sign);
+      gcc_fallthrough ();
     case rvc_zero:
       if (!fmt->has_signed_zero)
 	r->sign = 0;
@@ -2674,6 +2677,7 @@ round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
 
     overflow:
       get_inf (r, r->sign);
+      gcc_fallthrough ();
     case rvc_inf:
       return;
 
diff --git gcc/gcc/recog.c gcc/gcc/recog.c
index 80d1779..f400a6e 100644
--- gcc/gcc/recog.c
+++ gcc/gcc/recog.c
@@ -1792,6 +1792,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints)
 
 	     Match any memory and hope things are resolved after reload.  */
 	  incdec_ok = true;
+	  gcc_fallthrough ();
 	default:
 	  cn = lookup_constraint (constraint);
 	  switch (get_constraint_type (cn))
diff --git gcc/gcc/reg-stack.c gcc/gcc/reg-stack.c
index c931349..547e8dd 100644
--- gcc/gcc/reg-stack.c
+++ gcc/gcc/reg-stack.c
@@ -424,6 +424,8 @@ get_true_reg (rtx *pat)
 	      return pat;
 	    }
 	}
+	/* XXX Really fallthru?  */
+	gcc_fallthrough ();
       case FLOAT:
       case FIX:
       case FLOAT_EXTEND:
@@ -1490,6 +1492,7 @@ subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat)
 	    src1 = src;
 
 	    /* Fall through.  */
+	    gcc_fallthrough ();
 
 	  case FLOAT_TRUNCATE:
 	  case SQRT:
@@ -1751,6 +1754,7 @@ subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat)
 
 		regstack->top++;
 		/* FALLTHRU */
+		gcc_fallthrough ();
 
 	      case UNSPEC_TAN:
 
@@ -1880,6 +1884,7 @@ subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat)
 		gcc_assert (GET_CODE (pat_src) == UNSPEC);
 		gcc_assert (XINT (pat_src, 1) == UNSPEC_FNSTSW);
 		/* Fall through.  */
+		gcc_fallthrough ();
 
 	      case UNSPEC_FNSTSW:
 		/* Combined fcomp+fnstsw generated for doing well with
diff --git gcc/gcc/reginfo.c gcc/gcc/reginfo.c
index f4dac08..90e47fd 100644
--- gcc/gcc/reginfo.c
+++ gcc/gcc/reginfo.c
@@ -1150,6 +1150,7 @@ reg_scan_mark_refs (rtx x, rtx_insn *insn)
 	set_reg_attrs_from_value (dest, SET_SRC (x));
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     default:
       {
diff --git gcc/gcc/reload1.c gcc/gcc/reload1.c
index 5622e89..f657b25 100644
--- gcc/gcc/reload1.c
+++ gcc/gcc/reload1.c
@@ -2331,6 +2331,7 @@ set_label_offsets (rtx x, rtx_insn *insn, int initial_p)
       x = LABEL_REF_LABEL (x);
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case CODE_LABEL:
       /* If we know nothing about this label, set the desired offsets.  Note
@@ -2378,6 +2379,7 @@ set_label_offsets (rtx x, rtx_insn *insn, int initial_p)
       set_label_offsets (PATTERN (insn), insn, initial_p);
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case INSN:
     case CALL_INSN:
@@ -2693,6 +2695,7 @@ eliminate_regs_1 (rtx x, machine_mode mem_mode, rtx insn,
 	    }
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case CALL:
     case COMPARE:
@@ -2740,6 +2743,7 @@ eliminate_regs_1 (rtx x, machine_mode mem_mode, rtx insn,
 	}
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case INSN_LIST:
     case INT_LIST:
@@ -3032,6 +3036,7 @@ elimination_effects (rtx x, machine_mode mem_mode)
 	break;
 
       /* Fall through to generic unary operation case.  */
+      gcc_fallthrough ();
     case STRICT_LOW_PART:
     case NEG:          case NOT:
     case SIGN_EXTEND:  case ZERO_EXTEND:
@@ -5502,6 +5507,7 @@ reload_reg_reaches_end_p (unsigned int regno, int reloadnum)
       opnum = reload_n_operands;
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case RELOAD_FOR_OUTPUT:
     case RELOAD_FOR_OUTPUT_ADDRESS:
@@ -6846,6 +6852,7 @@ choose_reload_regs (struct insn_chain *chain)
 			if (! rld[r].optional)
 			  reload_override_in[r] = equiv;
 			/* Fall through.  */
+			gcc_fallthrough ();
 		      default:
 			equiv = 0;
 			break;
@@ -6864,6 +6871,7 @@ choose_reload_regs (struct insn_chain *chain)
 			if (! rld[r].optional)
 			  reload_override_in[r] = equiv;
 			/* Fall through.  */
+			gcc_fallthrough ();
 		      default:
 			equiv = 0;
 			break;
diff --git gcc/gcc/resource.c gcc/gcc/resource.c
index ae2f5d8..512742f 100644
--- gcc/gcc/resource.c
+++ gcc/gcc/resource.c
@@ -364,6 +364,7 @@ mark_referenced_resources (rtx x, struct resources *res,
 	}
 
       /* ... fall through to other INSN processing ...  */
+      gcc_fallthrough ();
 
     case INSN:
     case JUMP_INSN:
@@ -478,6 +479,7 @@ find_dead_or_set_registers (rtx_insn *target, struct resources *res,
 		    break;
 		}
 	    }
+	  gcc_fallthrough ();
 
 	default:
 	  break;
@@ -674,6 +676,7 @@ mark_set_resources (rtx x, struct resources *res, int in_dest,
 	}
 
       /* ... and also what its RTL says it modifies, if anything.  */
+      gcc_fallthrough ();
 
     case JUMP_INSN:
     case INSN:
diff --git gcc/gcc/rtlanal.c gcc/gcc/rtlanal.c
index 8e4762c..8fdb2c0 100644
--- gcc/gcc/rtlanal.c
+++ gcc/gcc/rtlanal.c
@@ -233,6 +233,7 @@ rtx_unstable_p (const_rtx x)
 	return 1;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       break;
@@ -315,6 +316,7 @@ rtx_varies_p (const_rtx x, bool for_alias)
 	return 1;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       break;
@@ -1765,6 +1767,7 @@ reg_overlap_mentioned_p (const_rtx x, const_rtx in)
     case REG:
       regno = REGNO (x);
       endregno = END_REGNO (x);
+      gcc_fallthrough ();
     do_reg:
       return refers_to_regno_p (regno, endregno, in, (rtx*) 0);
 
@@ -2516,6 +2519,7 @@ volatile_insn_p (const_rtx x)
     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
 	return 1;
+      gcc_fallthrough ();
 
     default:
       break;
@@ -2576,6 +2580,7 @@ volatile_refs_p (const_rtx x)
     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
 	return 1;
+      gcc_fallthrough ();
 
     default:
       break;
@@ -2649,6 +2654,7 @@ side_effects_p (const_rtx x)
     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
 	return 1;
+      gcc_fallthrough ();
 
     default:
       break;
@@ -3421,6 +3427,7 @@ commutative_operand_precedence (rtx op)
       /* Then prefer NEG and NOT.  */
       if (code == NEG || code == NOT)
         return 1;
+      gcc_fallthrough ();
 
     default:
       return 0;
@@ -3453,6 +3460,7 @@ auto_inc_p (const_rtx x)
       /* There are no REG_INC notes for SP.  */
       if (XEXP (x, 0) != stack_pointer_rtx)
 	return 1;
+      gcc_fallthrough ();
     default:
       break;
     }
@@ -4096,6 +4104,7 @@ rtx_cost (rtx x, machine_mode mode, enum rtx_code outer_code,
       if (factor == 0)
 	factor = 1;
       /* Pass through.  */
+      gcc_fallthrough ();
     default:
       total = factor * COSTS_N_INSNS (1);
     }
diff --git gcc/gcc/sched-deps.c gcc/gcc/sched-deps.c
index 41a6af2..1f1d077 100644
--- gcc/gcc/sched-deps.c
+++ gcc/gcc/sched-deps.c
@@ -2744,6 +2744,7 @@ sched_analyze_2 (struct deps_desc *deps, rtx x, rtx_insn *insn)
     case UNSPEC_VOLATILE:
       flush_pending_lists (deps, insn, true, true);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case ASM_OPERANDS:
     case ASM_INPUT:
diff --git gcc/gcc/sched-ebb.c gcc/gcc/sched-ebb.c
index 89dd823..abb737e 100644
--- gcc/gcc/sched-ebb.c
+++ gcc/gcc/sched-ebb.c
@@ -416,6 +416,7 @@ add_deps_for_risky_insns (rtx_insn *head, rtx_insn *tail)
 		    }
 		}
 	      /* Fall through.  */
+	      gcc_fallthrough ();
 	    case TRAP_RISKY:
 	    case IRISKY:
 	    case PRISKY_CANDIDATE:
diff --git gcc/gcc/sched-rgn.c gcc/gcc/sched-rgn.c
index fa662ff..03c0e13 100644
--- gcc/gcc/sched-rgn.c
+++ gcc/gcc/sched-rgn.c
@@ -2052,6 +2052,7 @@ is_exception_free (rtx_insn *insn, int bb_src, int bb_trg)
       if (is_pfree (insn, bb_src, bb_trg))
 	return 1;
       /* Don't 'break' here: PFREE-candidate is also PRISKY-candidate.  */
+      gcc_fallthrough ();
     case PRISKY_CANDIDATE:
       if (!flag_schedule_speculative_load_dangerous
 	  || is_prisky (insn, bb_src, bb_trg))
diff --git gcc/gcc/simplify-rtx.c gcc/gcc/simplify-rtx.c
index a23a6f5..eeb4018 100644
--- gcc/gcc/simplify-rtx.c
+++ gcc/gcc/simplify-rtx.c
@@ -3263,6 +3263,7 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
 							- INTVAL (trueop1)));
 #endif
       /* FALLTHRU */
+      gcc_fallthrough ();
     case ASHIFTRT:
       if (trueop1 == CONST0_RTX (mode))
 	return op0;
@@ -3308,6 +3309,7 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
 				     tmp);
 	  return lowpart_subreg (mode, tmp, inner_mode);
 	}
+      gcc_fallthrough ();
     canonicalize_shift:
       if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
 	{
@@ -6254,6 +6256,7 @@ simplify_rtx (const_rtx x)
 	return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
 
       /* Fall through....  */
+      gcc_fallthrough ();
 
     case RTX_BIN_ARITH:
       return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
diff --git gcc/gcc/stmt.c gcc/gcc/stmt.c
index 2e9072f..8202181 100644
--- gcc/gcc/stmt.c
+++ gcc/gcc/stmt.c
@@ -418,6 +418,7 @@ parse_input_constraint (const char **constraint_p, int input_num,
 	  j--;
 	}
 	/* Fall through.  */
+      gcc_fallthrough ();
 
       case 'g':  case 'X':
 	*allows_reg = true;
diff --git gcc/gcc/stor-layout.c gcc/gcc/stor-layout.c
index d66d769..8ffec99 100644
--- gcc/gcc/stor-layout.c
+++ gcc/gcc/stor-layout.c
@@ -399,6 +399,7 @@ int_mode_for_mode (machine_mode mode)
 	break;
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case MODE_CC:
     default:
diff --git gcc/gcc/toplev.c gcc/gcc/toplev.c
index da80097..869ad9b 100644
--- gcc/gcc/toplev.c
+++ gcc/gcc/toplev.c
@@ -732,6 +732,7 @@ print_to_asm_out_file (print_switch_type type, const char * text)
       if (ASM_COMMENT_START[0] == 0)
 	prepend_sep = false;
       /* Drop through.  */
+      gcc_fallthrough ();
     case SWITCH_TYPE_PASSED:
     case SWITCH_TYPE_ENABLED:
       if (prepend_sep)
@@ -762,6 +763,7 @@ print_to_stderr (print_switch_type type, const char * text)
     case SWITCH_TYPE_ENABLED:
       fputc (' ', stderr);
       /* Drop through.  */
+      gcc_fallthrough ();
 
     case SWITCH_TYPE_DESCRIPTIVE:
       fputs (text, stderr);
diff --git gcc/gcc/trans-mem.c gcc/gcc/trans-mem.c
index 2a6e101..920f618 100644
--- gcc/gcc/trans-mem.c
+++ gcc/gcc/trans-mem.c
@@ -174,12 +174,14 @@ get_attrs_for (const_tree x)
       if (TREE_CODE (x) != POINTER_TYPE)
 	return NULL_TREE;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case POINTER_TYPE:
       x = TREE_TYPE (x);
       if (TREE_CODE (x) != FUNCTION_TYPE && TREE_CODE (x) != METHOD_TYPE)
 	return NULL_TREE;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case FUNCTION_TYPE:
     case METHOD_TYPE:
@@ -208,6 +210,7 @@ is_tm_pure (const_tree x)
       if (TREE_CODE (x) != POINTER_TYPE)
 	return false;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case POINTER_TYPE:
       x = TREE_TYPE (x);
@@ -1548,6 +1551,7 @@ requires_barrier (basic_block entry_block, tree x, gimple *stmt)
 	return false;
       gcc_assert (TREE_CODE (x) == VAR_DECL);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case PARM_DECL:
     case RESULT_DECL:
diff --git gcc/gcc/tree-cfg.c gcc/gcc/tree-cfg.c
index 0fac49c..7f75eb1 100644
--- gcc/gcc/tree-cfg.c
+++ gcc/gcc/tree-cfg.c
@@ -2995,6 +2995,7 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
       t = TREE_OPERAND (t, 0);
 
       /* Fall-through.  */
+      gcc_fallthrough ();
     case COMPONENT_REF:
     case ARRAY_REF:
     case ARRAY_RANGE_REF:
@@ -3064,6 +3065,7 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
 	  return t;
 	}
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case LT_EXPR:
     case LE_EXPR:
     case GT_EXPR:
@@ -4040,6 +4042,7 @@ verify_gimple_assign_ternary (gassign *stmt)
 	  return true;
 	}
       /* Fallthrough.  */
+      gcc_fallthrough ();
     case COND_EXPR:
       if (!useless_type_conversion_p (lhs_type, rhs2_type)
 	  || !useless_type_conversion_p (lhs_type, rhs3_type))
@@ -5413,6 +5416,7 @@ gimple_verify_flow_info (void)
 	  if (!gimple_call_builtin_p (stmt, BUILT_IN_RETURN))
 	    break;
 	  /* ... fallthru ... */
+	  gcc_fallthrough ();
 	case GIMPLE_RETURN:
 	  if (!single_succ_p (bb)
 	      || (single_succ_edge (bb)->flags
@@ -6698,6 +6702,7 @@ move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
 	      r = move_stmt_eh_region_tree_nr (r, p);
 	      gimple_call_set_arg (stmt, 1, r);
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 
 	    case BUILT_IN_EH_POINTER:
 	    case BUILT_IN_EH_FILTER:
diff --git gcc/gcc/tree-chrec.c gcc/gcc/tree-chrec.c
index ee789a2..85959c1 100644
--- gcc/gcc/tree-chrec.c
+++ gcc/gcc/tree-chrec.c
@@ -287,6 +287,7 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
 	CASE_CONVERT:
 	  if (tree_contains_chrecs (op1, NULL))
 	    return chrec_dont_know;
+	  gcc_fallthrough ();
 
 	default:
 	  if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
@@ -304,6 +305,7 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
     CASE_CONVERT:
       if (tree_contains_chrecs (op0, NULL))
 	return chrec_dont_know;
+      gcc_fallthrough ();
 
     default:
       switch (TREE_CODE (op1))
@@ -329,6 +331,7 @@ chrec_fold_plus_1 (enum tree_code code, tree type,
 	CASE_CONVERT:
 	  if (tree_contains_chrecs (op1, NULL))
 	    return chrec_dont_know;
+	  gcc_fallthrough ();
 
 	default:
 	  {
@@ -423,6 +426,7 @@ chrec_fold_multiply (tree type,
 	CASE_CONVERT:
 	  if (tree_contains_chrecs (op1, NULL))
 	    return chrec_dont_know;
+	  gcc_fallthrough ();
 
 	default:
 	  if (integer_onep (op1))
@@ -439,6 +443,7 @@ chrec_fold_multiply (tree type,
     CASE_CONVERT:
       if (tree_contains_chrecs (op0, NULL))
 	return chrec_dont_know;
+      gcc_fallthrough ();
 
     default:
       if (integer_onep (op0))
@@ -461,6 +466,7 @@ chrec_fold_multiply (tree type,
 	CASE_CONVERT:
 	  if (tree_contains_chrecs (op1, NULL))
 	    return chrec_dont_know;
+	  gcc_fallthrough ();
 
 	default:
 	  if (integer_onep (op1))
@@ -1026,6 +1032,7 @@ evolution_function_is_invariant_rec_p (tree chrec, int loopnum)
       if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 1),
 						  loopnum))
 	return false;
+      gcc_fallthrough ();
 
     case 1:
       if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 0),
@@ -1527,12 +1534,15 @@ for_each_scev_op (tree *scev, bool (*cbck) (tree *, void *), void *data)
     {
     case 3:
       for_each_scev_op (&TREE_OPERAND (*scev, 2), cbck, data);
+      gcc_fallthrough ();
 
     case 2:
       for_each_scev_op (&TREE_OPERAND (*scev, 1), cbck, data);
+      gcc_fallthrough ();
 
     case 1:
       for_each_scev_op (&TREE_OPERAND (*scev, 0), cbck, data);
+      gcc_fallthrough ();
 
     default:
       cbck (scev, data);
diff --git gcc/gcc/tree-complex.c gcc/gcc/tree-complex.c
index d7baf22..0c90f63 100644
--- gcc/gcc/tree-complex.c
+++ gcc/gcc/tree-complex.c
@@ -1336,6 +1336,8 @@ expand_complex_division (gimple_stmt_iterator *gsi, tree inner_type,
       rr = gimplify_build2 (gsi, code, inner_type, ai, bi);
       ri = gimplify_build2 (gsi, code, inner_type, ar, bi);
       ri = gimplify_build1 (gsi, NEGATE_EXPR, inner_type, ri);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     case PAIR (ONLY_REAL, VARYING):
     case PAIR (ONLY_IMAG, VARYING):
@@ -1354,6 +1356,7 @@ expand_complex_division (gimple_stmt_iterator *gsi, tree inner_type,
 	      break;
 	    }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case 1:
 	  /* wide ranges of inputs must work for complex divide.  */
diff --git gcc/gcc/tree-data-ref.c gcc/gcc/tree-data-ref.c
index ed28ca1..5b0c4b2 100644
--- gcc/gcc/tree-data-ref.c
+++ gcc/gcc/tree-data-ref.c
@@ -591,6 +591,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
     case POINTER_PLUS_EXPR:
       ocode = PLUS_EXPR;
       /* FALLTHROUGH */
+      gcc_fallthrough ();
     case PLUS_EXPR:
     case MINUS_EXPR:
       split_constant_offset (op0, &var0, &off0);
@@ -1685,6 +1686,7 @@ siv_subscript_p (const_tree chrec_a, const_tree chrec_b)
 	    case POLYNOMIAL_CHREC:
 	      if (CHREC_VARIABLE (chrec_a) != CHREC_VARIABLE (chrec_b))
 		return false;
+	      gcc_fallthrough ();
 
 	    default:
 	      return true;
@@ -3889,6 +3891,8 @@ get_references_in_stmt (gimple *stmt, vec<data_ref_loc, va_heap> *references)
 	    if (gimple_call_lhs (stmt) == NULL_TREE)
 	      break;
 	    ref.is_read = true;
+	    /* XXX Really fallthru?  */
+	    gcc_fallthrough ();
 	  case IFN_MASK_STORE:
 	    ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
 	    align = tree_to_shwi (gimple_call_arg (stmt, 1));
diff --git gcc/gcc/tree-dfa.c gcc/gcc/tree-dfa.c
index 9a3b072..9209aae 100644
--- gcc/gcc/tree-dfa.c
+++ gcc/gcc/tree-dfa.c
@@ -543,6 +543,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
 	      goto done;
 	    }
 	  /* Fallthru.  */
+	  gcc_fallthrough ();
 	case MEM_REF:
 	  /* We need to deal with variable arrays ending structures such as
 	     struct { int length; int a[1]; } x;           x.a[d]
diff --git gcc/gcc/tree-dump.c gcc/gcc/tree-dump.c
index 05228a0..9aeb678 100644
--- gcc/gcc/tree-dump.c
+++ gcc/gcc/tree-dump.c
@@ -488,6 +488,7 @@ dequeue_and_dump (dump_info_p di)
     case METHOD_TYPE:
       dump_child ("clas", TYPE_METHOD_BASETYPE (t));
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case FUNCTION_TYPE:
       dump_child ("retn", TREE_TYPE (t));
@@ -519,6 +520,7 @@ dequeue_and_dump (dump_info_p di)
     case DEBUG_EXPR_DECL:
       dump_int (di, "-uid", DEBUG_TEMP_UID (t));
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case VAR_DECL:
     case PARM_DECL:
diff --git gcc/gcc/tree-eh.c gcc/gcc/tree-eh.c
index db72156..717ed1f 100644
--- gcc/gcc/tree-eh.c
+++ gcc/gcc/tree-eh.c
@@ -2011,11 +2011,13 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
 		 is accessible to abuse by users.  Just remove it and
 		 replace the use with the arbitrary value zero.  */
 	      rhs = build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
+	      gcc_fallthrough ();
 	    do_replace:
 	      lhs = gimple_call_lhs (stmt);
 	      x = gimple_build_assign (lhs, rhs);
 	      gsi_insert_before (gsi, x, GSI_SAME_STMT);
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 
 	    case BUILT_IN_EH_COPY_VALUES:
 	      /* Likewise this should not appear.  Remove it.  */
@@ -2027,6 +2029,7 @@ lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
 	    }
       }
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case GIMPLE_ASSIGN:
       /* If the stmt can throw use a new temporary for the assignment
diff --git gcc/gcc/tree-emutls.c gcc/gcc/tree-emutls.c
index 6cf49f9..cd3a86e 100644
--- gcc/gcc/tree-emutls.c
+++ gcc/gcc/tree-emutls.c
@@ -496,6 +496,7 @@ lower_emutls_1 (tree *ptr, int *walk_subtrees, void *cb_data)
       t = TREE_OPERAND (t, 0);
       is_addr = true;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case VAR_DECL:
       if (!DECL_THREAD_LOCAL_P (t))
@@ -507,6 +508,7 @@ lower_emutls_1 (tree *ptr, int *walk_subtrees, void *cb_data)
       if (EXPR_P (t))
         *walk_subtrees = 1;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SSA_NAME:
       /* Special-case the return of SSA_NAME, since it's so common.  */
diff --git gcc/gcc/tree-inline.c gcc/gcc/tree-inline.c
index ef58866..c76deb0c 100644
--- gcc/gcc/tree-inline.c
+++ gcc/gcc/tree-inline.c
@@ -1665,6 +1665,7 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
 		    r = remap_eh_region_tree_nr (r, id);
 		    gimple_call_set_arg (copy, 1, r);
 		    /* FALLTHRU */
+		    gcc_fallthrough ();
 
 		  case BUILT_IN_EH_POINTER:
 		  case BUILT_IN_EH_FILTER:
diff --git gcc/gcc/tree-nested.c gcc/gcc/tree-nested.c
index 62cb01f..dc70b0b 100644
--- gcc/gcc/tree-nested.c
+++ gcc/gcc/tree-nested.c
@@ -899,6 +899,7 @@ convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data)
       if (TREE_STATIC (t) || DECL_EXTERNAL (t))
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case PARM_DECL:
       if (decl_function_context (t) != info->context)
@@ -1094,6 +1095,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
 	  if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause) == NULL)
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case OMP_CLAUSE_FINAL:
 	case OMP_CLAUSE_IF:
 	case OMP_CLAUSE_NUM_THREADS:
@@ -1594,6 +1596,7 @@ convert_local_reference_op (tree *tp, int *walk_subtrees, void *data)
       if (TREE_STATIC (t) || DECL_EXTERNAL (t))
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case PARM_DECL:
       if (decl_function_context (t) == info->context)
@@ -1797,6 +1800,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
 	  if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause) == NULL)
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case OMP_CLAUSE_FINAL:
 	case OMP_CLAUSE_IF:
 	case OMP_CLAUSE_NUM_THREADS:
@@ -2399,6 +2403,7 @@ convert_tramp_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 	  return NULL_TREE;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case GIMPLE_OMP_PARALLEL:
     case GIMPLE_OMP_TASK:
       {
@@ -2567,8 +2572,9 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 
     case GIMPLE_OMP_FOR:
       walk_body (convert_gimple_call, NULL, info,
-	  	 gimple_omp_for_pre_body_ptr (stmt));
+		 gimple_omp_for_pre_body_ptr (stmt));
       /* FALLTHRU */
+      gcc_fallthrough ();
     case GIMPLE_OMP_SECTIONS:
     case GIMPLE_OMP_SECTION:
     case GIMPLE_OMP_SINGLE:
diff --git gcc/gcc/tree-object-size.c gcc/gcc/tree-object-size.c
index 07455cc..b5b27c4 100644
--- gcc/gcc/tree-object-size.c
+++ gcc/gcc/tree-object-size.c
@@ -410,10 +410,12 @@ alloc_object_size (const gcall *call, int object_size_type)
       case BUILT_IN_CALLOC:
 	arg2 = 1;
 	/* fall through */
+	gcc_fallthrough ();
       case BUILT_IN_MALLOC:
       case BUILT_IN_ALLOCA:
       case BUILT_IN_ALLOCA_WITH_ALIGN:
 	arg1 = 0;
+	gcc_fallthrough ();
       default:
 	break;
       }
diff --git gcc/gcc/tree-pretty-print.c gcc/gcc/tree-pretty-print.c
index 734ecda..ae9beda 100644
--- gcc/gcc/tree-pretty-print.c
+++ gcc/gcc/tree-pretty-print.c
@@ -743,6 +743,7 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, int flags)
       pp_colon (pp);
       dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
 			 spc, flags, false);
+      gcc_fallthrough ();
      print_clause_size:
       if (OMP_CLAUSE_SIZE (clause))
 	{
@@ -2946,6 +2947,8 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, int flags,
 
     dump_omp_loop:
       dump_omp_clauses (pp, OMP_FOR_CLAUSES (node), spc, flags);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
 
     dump_omp_loop_cilk_for:
       if (!(flags & TDF_SLIM))
@@ -3763,6 +3766,7 @@ print_call_name (pretty_printer *pp, tree node, int flags)
 	  goto again;
 	}
       /* Fallthru.  */
+      gcc_fallthrough ();
     case COMPONENT_REF:
     case SSA_NAME:
     case OBJ_TYPE_REF:
diff --git gcc/gcc/tree-scalar-evolution.c gcc/gcc/tree-scalar-evolution.c
index e51f0aa..c8e975a 100644
--- gcc/gcc/tree-scalar-evolution.c
+++ gcc/gcc/tree-scalar-evolution.c
@@ -3592,6 +3592,7 @@ expression_expensive_p (tree expr)
 	return true;
 
       /* Fallthru.  */
+      gcc_fallthrough ();
     case tcc_unary:
       return expression_expensive_p (TREE_OPERAND (expr, 0));
 
diff --git gcc/gcc/tree-sra.c gcc/gcc/tree-sra.c
index 7c0e90d..71263f0 100644
--- gcc/gcc/tree-sra.c
+++ gcc/gcc/tree-sra.c
@@ -1188,6 +1188,7 @@ build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
 	  && sra_mode != SRA_MODE_EARLY_IPA)
 	return NULL;
       /* fall through */
+      gcc_fallthrough ();
     case VAR_DECL:
     case PARM_DECL:
     case RESULT_DECL:
@@ -2157,6 +2158,7 @@ create_access_replacement (struct access *access)
 		&& TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST)
 	      fail = true;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case COMPONENT_REF:
 	    if (TREE_OPERAND (d, 2)
 		&& TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST)
diff --git gcc/gcc/tree-ssa-alias.c gcc/gcc/tree-ssa-alias.c
index 70c24b5..d3a76f7 100644
--- gcc/gcc/tree-ssa-alias.c
+++ gcc/gcc/tree-ssa-alias.c
@@ -1626,6 +1626,7 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref)
 	      return true;
 	  }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case BUILT_IN_STRCPY:
 	case BUILT_IN_STRNCPY:
 	case BUILT_IN_MEMCPY:
@@ -1656,6 +1657,7 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref)
 	      return true;
 	  }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case BUILT_IN_STRCPY_CHK:
 	case BUILT_IN_STRNCPY_CHK:
 	case BUILT_IN_MEMCPY_CHK:
diff --git gcc/gcc/tree-ssa-ccp.c gcc/gcc/tree-ssa-ccp.c
index ae120a8..8a71ff4 100644
--- gcc/gcc/tree-ssa-ccp.c
+++ gcc/gcc/tree-ssa-ccp.c
@@ -1458,6 +1458,7 @@ bit_value_binop_1 (enum tree_code code, tree type,
       swap_p = true;
       code = swap_tree_comparison (code);
       /* Fall through.  */
+      gcc_fallthrough ();
     case LT_EXPR:
     case LE_EXPR:
       {
@@ -3107,6 +3108,7 @@ pass_fold_builtins::execute (function *fun)
 		  if (result)
 		    break;
 		  /* FALLTHRU */
+		  gcc_fallthrough ();
 
 		default:;
 		}
diff --git gcc/gcc/tree-ssa-dce.c gcc/gcc/tree-ssa-dce.c
index 954fc67..c34aea3 100644
--- gcc/gcc/tree-ssa-dce.c
+++ gcc/gcc/tree-ssa-dce.c
@@ -269,6 +269,7 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
     case GIMPLE_COND:
       gcc_assert (EDGE_COUNT (gimple_bb (stmt)->succs) == 2);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case GIMPLE_SWITCH:
       if (! aggressive)
diff --git gcc/gcc/tree-ssa-loop-ivopts.c gcc/gcc/tree-ssa-loop-ivopts.c
index 25b9780..690bb41 100644
--- gcc/gcc/tree-ssa-loop-ivopts.c
+++ gcc/gcc/tree-ssa-loop-ivopts.c
@@ -983,6 +983,7 @@ contains_abnormal_ssa_name_p (tree expr)
 	return true;
 
       /* Fallthru.  */
+      gcc_fallthrough ();
     case tcc_unary:
       if (contains_abnormal_ssa_name_p (TREE_OPERAND (expr, 0)))
 	return true;
@@ -1884,6 +1885,7 @@ find_deriving_biv_for_expr (struct ivopts_data *data, tree expr)
 	return iv;
 
       /* Fallthru.  */
+      gcc_fallthrough ();
     CASE_CONVERT:
       /* Casts are simple.  */
       return find_deriving_biv_for_expr (data, e1);
@@ -7100,6 +7102,7 @@ create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
     case IP_AFTER_USE:
       after = true;
       /* fall through */
+      gcc_fallthrough ();
     case IP_BEFORE_USE:
       incr_pos = gsi_for_stmt (cand->incremented_at);
       break;
diff --git gcc/gcc/tree-ssa-loop-niter.c gcc/gcc/tree-ssa-loop-niter.c
index 0723752..871fbb0 100644
--- gcc/gcc/tree-ssa-loop-niter.c
+++ gcc/gcc/tree-ssa-loop-niter.c
@@ -80,6 +80,7 @@ split_to_var_and_offset (tree expr, tree *var, mpz_t offset)
     case MINUS_EXPR:
       negate = true;
       /* Fallthru.  */
+      gcc_fallthrough ();
 
     case PLUS_EXPR:
     case POINTER_PLUS_EXPR:
@@ -1911,6 +1912,7 @@ expand_simple_operations (tree expr, tree stop)
 	  && TYPE_OVERFLOW_TRAPS (TREE_TYPE (expr)))
 	return expr;
       /* Fallthru.  */
+      gcc_fallthrough ();
     case POINTER_PLUS_EXPR:
       /* And increments and decrements by a constant are simple.  */
       e1 = gimple_assign_rhs2 (stmt);
diff --git gcc/gcc/tree-ssa-math-opts.c gcc/gcc/tree-ssa-math-opts.c
index d31c12f..3fc8bd8 100644
--- gcc/gcc/tree-ssa-math-opts.c
+++ gcc/gcc/tree-ssa-math-opts.c
@@ -2872,6 +2872,7 @@ pass_optimize_bswap::execute (function *fun)
 		     % BITS_PER_UNIT)
 		continue;
 	      /* Fall through.  */
+	      gcc_fallthrough ();
 	    case BIT_IOR_EXPR:
 	      break;
 	    default:
diff --git gcc/gcc/tree-ssa-operands.c gcc/gcc/tree-ssa-operands.c
index eccea2f..6ccf097 100644
--- gcc/gcc/tree-ssa-operands.c
+++ gcc/gcc/tree-ssa-operands.c
@@ -827,6 +827,7 @@ get_expr_operands (struct function *fn, gimple *stmt, tree *expr_p, int flags)
 	  && TREE_THIS_VOLATILE (expr))
 	gimple_set_has_volatile_ops (stmt, true);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case VIEW_CONVERT_EXPR:
     do_unary:
@@ -919,11 +920,13 @@ parse_ssa_operands (struct function *fn, gimple *stmt)
       /* Add call-clobbered operands, if needed.  */
       maybe_add_call_vops (fn, as_a <gcall *> (stmt));
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case GIMPLE_ASSIGN:
       get_expr_operands (fn, stmt, gimple_op_ptr (stmt, 0), opf_def);
       start = 1;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     default:
     do_default:
diff --git gcc/gcc/tree-ssa-pre.c gcc/gcc/tree-ssa-pre.c
index 3ce87d9..ed86333 100644
--- gcc/gcc/tree-ssa-pre.c
+++ gcc/gcc/tree-ssa-pre.c
@@ -1194,6 +1194,7 @@ fully_constant_expression (pre_expr e)
 		&& nary->opcode != VIEW_CONVERT_EXPR)
 	      return e;
 	    /* Fallthrough.  */
+	    gcc_fallthrough ();
 	  case tcc_unary:
 	    {
 	      /* We have to go from trees to pre exprs to value ids to
@@ -2503,6 +2504,7 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
 	  return currop->op0;
 	}
       /* Fallthrough.  */
+      gcc_fallthrough ();
     case REALPART_EXPR:
     case IMAGPART_EXPR:
     case VIEW_CONVERT_EXPR:
diff --git gcc/gcc/tree-ssa-propagate.c gcc/gcc/tree-ssa-propagate.c
index c4535a4..2405a76 100644
--- gcc/gcc/tree-ssa-propagate.c
+++ gcc/gcc/tree-ssa-propagate.c
@@ -641,6 +641,7 @@ valid_gimple_rhs_p (tree expr)
 	return false;
 
       /* Fallthru.  */
+      gcc_fallthrough ();
     case tcc_binary:
       if (!is_gimple_val (TREE_OPERAND (expr, 0))
 	  || !is_gimple_val (TREE_OPERAND (expr, 1)))
diff --git gcc/gcc/tree-ssa-reassoc.c gcc/gcc/tree-ssa-reassoc.c
index 9264e0b..32f5a5f 100644
--- gcc/gcc/tree-ssa-reassoc.c
+++ gcc/gcc/tree-ssa-reassoc.c
@@ -2086,9 +2086,11 @@ init_range_entry (struct range_entry *r, tree exp, gimple *stmt)
 	case GT_EXPR:
 	  is_bool = true;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	default:
 	  if (!is_bool)
 	    return;
+	  gcc_fallthrough ();
 	do_default:
 	  nexp = make_range_step (loc, code, arg0, arg1, exp_type,
 				  &low, &high, &in_p,
diff --git gcc/gcc/tree-ssa-sccvn.c gcc/gcc/tree-ssa-sccvn.c
index 0cbd2cd..02eff33 100644
--- gcc/gcc/tree-ssa-sccvn.c
+++ gcc/gcc/tree-ssa-sccvn.c
@@ -448,6 +448,7 @@ vn_get_stmt_kind (gimple *stmt)
 		  return VN_NARY;
 
 		/* Fallthrough.  */
+		gcc_fallthrough ();
 	      case tcc_declaration:
 		return VN_REFERENCE;
 
@@ -828,6 +829,7 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result)
 	      break;
 	    }
 	  /* Fallthru.  */
+	  gcc_fallthrough ();
 	case PARM_DECL:
 	case CONST_DECL:
 	case RESULT_DECL:
@@ -960,6 +962,7 @@ ao_ref_init_from_vn_reference (ao_ref *ref,
 	      break;
 	    }
 	  /* Fallthru.  */
+	  gcc_fallthrough ();
 	case CALL_EXPR:
 	  return false;
 
diff --git gcc/gcc/tree-ssa-strlen.c gcc/gcc/tree-ssa-strlen.c
index 489c8f0..bffe1d8 100644
--- gcc/gcc/tree-ssa-strlen.c
+++ gcc/gcc/tree-ssa-strlen.c
@@ -500,6 +500,7 @@ get_string_length (strinfo *si)
 	  gimple_call_set_arg (stmt, 0, gimple_assign_lhs (lenstmt));
 	  lhs = NULL_TREE;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case BUILT_IN_STRCPY:
 	case BUILT_IN_STRCPY_CHK:
 	case BUILT_IN_STRCPY_CHKP:
@@ -527,6 +528,7 @@ get_string_length (strinfo *si)
 	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
 	    }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case BUILT_IN_STPCPY:
 	case BUILT_IN_STPCPY_CHK:
 	case BUILT_IN_STPCPY_CHKP:
@@ -871,6 +873,7 @@ find_equal_ptrs (tree ptr, int idx)
 	  if (TREE_CODE (ptr) != ADDR_EXPR)
 	    return;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case ADDR_EXPR:
 	  {
 	    int *pidx = addr_stridxptr (TREE_OPERAND (ptr, 0));
diff --git gcc/gcc/tree-tailcall.c gcc/gcc/tree-tailcall.c
index 0436f0f..dfdb990 100644
--- gcc/gcc/tree-tailcall.c
+++ gcc/gcc/tree-tailcall.c
@@ -300,6 +300,7 @@ process_assignment (gassign *stmt, gimple_stmt_iterator call, tree *m,
       op1 = gimple_assign_rhs2 (stmt);
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case GIMPLE_UNARY_RHS:
       op0 = gimple_assign_rhs1 (stmt);
diff --git gcc/gcc/tree-vect-patterns.c gcc/gcc/tree-vect-patterns.c
index f0c515d..7c56869 100644
--- gcc/gcc/tree-vect-patterns.c
+++ gcc/gcc/tree-vect-patterns.c
@@ -3111,10 +3111,12 @@ adjust_bool_pattern (tree var, tree out_type,
 	  goto and_ior_xor;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
       irhs1 = *defs.get (rhs1);
       irhs2 = *defs.get (rhs2);
+      gcc_fallthrough ();
     and_ior_xor:
       if (TYPE_PRECISION (TREE_TYPE (irhs1))
 	  != TYPE_PRECISION (TREE_TYPE (irhs2)))
diff --git gcc/gcc/tree-vect-stmts.c gcc/gcc/tree-vect-stmts.c
index c41550d..6cfe26e 100644
--- gcc/gcc/tree-vect-stmts.c
+++ gcc/gcc/tree-vect-stmts.c
@@ -389,6 +389,7 @@ exist_non_indexing_operands_for_use_p (tree use, gimple *stmt)
 	    if (operand == use)
 	      return true;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case IFN_MASK_LOAD:
 	    operand = gimple_call_arg (stmt, 2);
 	    if (operand == use)
@@ -3792,6 +3793,7 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi,
 					 &decl1, &code1))
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
     unsupported:
       if (dump_enabled_p ())
 	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
diff --git gcc/gcc/tree.c gcc/gcc/tree.c
index 2295111..e99f17f 100644
--- gcc/gcc/tree.c
+++ gcc/gcc/tree.c
@@ -1443,6 +1443,7 @@ wide_int_to_tree (tree type, const wide_int_ref &pcst)
 	case NULLPTR_TYPE:
 	  gcc_assert (hwi == 0);
 	  /* Fallthru.  */
+	  gcc_fallthrough ();
 
 	case POINTER_TYPE:
 	case REFERENCE_TYPE:
@@ -1566,6 +1567,7 @@ cache_integer_cst (tree t)
     case NULLPTR_TYPE:
       gcc_assert (integer_zerop (t));
       /* Fallthru.  */
+      gcc_fallthrough ();
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
@@ -3728,6 +3730,7 @@ find_placeholder_in_expr (tree exp, vec<tree> *refs)
 	  }
 
         /* Fall through...  */
+	gcc_fallthrough ();
 
       case tcc_exceptional:
       case tcc_unary:
@@ -3817,6 +3820,7 @@ substitute_in_expr (tree exp, tree f, tree r)
 	  return r;
 
         /* Fall through...  */
+	gcc_fallthrough ();
 
       case tcc_exceptional:
       case tcc_unary:
@@ -4924,6 +4928,7 @@ omp_declare_simd_clauses_equal (tree clauses1, tree clauses2)
 	  if (simple_cst_equal (OMP_CLAUSE_SIMDLEN_EXPR (cl1),
 				OMP_CLAUSE_SIMDLEN_EXPR (cl2)) != 1)
 	    return false;
+	  gcc_fallthrough ();
 	default:
 	  break;
 	}
@@ -7037,6 +7042,7 @@ type_cache_hasher::equal (type_hash *a, type_hash *b)
 	return 0;
 
       /* ... fall through ... */
+      gcc_fallthrough ();
 
     case INTEGER_TYPE:
     case REAL_TYPE:
@@ -7873,6 +7879,7 @@ add_expr (const_tree t, inchash::hash &hstate, unsigned int flags)
 	  code = TREE_CODE (t);
 	}
       /* FALL THROUGH */
+      gcc_fallthrough ();
     default:
       tclass = TREE_CODE_CLASS (code);
 
@@ -11574,6 +11581,7 @@ walk_type_fields (tree type, walk_tree_fn func, void *data,
 	}
 
       /* ... fall through ... */
+      gcc_fallthrough ();
 
     case COMPLEX_TYPE:
       WALK_SUBTREE (TREE_TYPE (type));
@@ -11583,6 +11591,7 @@ walk_type_fields (tree type, walk_tree_fn func, void *data,
       WALK_SUBTREE (TYPE_METHOD_BASETYPE (type));
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case FUNCTION_TYPE:
       WALK_SUBTREE (TREE_TYPE (type));
@@ -11768,6 +11777,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	case OMP_CLAUSE__GRIDDIM_:
 	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1));
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case OMP_CLAUSE_ASYNC:
 	case OMP_CLAUSE_WAIT:
@@ -11807,6 +11817,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	  WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case OMP_CLAUSE_INDEPENDENT:
 	case OMP_CLAUSE_NOWAIT:
@@ -11954,6 +11965,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
 	  WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     default:
       if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
@@ -12890,6 +12902,7 @@ block_may_fallthru (const_tree block)
       else
 	return true;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CALL_EXPR:
       /* Functions that do not return do not fall through.  */
diff --git gcc/gcc/tsan.c gcc/gcc/tsan.c
index 47764bc..9a7daa5 100644
--- gcc/gcc/tsan.c
+++ gcc/gcc/tsan.c
@@ -551,6 +551,7 @@ instrument_builtin_call (gimple_stmt_iterator *gsi)
 	    if (!integer_nonzerop (gimple_call_arg (stmt, 3)))
 	      continue;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case strong_cas:
 	    gcc_assert (num == 6);
 	    for (j = 0; j < 6; j++)
diff --git gcc/gcc/var-tracking.c gcc/gcc/var-tracking.c
index 9f09d30..85d31bc 100644
--- gcc/gcc/var-tracking.c
+++ gcc/gcc/var-tracking.c
@@ -1056,6 +1056,8 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data)
 					 ? GET_MODE_SIZE (amd->mem_mode)
 					 : -GET_MODE_SIZE (amd->mem_mode),
 					 GET_MODE (loc)));
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case POST_INC:
     case POST_DEC:
       if (addr == loc)
@@ -1078,6 +1080,8 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data)
       return addr;
     case PRE_MODIFY:
       addr = XEXP (loc, 1);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case POST_MODIFY:
       if (addr == loc)
 	addr = XEXP (loc, 0);
@@ -1116,6 +1120,7 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data)
 				 SUBREG_BYTE (loc));
       if (tem == NULL_RTX)
 	tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
+      gcc_fallthrough ();
     finish_subreg:
       if (MAY_HAVE_DEBUG_INSNS
 	  && GET_CODE (tem) == SUBREG
@@ -3153,6 +3158,7 @@ set_dv_changed (decl_or_value dv, bool newv)
       if (newv)
 	NO_LOC_P (DECL_RTL_KNOWN_SET (dv_as_decl (dv))) = false;
       /* Fall through...  */
+      gcc_fallthrough ();
 
     default:
       DECL_CHANGED (dv_as_decl (dv)) = newv;
diff --git gcc/gcc/varasm.c gcc/gcc/varasm.c
index 6a8fb81..1d659bd 100644
--- gcc/gcc/varasm.c
+++ gcc/gcc/varasm.c
@@ -589,6 +589,7 @@ default_function_section (tree decl, enum node_frequency freq,
            these ELF section.  */
         if (!in_lto_p || !flag_profile_values)
           return get_named_text_section (decl, ".text.hot", NULL);
+	gcc_fallthrough ();
       default:
 	return NULL;
     }
@@ -3568,6 +3569,7 @@ const_rtx_hash_1 (const_rtx x)
     {
     case CONST_INT:
       hwi = INTVAL (x);
+      gcc_fallthrough ();
 
     fold_hwi:
       {
@@ -3890,6 +3892,7 @@ output_constant_pool_1 (struct constant_descriptor_rtx *desc,
 	break;
       tmp = XEXP (XEXP (tmp, 0), 0);
       /* FALLTHRU  */
+      gcc_fallthrough ();
 
     case LABEL_REF:
       tmp = LABEL_REF_LABEL (tmp);
@@ -4173,6 +4176,7 @@ output_addressed_constants (tree exp)
     case MINUS_EXPR:
       output_addressed_constants (TREE_OPERAND (exp, 1));
       /* Fall through.  */
+      gcc_fallthrough ();
 
     CASE_CONVERT:
     case VIEW_CONVERT_EXPR:
@@ -7520,6 +7524,7 @@ elf_record_gcc_switches (print_switch_type type, const char * name)
 	      started = true;
 	    }
 	}
+      gcc_fallthrough ();
 
     default:
       break;
diff --git gcc/include/libiberty.h gcc/include/libiberty.h
index a9c885f..e435253 100644
--- gcc/include/libiberty.h
+++ gcc/include/libiberty.h
@@ -735,5 +735,10 @@ extern unsigned long libiberty_len;
 }
 #endif
 
+#if GCC_VERSION >= 7000
+# define D_FALLTHRU() __builtin_fallthrough ()
+#else
+# define D_FALLTHRU()
+#endif
 
 #endif /* ! defined (LIBIBERTY_H) */

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: aarch64 + arm
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (5 preceding siblings ...)
  2016-07-11 19:52 ` Implement -Wswitch-fallthrough: gcc/ Marek Polacek
@ 2016-07-11 19:53 ` Marek Polacek
  2016-07-14  9:05   ` Richard Earnshaw (lists)
  2016-07-11 19:54 ` Implement -Wswitch-fallthrough: i386 Marek Polacek
                   ` (22 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:53 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* config/aarch64/aarch64-builtins.c (aarch64_simd_expand_args): Add gcc_fallthrough.
	* config/aarch64/aarch64-simd.md: Likewise.
	* config/aarch64/aarch64.c (aarch64_expand_mov_immediate): Likewise.
	(aarch64_print_operand): Likewise.
	(aarch64_rtx_costs): Likewise.
	(aarch64_expand_compare_and_swap): Likewise.
	(aarch64_gen_atomic_ldop): Likewise.
	(aarch64_split_atomic_op): Likewise.
	(aarch64_expand_vec_perm_const): Likewise.
	* config/aarch64/predicates.md: Likewise.
	* config/arm/arm-builtins.c (arm_expand_neon_args): Likewise.
	* config/arm/arm.c (const_ok_for_op): Likewise.
	(arm_rtx_costs_1): Likewise.
	(thumb1_size_rtx_costs): Likewise.
	(arm_size_rtx_costs): Likewise.
	(arm_new_rtx_costs): Likewise.
	(thumb2_reorg): Likewise.
	(output_move_double): Likewise.
	(output_move_neon): Likewise.
	(arm_print_operand): Likewise.
	(arm_expand_compare_and_swap): Likewise.
	(arm_split_atomic_op): Likewise.
	(arm_expand_vec_perm_const): Likewise.
	* config/arm/neon.md: Likewise.

diff --git gcc/gcc/config/aarch64/aarch64-builtins.c gcc/gcc/config/aarch64/aarch64-builtins.c
index 6b90b2a..fe37ea2 100644
--- gcc/gcc/config/aarch64/aarch64-builtins.c
+++ gcc/gcc/config/aarch64/aarch64-builtins.c
@@ -999,6 +999,7 @@ aarch64_simd_expand_args (rtx target, int icode, int have_retval,
 		}
 	      /* Fall through - if the lane index isn't a constant then
 		 the next case will error.  */
+	      gcc_fallthrough ();
 	    case SIMD_ARG_CONSTANT:
 constant_arg:
 	      if (!(*insn_data[icode].operand[opc].predicate)
diff --git gcc/gcc/config/aarch64/aarch64-simd.md gcc/gcc/config/aarch64/aarch64-simd.md
index a19d171..110a070 100644
--- gcc/gcc/config/aarch64/aarch64-simd.md
+++ gcc/gcc/config/aarch64/aarch64-simd.md
@@ -2328,6 +2328,7 @@
       if (operands[5] == CONST0_RTX (<MODE>mode))
         break;
       /* Fall through, as may need to load into register.  */
+      gcc_fallthrough ();
     default:
       if (!REG_P (operands[5]))
         operands[5] = force_reg (<MODE>mode, operands[5]);
@@ -2430,6 +2431,7 @@
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     default:
       if (!REG_P (operands[5]))
 	operands[5] = force_reg (<VDQF:MODE>mode, operands[5]);
@@ -2441,6 +2443,7 @@
     case UNLT:
       inverse = 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case GE:
     case UNGE:
     case ORDERED:
@@ -2452,6 +2455,7 @@
     case UNLE:
       inverse = 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case GT:
     case UNGT:
       base_comparison = gen_aarch64_cmgt<VDQF:mode>;
@@ -2545,6 +2549,7 @@
 	 Swapping the operands to BSL will give the UNORDERED case.  */
      swap_bsl_operands = 1;
      /* Fall through.  */
+     gcc_fallthrough ();
     case ORDERED:
       emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[4], operands[5]));
       emit_insn (gen_aarch64_cmge<VDQF:mode> (mask, operands[5], operands[4]));
diff --git gcc/gcc/config/aarch64/aarch64.c gcc/gcc/config/aarch64/aarch64.c
index 512ef10..3ecf244 100644
--- gcc/gcc/config/aarch64/aarch64.c
+++ gcc/gcc/config/aarch64/aarch64.c
@@ -1833,6 +1833,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
 	      return;
 	    }
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case SYMBOL_SMALL_ABSOLUTE:
 	case SYMBOL_TINY_ABSOLUTE:
@@ -4541,6 +4542,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
 	      break;
 	    }
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	default:
 	  output_operand_lossage ("Unsupported operand for code '%c'", code);
@@ -4713,6 +4715,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
 
     case 0:
       /* Print a normal operand, if it's a general register, then we
@@ -6192,6 +6195,7 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED,
 	    *cost += rtx_cost (SUBREG_REG (op0), VOIDmode, SET, 0, speed);
 
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case REG:
 	  /* The cost is one per vector-register copied.  */
 	  if (VECTOR_MODE_P (GET_MODE (op0)) && REG_P (op1))
@@ -6685,6 +6689,7 @@ cost_plus:
           return true;
         }
     /* Fall through.  */
+    gcc_fallthrough ();
     case XOR:
     case AND:
     cost_logic:
@@ -7081,6 +7086,7 @@ cost_plus:
 	}
 
     /* Fall-through.  */
+    gcc_fallthrough ();
     case UMOD:
       if (speed)
 	{
@@ -7356,6 +7362,7 @@ cost_plus:
         }
 
       /* Fall through.  */
+      gcc_fallthrough ();
     default:
       break;
     }
@@ -11422,6 +11429,7 @@ aarch64_expand_compare_and_swap (rtx operands[])
       rval = gen_reg_rtx (SImode);
       oldval = convert_modes (SImode, mode, oldval, true);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case SImode:
     case DImode:
@@ -11777,6 +11785,7 @@ aarch64_gen_atomic_ldop (enum rtx_code code, rtx out_data, rtx out_result,
 	  src = gen_lowpart (mode, src);
       }
       /* Fall-through.  */
+      gcc_fallthrough ();
     case PLUS:
       ldop_code = AARCH64_LDOP_PLUS;
       break;
@@ -11904,6 +11913,7 @@ aarch64_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
 	  code = PLUS;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       x = gen_rtx_fmt_ee (code, wmode, old_out, value);
@@ -12817,6 +12827,7 @@ aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel)
 	 of the permutation by folding the permutation into the single
 	 input vector.  */
       /* Fall Through.  */
+      gcc_fallthrough ();
     case 2:
       for (i = 0; i < nelt; ++i)
 	d.perm[i] &= nelt - 1;
diff --git gcc/gcc/config/aarch64/predicates.md gcc/gcc/config/aarch64/predicates.md
index 8f2726d..9a7b336 100644
--- gcc/gcc/config/aarch64/predicates.md
+++ gcc/gcc/config/aarch64/predicates.md
@@ -180,6 +180,7 @@
 	  || GET_CODE (XEXP (op, 1)) != CONST_INT)
 	return false;
       op = XEXP (op, 0);
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
@@ -201,6 +202,7 @@
 	  || GET_CODE (XEXP (op, 1)) != CONST_INT)
 	return false;
       op = XEXP (op, 0);
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
diff --git gcc/gcc/config/arm/arm-builtins.c gcc/gcc/config/arm/arm-builtins.c
index 68b2839..3b03c29 100644
--- gcc/gcc/config/arm/arm-builtins.c
+++ gcc/gcc/config/arm/arm-builtins.c
@@ -2113,6 +2113,7 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
 		}
 	      /* Fall through - if the lane index isn't a constant then
 		 the next case will error.  */
+	      gcc_fallthrough ();
 
 	    case NEON_ARG_CONSTANT:
 constant_arg:
diff --git gcc/gcc/config/arm/arm.c gcc/gcc/config/arm/arm.c
index 580662d..e5f8208 100644
--- gcc/gcc/config/arm/arm.c
+++ gcc/gcc/config/arm/arm.c
@@ -3956,6 +3956,7 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
 	      || ((-i) & 0xfffff000) == 0))
 	return 1;
       /* else fall through.  */
+      gcc_fallthrough ();
 
     case COMPARE:
     case EQ:
@@ -8469,6 +8470,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
 	*total = rtx_cost (XEXP (x, 1), mode, code, 1, speed);
 
       /* Fall through */
+      gcc_fallthrough ();
     case ROTATERT:
       if (mode != SImode)
 	{
@@ -8477,6 +8479,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
     case ASHIFT: case LSHIFTRT: case ASHIFTRT:
       *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       if (mode == DImode)
@@ -8590,6 +8593,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
 
     case PLUS:
       if (code == PLUS && arm_arch6 && mode == SImode
@@ -8646,6 +8650,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
 
     case AND: case XOR: case IOR:
 
@@ -8741,6 +8746,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
     case NOT:
       *total = COSTS_N_INSNS (ARM_NUM_REGS(mode));
       if (mode == SImode && code == NOT)
@@ -8837,6 +8843,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
     case COMPARE:
       if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) == CC_REGNUM)
 	{
@@ -9076,6 +9083,7 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
 	      && power_of_two_operand (XEXP (XEXP (x, 1), 1), SImode)))
 	return COSTS_N_INSNS (2);
       /* On purpose fall through for normal RTX.  */
+      gcc_fallthrough ();
     case COMPARE:
     case NEG:
     case NOT:
@@ -9243,6 +9251,7 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
 	  return true;
 	}
       /* Fall through */
+      gcc_fallthrough ();
     case ROTATERT:
     case ASHIFT:
     case LSHIFTRT:
@@ -9317,6 +9326,7 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
     case AND: case XOR: case IOR:
       if (mode == SImode)
 	{
@@ -9348,6 +9358,7 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
 	}
 
       /* Fall through */
+      gcc_fallthrough ();
     case NOT:
       *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
 
@@ -9721,6 +9732,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
 	}
 
     /* Fall-through.  */
+    gcc_fallthrough ();
     case UMOD:
       *cost = LIBCALL_COST (2);
       return false;	/* All arguments must be in registers.  */
@@ -9735,6 +9747,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
 	  return true;
 	}
       /* Fall through */
+      gcc_fallthrough ();
     case ROTATERT:
     case ASHIFT:
     case LSHIFTRT:
@@ -10244,6 +10257,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
           return true;
         }
     /* Fall through.  */
+    gcc_fallthrough ();
     case AND: case XOR:
       if (mode == SImode)
 	{
@@ -11035,6 +11049,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
 	  return true;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case SMAX:
     case UMIN:
     case UMAX:
@@ -11076,6 +11091,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
     case ZERO_EXTRACT:
       /* TODO: Simple zero_extract of bottom bits using AND.  */
       /* Fall through.  */
+      gcc_fallthrough ();
     case SIGN_EXTRACT:
       if (arm_arch6
 	  && mode == SImode
@@ -17506,6 +17522,7 @@ thumb2_reorg (void)
 		      if (!optimize_size)
 			break;
 		      /* else fall through.  */
+		      gcc_fallthrough ();
 		    case AND:
 		    case IOR:
 		    case XOR:
@@ -18544,6 +18561,7 @@ output_move_double (rtx *operands, bool emit, int *count)
 	      return "";
 	    }
 	  /* Fall through */
+	  gcc_fallthrough ();
 
         default:
 	  otherops[0] = adjust_address (operands[0], SImode, 4);
@@ -18811,6 +18829,7 @@ output_move_neon (rtx *operands)
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case LABEL_REF:
     case PLUS:
       {
@@ -21992,6 +22011,7 @@ arm_print_operand (FILE *stream, rtx x, int code)
 	      break;
 	    }
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	default:
 	  output_operand_lossage ("Unsupported operand for code '%c'", code);
@@ -28107,6 +28127,7 @@ arm_expand_compare_and_swap (rtx operands[])
       rval = gen_reg_rtx (SImode);
       oldval = convert_modes (SImode, mode, oldval, true);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SImode:
       /* Force the value into a register if needed.  We waited until after
@@ -28298,6 +28319,7 @@ arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
 	  code = PLUS;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case PLUS:
       if (mode == DImode)
@@ -28317,6 +28339,7 @@ arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     default:
       x = gen_rtx_fmt_ee (code, wmode, old_out, value);
@@ -28904,6 +28927,7 @@ arm_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel)
 	 of the permutation by folding the permutation into the single
 	 input vector.  */
       /* FALLTHRU */
+      gcc_fallthrough ();
     case 2:
       for (i = 0; i < nelt; ++i)
         d.perm[i] &= nelt - 1;
diff --git gcc/gcc/config/arm/neon.md gcc/gcc/config/arm/neon.md
index e2fdfbb..6488cdc 100644
--- gcc/gcc/config/arm/neon.md
+++ gcc/gcc/config/arm/neon.md
@@ -1731,6 +1731,7 @@
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     default:
       if (!REG_P (operands[5]))
 	operands[5] = force_reg (<MODE>mode, operands[5]);
@@ -1742,6 +1743,7 @@
     case UNLT:
       inverse = 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case GE:
     case UNGE:
     case ORDERED:
@@ -1753,6 +1755,7 @@
     case UNLE:
       inverse = 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case GT:
     case UNGT:
       base_comparison = gen_neon_vcgt<mode>;
@@ -1846,6 +1849,7 @@
 	 Swapping the operands to BSL will give the UNORDERED case.  */
      swap_bsl_operands = 1;
      /* Fall through.  */
+     gcc_fallthrough ();
     case ORDERED:
       emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5]));
       emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4]));

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: i386
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (6 preceding siblings ...)
  2016-07-11 19:53 ` Implement -Wswitch-fallthrough: aarch64 + arm Marek Polacek
@ 2016-07-11 19:54 ` Marek Polacek
  2016-07-11 19:54 ` Implement -Wswitch-fallthrough: java Marek Polacek
                   ` (21 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:54 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* config/i386/driver-i386.c (decode_caches_intel): Likewise.
	(detect_caches_cpuid4): Likewise.
	* config/i386/i386-c.c (ix86_target_macros_internal): Likewise.
	* config/i386/i386.c (function_arg_advance_32): Likewise.
	(function_arg_32): Likewise.
	(ix86_gimplify_va_arg): Likewise.
	(standard_sse_constant_opcode): Likewise.
	(ix86_decompose_address): Likewise.
	(ix86_legitimate_constant_p): Likewise.
	(legitimate_pic_operand_p): Likewise.
	(legitimate_pic_address_disp_p): Likewise.
	(ix86_legitimate_address_p): Likewise.
	(output_pic_addr_const): Likewise.
	(print_reg): Likewise.
	(ix86_print_operand): Likewise.
	(ix86_expand_move): Likewise.
	(ix86_build_const_vector): Likewise.
	(ix86_match_ccmode): Likewise.
	(ix86_expand_branch): Likewise.
	(ix86_prepare_sse_fp_compare_args): Likewise.
	(ix86_expand_int_sse_cmp): Likewise.
	(ix86_adjust_cost): Likewise.
	(ix86_sched_init_global): Likewise.
	(ix86_expand_multi_arg_builtin): Likewise.
	(ix86_expand_args_builtin): Likewise.
	(ix86_expand_round_builtin): Likewise.
	(ix86_expand_special_args_builtin): Likewise.
	(ix86_expand_builtin): Likewise.
	(avx_vpermilp_parallel): Likewise.
	(ix86_rtx_costs): Likewise.
	(ix86_expand_vector_init_duplicate): Likewise.
	(ix86_expand_vector_init_one_nonzero): Likewise.
	(ix86_expand_vector_init_one_var): Likewise.
	(ix86_expand_vector_init_interleave): Likewise.
	(ix86_expand_vector_init_general): Likewise.
	(ix86_expand_vector_extract): Likewise.
	(expand_vec_perm_blend): Likewise.
	(canonicalize_perm): Likewise.
	(ix86_expand_vecop_qihi): Likewise.
	(ix86_preferred_simd_mode): Likewise.
	* config/i386/sse.md: Likewise.

diff --git gcc/gcc/config/i386/driver-i386.c gcc/gcc/config/i386/driver-i386.c
index 22a8f28..a84a326 100644
--- gcc/gcc/config/i386/driver-i386.c
+++ gcc/gcc/config/i386/driver-i386.c
@@ -238,6 +238,7 @@ decode_caches_intel (unsigned reg, bool xeon_mp,
 	break;
       case 0x87:
 	level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
+	gcc_fallthrough ();
 
       default:
 	break;
@@ -326,6 +327,7 @@ detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2,
 				 * cache->line * sets) / 1024;
 	      }
 	  }
+	  gcc_fallthrough ();
 	default:
 	  break;
 	}
diff --git gcc/gcc/config/i386/i386-c.c gcc/gcc/config/i386/i386-c.c
index f93a09d..8e5087d 100644
--- gcc/gcc/config/i386/i386-c.c
+++ gcc/gcc/config/i386/i386-c.c
@@ -210,6 +210,7 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
 	case '3':
 	  def_or_undef (parse_in, "__tune_pentium3__");
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case '2':
 	  def_or_undef (parse_in, "__tune_pentium2__");
 	  break;
diff --git gcc/gcc/config/i386/i386.c gcc/gcc/config/i386/i386.c
index 9eaf414..f7e9845 100644
--- gcc/gcc/config/i386/i386.c
+++ gcc/gcc/config/i386/i386.c
@@ -9284,6 +9284,7 @@ function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
       if (bytes < 0)
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case DImode:
     case SImode:
@@ -9312,12 +9313,14 @@ pass_in_reg:
 	error_p = 1;
       if (cum->float_in_sse < 2)
 	break;
+      gcc_fallthrough ();
     case SFmode:
       if (cum->float_in_sse == -1)
 	error_p = 1;
       if (cum->float_in_sse < 1)
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V8SFmode:
     case V8SImode:
@@ -9547,6 +9550,7 @@ function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
       if (bytes < 0)
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case DImode:
     case SImode:
     case HImode:
@@ -9579,12 +9583,14 @@ pass_in_reg:
 	error_p = 1;
       if (cum->float_in_sse < 2)
 	break;
+      gcc_fallthrough ();
     case SFmode:
       if (cum->float_in_sse == -1)
 	error_p = 1;
       if (cum->float_in_sse < 1)
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case TImode:
       /* In 32bit, we pass TImode in xmm registers.  */
     case V16QImode:
@@ -10984,6 +10990,7 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
 	  container = NULL;
 	  break;
 	}
+      gcc_fallthrough ();
 
     default:
       container = construct_container (nat_mode, TYPE_MODE (type),
@@ -11495,6 +11502,7 @@ standard_sse_constant_opcode (rtx_insn *insn, rtx x)
 	case MODE_V8SF:
 	  gcc_assert (TARGET_AVX2);
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case MODE_TI:
 	case MODE_V2DF:
 	case MODE_V4SF:
@@ -14911,6 +14919,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
 	      if (GET_CODE (op) != UNSPEC)
 		return 0;
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 
 	    case UNSPEC:
 	      if (XINT (op, 1) == UNSPEC_TP
@@ -14925,6 +14934,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
 	      if (!REG_P (SUBREG_REG (op)))
 		return 0;
 	      /* FALLTHRU */
+	      gcc_fallthrough ();
 
 	    case REG:
 	      if (!base)
@@ -15186,6 +15196,7 @@ ix86_legitimate_constant_p (machine_mode mode, rtx x)
       if (GET_CODE (x) != SYMBOL_REF)
 	return false;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       /* TLS symbols are never valid.  */
@@ -15217,10 +15228,12 @@ ix86_legitimate_constant_p (machine_mode mode, rtx x)
 	  if (TARGET_64BIT)
 	    return true;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case OImode:
 	case XImode:
 	  if (!standard_sse_constant_p (x, mode))
 	    return false;
+	  gcc_fallthrough ();
 	default:
 	  break;
 	}
@@ -15229,6 +15242,7 @@ ix86_legitimate_constant_p (machine_mode mode, rtx x)
     case CONST_VECTOR:
       if (!standard_sse_constant_p (x, mode))
 	return false;
+      gcc_fallthrough ();
 
     default:
       break;
@@ -15307,6 +15321,7 @@ legitimate_pic_operand_p (rtx x)
 	    return false;
 	  }
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
     case LABEL_REF:
@@ -15357,6 +15372,7 @@ legitimate_pic_address_disp_p (rtx disp)
 	  if (GET_CODE (op0) != SYMBOL_REF)
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case SYMBOL_REF:
 	  /* TLS references should always be enclosed in UNSPEC.
@@ -15613,6 +15629,7 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
 		&& ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
 	      goto is_legitimate_pic;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case UNSPEC_GOTOFF:
 	    gcc_assert (flag_pic);
 	    if (!TARGET_64BIT)
@@ -15625,6 +15642,7 @@ ix86_legitimate_address_p (machine_mode, rtx addr, bool strict)
 	    if (ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
 	      goto is_legitimate_pic;
 	    /* FALLTHRU */
+	    gcc_fallthrough ();
 	  case UNSPEC_PCREL:
 	    gcc_assert (flag_pic);
 	    goto is_legitimate_pic;
@@ -16679,6 +16697,7 @@ output_pic_addr_const (FILE *file, rtx x, int code)
     case LABEL_REF:
       x = XEXP (x, 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
     case CODE_LABEL:
       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
       assemble_name (asm_out_file, buf);
@@ -17292,6 +17311,7 @@ print_reg (rtx x, int code, FILE *file)
     case 4:
       if (LEGACY_INT_REGNO_P (regno))
 	putc (msize == 8 && TARGET_64BIT ? 'r' : 'e', file);
+      gcc_fallthrough ();
     case 16:
     case 12:
     case 2:
@@ -17541,6 +17561,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
 	    warning
 	      (0, "non-integer operand used with operand code 'z'");
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case 'Z':
 	  /* 387 opcodes don't get size suffixes if using Intel opcodes.  */
@@ -17701,6 +17722,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
 		  fputs ("eq_us", file);
 		  break;
 		}
+	      gcc_fallthrough ();
 	    case EQ:
 	      fputs ("eq", file);
 	      break;
@@ -17710,6 +17732,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
 		  fputs ("nge", file);
 		  break;
 		}
+	      gcc_fallthrough ();
 	    case LT:
 	      fputs ("lt", file);
 	      break;
@@ -17719,6 +17742,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
 		  fputs ("ngt", file);
 		  break;
 		}
+	      gcc_fallthrough ();
 	    case LE:
 	      fputs ("le", file);
 	      break;
@@ -17731,6 +17755,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
 		  fputs ("neq_oq", file);
 		  break;
 		}
+	      gcc_fallthrough ();
 	    case NE:
 	      fputs ("neq", file);
 	      break;
@@ -17740,6 +17765,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
 		  fputs ("ge", file);
 		  break;
 		}
+	      gcc_fallthrough ();
 	    case UNGE:
 	      fputs ("nlt", file);
 	      break;
@@ -17749,6 +17775,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
 		  fputs ("gt", file);
 		  break;
 		}
+	      gcc_fallthrough ();
 	    case UNGT:
 	      fputs ("nle", file);
 	      break;
@@ -19447,6 +19474,7 @@ ix86_expand_move (machine_mode mode, rtx operands[])
       op1 = XEXP (tmp, 0);
       addend = XEXP (tmp, 1);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       model = SYMBOL_REF_TLS_MODEL (op1);
@@ -19493,6 +19521,7 @@ ix86_expand_move (machine_mode mode, rtx operands[])
 	return;
 
       op1 = convert_to_mode (mode, op1, 1);
+      gcc_fallthrough ();
 
     default:
       break;
@@ -21496,6 +21525,7 @@ ix86_build_const_vector (machine_mode mode, bool vect, rtx value)
     case V4DImode:
     case V2DImode:
       gcc_assert (vect);
+      gcc_fallthrough ();
     case V16SFmode:
     case V8SFmode:
     case V4SFmode:
@@ -21836,14 +21866,17 @@ ix86_match_ccmode (rtx insn, machine_mode req_mode)
       if (req_mode == CCGCmode)
 	return false;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case CCGCmode:
       if (req_mode == CCGOCmode || req_mode == CCNOmode)
 	return false;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case CCGOCmode:
       if (req_mode == CCZmode)
 	return false;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case CCZmode:
       break;
 
@@ -22481,6 +22514,8 @@ ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
 	  op0 = force_reg (mode, gen_rtx_XOR (mode, op0, op1));
 	  op1 = const0_rtx;
 	}
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case TImode:
       /* Expand DImode branch into multiple compare+branch.  */
       {
@@ -23313,6 +23348,7 @@ ix86_prepare_sse_fp_compare_args (rtx dest, enum rtx_code code,
       if (!dest || !rtx_equal_p (dest, *pop1))
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case GE:
     case GT:
@@ -23892,6 +23928,7 @@ ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1,
 	  code = reverse_condition (code);
 	  *negate = true;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case LT:
 	case LTU:
@@ -28915,6 +28952,7 @@ ix86_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
 	  && (dep_insn_type == TYPE_PUSH || dep_insn_type == TYPE_POP))
 	return 0;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case PROCESSOR_ATHLON:
     case PROCESSOR_K8:
@@ -29003,6 +29041,7 @@ ix86_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
 		}
 	    }
 	}
+      gcc_fallthrough ();
 
     default:
       break;
@@ -29842,6 +29881,7 @@ ix86_sched_init_global (FILE *, int, int)
 	  break;
 	}
       /* ... Fall through ...  */
+      gcc_fallthrough ();
     default:
       targetm.sched.dfa_post_advance_cycle = NULL;
       targetm.sched.first_cycle_multipass_init = NULL;
@@ -38725,6 +38765,7 @@ ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target,
 		  goto xop_rotl;
 		case CODE_FOR_xop_rotlv16qi3:
 		  new_icode = CODE_FOR_rotlv16qi3;
+		  gcc_fallthrough ();
 		xop_rotl:
 		  if (CONST_INT_P (op))
 		    {
@@ -40112,6 +40153,7 @@ ix86_expand_args_builtin (const struct builtin_description *d,
 			error ("the next to last argument must be an 8-bit immediate");
 			break;
 		      }
+		    gcc_fallthrough ();
 		  case 1:
 		    error ("the last argument must be an 8-bit immediate");
 		    break;
@@ -40168,6 +40210,8 @@ ix86_expand_args_builtin (const struct builtin_description *d,
     case 5:
       pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op,
 			     args[2].op, args[3].op, args[4].op);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case 6:
       pat = GEN_FCN (icode) (real_target, args[0].op, args[1].op,
 			     args[2].op, args[3].op, args[4].op,
@@ -40542,6 +40586,8 @@ ix86_expand_round_builtin (const struct builtin_description *d,
     case 5:
       pat = GEN_FCN (icode) (target, args[0].op, args[1].op,
 			     args[2].op, args[3].op, args[4].op);
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case 6:
       pat = GEN_FCN (icode) (target, args[0].op, args[1].op,
 			     args[2].op, args[3].op, args[4].op,
@@ -40725,6 +40771,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case VOID_FTYPE_PV8SF_V8SI_V8SF:
     case VOID_FTYPE_PV4DF_V4DI_V4DF:
     case VOID_FTYPE_PV4SF_V4SI_V4SF:
@@ -41973,6 +42020,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
     case IX86_BUILTIN_RDRAND64_STEP:
       icode = CODE_FOR_rdranddi_1;
       mode0 = DImode;
+      gcc_fallthrough ();
 
 rdrand_step:
       op0 = gen_reg_rtx (mode0);
@@ -42024,6 +42072,7 @@ rdrand_step:
     case IX86_BUILTIN_RDSEED64_STEP:
       icode = CODE_FOR_rdseeddi_1;
       mode0 = DImode;
+      gcc_fallthrough ();
 
 rdseed_step:
       op0 = gen_reg_rtx (mode0);
@@ -42069,6 +42118,7 @@ rdseed_step:
     case IX86_BUILTIN_ADDCARRYX64:
       icode = CODE_FOR_addcarrydi;
       mode0 = DImode;
+      gcc_fallthrough ();
 
     handlecarry:
       arg0 = CALL_EXPR_ARG (exp, 0); /* unsigned char c_in.  */
@@ -42149,6 +42199,7 @@ rdseed_step:
       icode = CODE_FOR_kortestzhi;
       mode0 = HImode;
       mode1 = CCZmode;
+      gcc_fallthrough ();
 
     kortest:
       arg0 = CALL_EXPR_ARG (exp, 0); /* Mask reg src1.  */
@@ -42612,6 +42663,7 @@ rdseed_step:
 			if (!integer_zerop (gimple_call_arg (def_stmt, 2)))
 			  break;
 			/* FALLTHRU */
+			gcc_fallthrough ();
 		      case IX86_BUILTIN_CMPEQPD:
 		      case IX86_BUILTIN_CMPEQPS:
 			if (initializer_zerop (gimple_call_arg (def_stmt, 0))
@@ -42841,6 +42893,7 @@ rdseed_step:
 	  if (!TARGET_SSE)
 	    /* Emit a normal call if SSE isn't available.  */
 	    return expand_call (exp, target, ignore);
+	  gcc_fallthrough ();
 	default:
 	  return ix86_expand_args_builtin (d, exp, target);
 	}
@@ -43772,6 +43825,7 @@ avx_vpermilp_parallel (rtx par, machine_mode mode)
 	  mask |= (ipar[i] - 6) << i;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V4DFmode:
       /* In the 256-bit DFmode case, we can only move elements within
@@ -43797,6 +43851,7 @@ avx_vpermilp_parallel (rtx par, machine_mode mode)
 	if (ipar[i] + 8 != ipar[i + 8])
 	  return 0;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V8SFmode:
       /* In 256 bit SFmode case, we have full freedom of
@@ -43807,6 +43862,7 @@ avx_vpermilp_parallel (rtx par, machine_mode mode)
 	  return 0;
       nelt = 4;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V2DFmode:
     case V4SFmode:
@@ -44714,6 +44770,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
 	    return true;
 	  }
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST_VECTOR:
       switch (standard_sse_constant_p (x, mode))
@@ -44728,6 +44785,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST_WIDE_INT:
       /* Fall back to (MEM (SYMBOL_REF)), since that's where
@@ -44773,6 +44831,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
 	    }
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case ROTATE:
     case ASHIFTRT:
@@ -45024,6 +45083,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
 	    }
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case MINUS:
       if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
@@ -45044,6 +45104,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
 	  return false;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case AND:
     case IOR:
@@ -45059,6 +45120,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case NEG:
       if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
@@ -45079,6 +45141,7 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
 	  return false;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case NOT:
       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
@@ -46669,6 +46732,7 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, machine_mode mode,
       if (!mmx_ok)
 	return false;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V4DFmode:
     case V4DImode:
@@ -46871,6 +46935,7 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, machine_mode mode,
       if (!mmx_ok)
 	return false;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V2DFmode:
     case V2DImode:
@@ -46994,6 +47059,7 @@ ix86_expand_vector_init_one_var (bool mmx_ok, machine_mode mode,
       /* Use ix86_expand_vector_set in 64bit mode only.  */
       if (!TARGET_64BIT)
 	return false;
+      gcc_fallthrough ();
     case V4DFmode:
     case V8SFmode:
     case V8SImode:
@@ -47336,6 +47402,7 @@ ix86_expand_vector_init_interleave (machine_mode mode,
       second_imode = V2DImode;
       gen_interleave_second_low = gen_vec_interleave_lowv2di;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V2DImode:
       op0 = gen_reg_rtx (second_imode);
@@ -47371,6 +47438,7 @@ ix86_expand_vector_init_general (bool mmx_ok, machine_mode mode,
       if (!mmx_ok && !TARGET_SSE)
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V16SImode:
     case V16SFmode:
@@ -47448,6 +47516,7 @@ quarter:
       if (!TARGET_SSE4_1)
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V8HImode:
       if (!TARGET_SSE2)
@@ -47928,6 +47997,7 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt)
       if (!mmx_ok)
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case V2DFmode:
     case V2DImode:
@@ -50006,6 +50076,7 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
 	mask |= (d->perm[i * 2] >= 16) << i;
       vmode = V8HImode;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     do_subreg:
       target = gen_reg_rtx (vmode);
@@ -52656,6 +52727,7 @@ canonicalize_perm (struct expand_vec_perm_d *d)
 	 of the permutation by folding the permutation into the single
 	 input vector.  */
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 2:
       for (i = 0; i < nelt; ++i)
@@ -52945,6 +53017,7 @@ ix86_expand_vecop_qihi (enum rtx_code code, rtx dest, rtx op1, rtx op2)
     case LSHIFTRT:
       uns_p = true;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case ASHIFTRT:
       op1_l = gen_reg_rtx (himode);
       op1_h = gen_reg_rtx (himode);
@@ -54627,6 +54700,7 @@ ix86_preferred_simd_mode (machine_mode mode)
       else if (TARGET_SSE2)
 	return V2DFmode;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     default:
       return word_mode;
diff --git gcc/gcc/config/i386/sse.md gcc/gcc/config/i386/sse.md
index c1ea04f..6b500bc 100644
--- gcc/gcc/config/i386/sse.md
+++ gcc/gcc/config/i386/sse.md
@@ -3185,6 +3185,7 @@
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case 1:
       ops = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
       break;
@@ -12221,6 +12222,7 @@
       if (GET_MODE_SIZE (<ssescalarmode>mode) < GET_MODE_SIZE (SImode))
 	return "pinsr<ssemodesuffix>\t{%3, %k2, %0|%0, %k2, %3}";
       /* FALLTHRU */
+      gcc_fallthrough ();
     case 1:
       return "pinsr<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}";
     case 2:
@@ -12228,6 +12230,7 @@
       if (GET_MODE_SIZE (<ssescalarmode>mode) < GET_MODE_SIZE (SImode))
 	return "vpinsr<ssemodesuffix>\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
       /* FALLTHRU */
+      gcc_fallthrough ();
     case 3:
     case 5:
       return "vpinsr<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}";
@@ -13481,6 +13484,7 @@
 	}
       operands[1] = tmp;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case 32:
       tmp = gen_reg_rtx (<ssevecmode>mode);
       if (<MODE>mode == SImode)

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: go
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (8 preceding siblings ...)
  2016-07-11 19:54 ` Implement -Wswitch-fallthrough: java Marek Polacek
@ 2016-07-11 19:54 ` Marek Polacek
  2016-07-11 19:55 ` Implement -Wswitch-fallthrough: libcpp Marek Polacek
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:54 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* go-system.h (go_fallthrough): New macro. 
	* gofrontend/escape.cc (Escape_analysis_assign::statement): Use it.
	(Escape_analysis_assign::assign): Likewise.
	* gofrontend/expressions.cc
	(Binary_expression::do_get_backend): Likewise.
	* gofrontend/lex.cc (Lex::next_token): Likewise.

diff --git gcc/gcc/go/go-system.h gcc/gcc/go/go-system.h
index cb7e745..e1b6a70 100644
--- gcc/gcc/go/go-system.h
+++ gcc/gcc/go/go-system.h
@@ -138,4 +138,7 @@ struct hash<T*>
 // When using gcc, go_unreachable is just gcc_unreachable.
 #define go_unreachable() gcc_unreachable()
 
+// When using gcc, go_fallthrough is just gcc_fallthrough.
+#define go_fallthrough() gcc_fallthrough()
+
 #endif // !defined(GO_SYSTEM_H)
diff --git gcc/gcc/go/gofrontend/escape.cc gcc/gcc/go/gofrontend/escape.cc
index 7a55818..f3d09e5 100644
--- gcc/gcc/go/gofrontend/escape.cc
+++ gcc/gcc/go/gofrontend/escape.cc
@@ -729,6 +729,7 @@ Escape_analysis_assign::statement(Block*, size_t*, Statement* s)
       if (this->context_->loop_depth() == 1)
 	break;
       // fallthrough
+      go_fallthrough ();
 
     case Statement::STATEMENT_GO:
       {
@@ -1483,6 +1484,7 @@ Escape_analysis_assign::assign(Node* dst, Node* src)
 	    // A non-pointer can't escape from a struct.
 	    if (!e->type()->has_pointer())
 	      break;
+	    go_fallthrough ();
 	  }
 
 	case Expression::EXPRESSION_CONVERSION:
diff --git gcc/gcc/go/gofrontend/expressions.cc gcc/gcc/go/gofrontend/expressions.cc
index 5f7e4c9..a13c997 100644
--- gcc/gcc/go/gofrontend/expressions.cc
+++ gcc/gcc/go/gofrontend/expressions.cc
@@ -5745,6 +5745,7 @@ Binary_expression::do_get_backend(Translate_context* context)
     case OPERATOR_DIV:
       if (left_type->float_type() != NULL || left_type->complex_type() != NULL)
         break;
+      go_fallthrough ();
     case OPERATOR_MOD:
       is_idiv_op = true;
       break;
@@ -5754,6 +5755,7 @@ Binary_expression::do_get_backend(Translate_context* context)
       break;
     case OPERATOR_BITCLEAR:
       this->right_ = Expression::make_unary(OPERATOR_XOR, this->right_, loc);
+      go_fallthrough ();
     case OPERATOR_AND:
       break;
     default:
diff --git gcc/gcc/go/gofrontend/lex.cc gcc/gcc/go/gofrontend/lex.cc
index 34a0811..4defad5 100644
--- gcc/gcc/go/gofrontend/lex.cc
+++ gcc/gcc/go/gofrontend/lex.cc
@@ -674,6 +674,7 @@ Lex::next_token()
 		    }
 		}
 	      // Fall through.
+	      go_fallthrough ();
 	    case '|':
 	    case '=':
 	    case '!':

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: java
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (7 preceding siblings ...)
  2016-07-11 19:54 ` Implement -Wswitch-fallthrough: i386 Marek Polacek
@ 2016-07-11 19:54 ` Marek Polacek
  2016-07-11 21:26   ` Tom Tromey
  2016-07-11 19:54 ` Implement -Wswitch-fallthrough: go Marek Polacek
                   ` (20 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:54 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* expr.c (java_truthvalue_conversion): Add gcc_fallthrough.
	(type_assertion_hasher::hash): Likewise.
	* jcf-dump.c (print_constant): Likewise.
	* jcf-io.c (verify_constant_pool): Likewise.
	* typeck.c (promote_type): Likewise.

diff --git gcc/gcc/java/expr.c gcc/gcc/java/expr.c
index 2b856e5..d824b6c 100644
--- gcc/gcc/java/expr.c
+++ gcc/gcc/java/expr.c
@@ -192,6 +192,7 @@ java_truthvalue_conversion (tree expr)
           >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
         return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
       /* fall through to default */
+      gcc_fallthrough ();
 
     default:
       return fold_build2 (NE_EXPR, boolean_type_node,
@@ -410,11 +411,13 @@ type_assertion_hasher::hash (type_assertion *k_p)
       hash = iterative_hash (&TYPE_UID (k_p->op2), sizeof TYPE_UID (k_p->op2),
 			     hash);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case JV_ASSERT_IS_INSTANTIABLE:
       hash = iterative_hash (&TYPE_UID (k_p->op1), sizeof TYPE_UID (k_p->op1),
 			     hash);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case JV_ASSERT_END_OF_TABLE:
       break;
diff --git gcc/gcc/java/jcf-dump.c gcc/gcc/java/jcf-dump.c
index 1331b55..d8733ed 100644
--- gcc/gcc/java/jcf-dump.c
+++ gcc/gcc/java/jcf-dump.c
@@ -926,6 +926,8 @@ print_constant (FILE *out, JCF *jcf, int index, int verbosity)
 	  if (verbosity > 0)
 	    fprintf (out, "Fieldref: %ld=", (long) JPOOL_USHORT2 (jcf, index));
 	  print_constant (out, jcf, JPOOL_USHORT2 (jcf, index), 0);
+	  /* XXX Really fallthru?  */
+	  gcc_fallthrough ();
 	case 5:
 	case 6:
 	case 7:
diff --git gcc/gcc/java/jcf-io.c gcc/gcc/java/jcf-io.c
index a560db7..91d9048 100644
--- gcc/gcc/java/jcf-io.c
+++ gcc/gcc/java/jcf-io.c
@@ -472,6 +472,7 @@ verify_constant_pool (JCF *jcf)
 	      || JPOOL_TAG (jcf, n) != CONSTANT_Utf8)
 	    return i;
 	  /* ... fall through ... */
+	  gcc_fallthrough ();
 	case CONSTANT_Class:
 	case CONSTANT_String:
 	  n = JPOOL_USHORT1 (jcf, i);
diff --git gcc/gcc/java/typeck.c gcc/gcc/java/typeck.c
index d2e3db6..f7c5da4 100644
--- gcc/gcc/java/typeck.c
+++ gcc/gcc/java/typeck.c
@@ -332,6 +332,7 @@ promote_type (tree type)
     case INTEGER_TYPE:
       if (type == char_type_node)
 	return promoted_char_type_node;
+      gcc_fallthrough ();
     handle_int:
       if (TYPE_PRECISION (type) < TYPE_PRECISION (int_type_node))
 	{
@@ -342,6 +343,7 @@ promote_type (tree type)
 	  return int_type_node;
 	}
       /* ... else fall through ... */
+      gcc_fallthrough ();
     default:
       return type;
     }

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: libatomic
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (10 preceding siblings ...)
  2016-07-11 19:55 ` Implement -Wswitch-fallthrough: libcpp Marek Polacek
@ 2016-07-11 19:55 ` Marek Polacek
  2016-07-11 19:56 ` Implement -Wswitch-fallthrough: libgcc Marek Polacek
                   ` (17 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:55 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* libatomic_i.h (libat_fallthrough): New macro.
	* gcas.c (libat_compare_exchange): Use libat_fallthrough.
	* gexch.c (libat_exchange): Likewise.
	* glfree.c (libat_is_lock_free): Likewise.
	* gload.c (libat_load): Likewise.
	* gstore.c (libat_store): Likewise.

diff --git gcc/libatomic/gcas.c gcc/libatomic/gcas.c
index 6a5025d..224df8e 100644
--- gcc/libatomic/gcas.c
+++ gcc/libatomic/gcas.c
@@ -92,8 +92,8 @@ libat_compare_exchange (size_t n, void *mptr, void *eptr, void *dptr,
     case 8:		EXACT(8);	goto L16;
     case 16:		EXACT(16);	break;
 
-    case 3: L4:		LARGER(4);	/* FALLTHRU */
-    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */
+    case 3: L4:		LARGER(4);	/* FALLTHRU */ libat_fallthrough ();
+    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */ libat_fallthrough ();
     case 9 ... 15: L16:	LARGER(16);	break;
 
     Lsucc:
diff --git gcc/libatomic/gexch.c gcc/libatomic/gexch.c
index fddb794..876ae87 100644
--- gcc/libatomic/gexch.c
+++ gcc/libatomic/gexch.c
@@ -116,8 +116,8 @@ libat_exchange (size_t n, void *mptr, void *vptr, void *rptr, int smodel)
     case 8:		EXACT(8);	goto L16;
     case 16:		EXACT(16);	break;
 
-    case 3: L4:		LARGER(4);	/* FALLTHRU */
-    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */
+    case 3: L4:		LARGER(4);	/* FALLTHRU */ libat_fallthrough ();
+    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */ libat_fallthrough ();
     case 9 ... 15: L16:	LARGER(16);	break;
 
     Lfinish:
diff --git gcc/libatomic/glfree.c gcc/libatomic/glfree.c
index fd1b3a7..3bb09de 100644
--- gcc/libatomic/glfree.c
+++ gcc/libatomic/glfree.c
@@ -56,8 +56,8 @@ libat_is_lock_free (size_t n, void *ptr)
     case 8:		EXACT(8);	goto L16;
     case 16:		EXACT(16);	break;
 
-    case 3: L4:		LARGER(4);	/* FALLTHRU */
-    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */
+    case 3: L4:		LARGER(4);	/* FALLTHRU */ libat_fallthrough ();
+    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */ libat_fallthrough ();
     case 9 ... 15: L16:	LARGER(16);	break;
     }
 
diff --git gcc/libatomic/gload.c gcc/libatomic/gload.c
index 64a0dc5..b4cc61c 100644
--- gcc/libatomic/gload.c
+++ gcc/libatomic/gload.c
@@ -79,8 +79,8 @@ libat_load (size_t n, void *mptr, void *rptr, int smodel)
     case 8:		EXACT(8);	goto L16;
     case 16:		EXACT(16);	break;
 
-    case 3: L4:		LARGER(4);	/* FALLTHRU */
-    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */
+    case 3: L4:		LARGER(4);	/* FALLTHRU */ libat_fallthrough ();
+    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */ libat_fallthrough ();
     case 9 ... 15: L16:	LARGER(16);	break;
 
     Lfinish:
diff --git gcc/libatomic/gstore.c gcc/libatomic/gstore.c
index af1d060..90a7430 100644
--- gcc/libatomic/gstore.c
+++ gcc/libatomic/gstore.c
@@ -91,8 +91,8 @@ libat_store (size_t n, void *mptr, void *vptr, int smodel)
     case 8:		EXACT(8);	goto L16;
     case 16:		EXACT(16);	break;
 
-    case 3: L4:		LARGER(4);	/* FALLTHRU */
-    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */
+    case 3: L4:		LARGER(4);	/* FALLTHRU */ libat_fallthrough ();
+    case 5 ... 7: L8:	LARGER(8);	/* FALLTHRU */ libat_fallthrough ();
     case 9 ... 15: L16:	LARGER(16);	break;
     }
 
diff --git gcc/libatomic/libatomic_i.h gcc/libatomic/libatomic_i.h
index 9206a8e..0faa103 100644
--- gcc/libatomic/libatomic_i.h
+++ gcc/libatomic/libatomic_i.h
@@ -200,6 +200,12 @@ void libat_unlock_n (void *ptr, size_t n);
 # define DECLARE_1(RET,NAME,ARGS)	RET C2(libat_,NAME) ARGS MAN(NAME)
 #endif
 
+#if __GNUC__ >= 7
+# define libat_fallthrough() __builtin_fallthrough ()
+#else
+# define libat_fallthrough()
+#endif
+
 /* Prefix to use when calling internal, possibly ifunc'ed functions.  */
 #if HAVE_IFUNC
 # define local_ ifunc_

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: libcpp
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (9 preceding siblings ...)
  2016-07-11 19:54 ` Implement -Wswitch-fallthrough: go Marek Polacek
@ 2016-07-11 19:55 ` Marek Polacek
  2016-07-11 19:55 ` Implement -Wswitch-fallthrough: libatomic Marek Polacek
                   ` (18 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:55 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* internal.h (CPP_FALLTHRU): Define.
	* expr.c (_cpp_parse_expr): Use CPP_FALLTHRU.
	* lex.c (search_line_fast): Likewise.
	(lex_raw_string): Likewise.
	(_cpp_lex_direct): Likewise.
	(cpp_token_val_index): Likewise.
	* macro.c (parse_params): Likewise.
	* pch.c (write_macdef): Likewise.
	(count_defs): Likewise.
	(write_defs): Likewise.

diff --git gcc/libcpp/expr.c gcc/libcpp/expr.c
index 5cdca6f..361e157 100644
--- gcc/libcpp/expr.c
+++ gcc/libcpp/expr.c
@@ -1311,6 +1311,7 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if)
 	    pfile->state.skip_eval++;
 	  else
 	    pfile->state.skip_eval--;
+	  CPP_FALLTHRU ();
 	default:
 	  break;
 	}
diff --git gcc/libcpp/internal.h gcc/libcpp/internal.h
index ca2b498..32aba40 100644
--- gcc/libcpp/internal.h
+++ gcc/libcpp/internal.h
@@ -78,6 +78,12 @@ struct cset_converter
    efficiency, and partly to limit runaway recursion.  */
 #define CPP_STACK_MAX 200
 
+#if __GNUC__ >= 7
+# define CPP_FALLTHRU() __builtin_fallthrough ()
+#else
+# define CPP_FALLTHRU()
+#endif
+
 /* Host alignment handling.  */
 struct dummy
 {
diff --git gcc/libcpp/lex.c gcc/libcpp/lex.c
index 236418d..ed884a4 100644
--- gcc/libcpp/lex.c
+++ gcc/libcpp/lex.c
@@ -610,6 +610,7 @@ search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED)
 	if (l != 0)
 	  break;
 	s += sizeof(unsigned long);
+	CPP_FALLTHRU ();
       case 2:
 	l = u.l[i++];
 	if (l != 0)
@@ -1574,6 +1575,7 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
 	      BUF_APPEND (base, cur - base);
 	      base = cur;
 	      BUF_APPEND ("\\", 1);
+	      CPP_FALLTHRU ();
 	    after_backslash:
 	      if (note->type == ' ')
 		{
@@ -2415,6 +2417,7 @@ _cpp_lex_direct (cpp_reader *pfile)
 	    }
 	}
       /* Fall through.  */
+      CPP_FALLTHRU ();
 
     case '_':
     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
@@ -2717,6 +2720,8 @@ _cpp_lex_direct (cpp_reader *pfile)
 	  }
 	buffer->cur++;
       }
+      /* XXX Really fallthru?  */
+      CPP_FALLTHRU ();
 
     default:
       create_literal (pfile, result, buffer->cur - 1, 1, CPP_OTHER);
@@ -3323,6 +3328,7 @@ cpp_token_val_index (const cpp_token *tok)
       else if (tok->type == CPP_PRAGMA)
 	return CPP_TOKEN_FLD_PRAGMA;
       /* else fall through */
+      CPP_FALLTHRU ();
     default:
       return CPP_TOKEN_FLD_NONE;
     }
diff --git gcc/libcpp/macro.c gcc/libcpp/macro.c
index a3b8348..c2c0de4 100644
--- gcc/libcpp/macro.c
+++ gcc/libcpp/macro.c
@@ -2886,6 +2886,7 @@ parse_params (cpp_reader *pfile, cpp_macro *macro)
 	    return true;
 
 	  /* Fall through to pick up the error.  */
+	  CPP_FALLTHRU ();
 	case CPP_COMMA:
 	  if (!prev_ident)
 	    {
@@ -2937,6 +2938,7 @@ parse_params (cpp_reader *pfile, cpp_macro *macro)
 	  if (token->type == CPP_CLOSE_PAREN)
 	    return true;
 	  /* Fall through.  */
+	  CPP_FALLTHRU ();
 
 	case CPP_EOF:
 	  cpp_error (pfile, CPP_DL_ERROR, "missing ')' in macro parameter list");
diff --git gcc/libcpp/pch.c gcc/libcpp/pch.c
index aa5ed6b..31f8bc5 100644
--- gcc/libcpp/pch.c
+++ gcc/libcpp/pch.c
@@ -55,6 +55,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
     case NT_VOID:
       if (! (hn->flags & NODE_POISONED))
 	return 1;
+      CPP_FALLTHRU ();
 
     case NT_MACRO:
       if ((hn->flags & NODE_BUILTIN)
@@ -231,6 +232,7 @@ count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
 	return 1;
 
       /* else fall through.  */
+      CPP_FALLTHRU ();
 
     case NT_VOID:
       {
@@ -270,6 +272,7 @@ write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
 	return 1;
 
       /* else fall through.  */
+      CPP_FALLTHRU ();
 
     case NT_VOID:
       {

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: libgcc
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (11 preceding siblings ...)
  2016-07-11 19:55 ` Implement -Wswitch-fallthrough: libatomic Marek Polacek
@ 2016-07-11 19:56 ` Marek Polacek
  2016-07-11 19:56 ` Implement -Wswitch-fallthrough: libgomp Marek Polacek
                   ` (16 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:56 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* soft-fp/soft-fp.h (_FP_FALLTHRU): Define.
	* soft-fp/op-common.h: Use it.

diff --git gcc/libgcc/soft-fp/op-common.h gcc/libgcc/soft-fp/op-common.h
index 080ef0e..6691f50 100644
--- gcc/libgcc/soft-fp/op-common.h
+++ gcc/libgcc/soft-fp/op-common.h
@@ -898,6 +898,7 @@
 	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):		\
 	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):		\
 	  R##_s = X##_s;					\
+	  _FP_FALLTHRU ();						\
 								\
 	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):		\
 	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):	\
@@ -911,6 +912,7 @@
 	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):		\
 	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):		\
 	  R##_s = Y##_s;					\
+	  _FP_FALLTHRU ();						\
 								\
 	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF):	\
 	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO):	\
@@ -1198,6 +1200,7 @@
 								\
 	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO):	\
 	  FP_SET_EXCEPTION (FP_EX_DIVZERO);			\
+	  _FP_FALLTHRU ();						\
 	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):		\
 	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):	\
 	  R##_c = FP_CLS_INF;					\
diff --git gcc/libgcc/soft-fp/soft-fp.h gcc/libgcc/soft-fp/soft-fp.h
index 3b39336..999b145 100644
--- gcc/libgcc/soft-fp/soft-fp.h
+++ gcc/libgcc/soft-fp/soft-fp.h
@@ -71,6 +71,12 @@
     [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
 #endif
 
+#if (defined __GNUC__ && __GNUC__ >= 7)
+# define _FP_FALLTHRU() __builtin_fallthrough ()
+#else
+# define _FP_FALLTHRU()
+#endif
+
 /* In the Linux kernel, some architectures have a single function that
    uses different kinds of unpacking and packing depending on the
    instruction being emulated, meaning it is not readily visible to

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: libgomp
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (12 preceding siblings ...)
  2016-07-11 19:56 ` Implement -Wswitch-fallthrough: libgcc Marek Polacek
@ 2016-07-11 19:56 ` Marek Polacek
  2016-07-11 19:57 ` Implement -Wswitch-fallthrough: libgo Marek Polacek
                   ` (15 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:56 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* libgomp.h (gomp_fallthrough): Define.
	* oacc-init.c (resolve_device): Use gomp_fallthrough.
	* testsuite/libgomp.c++/cancel-parallel-2.C: Add __builtin_fallthrough.
	* testsuite/libgomp.c/cancel-parallel-2.c: Add __builtin_fallthrough.

diff --git gcc/libgomp/libgomp.h gcc/libgomp/libgomp.h
index 7b2671b..c0c5e60 100644
--- gcc/libgomp/libgomp.h
+++ gcc/libgomp/libgomp.h
@@ -1080,6 +1080,12 @@ extern int gomp_test_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW;
 # define ialias_call(fn) fn
 #endif
 
+#if __GNUC__ >= 7
+# define gomp_fallthrough() __builtin_fallthrough ()
+#else
+# define gomp_fallthrough()
+#endif
+
 /* Helper function for priority_node_to_task() and
    task_to_priority_node().
 
diff --git gcc/libgomp/oacc-init.c gcc/libgomp/oacc-init.c
index f2325ad..70308fc 100644
--- gcc/libgomp/oacc-init.c
+++ gcc/libgomp/oacc-init.c
@@ -144,6 +144,7 @@ resolve_device (acc_device_t d, bool fail_is_error)
 	d = acc_device_not_host;
       }
       /* FALLTHROUGH */
+      gomp_fallthrough ();
 
     case acc_device_not_host:
       /* Find the first available device after acc_device_not_host.  */
diff --git gcc/libgomp/testsuite/libgomp.c++/cancel-parallel-2.C gcc/libgomp/testsuite/libgomp.c++/cancel-parallel-2.C
index 23b8caa..f793f8a 100644
--- gcc/libgomp/testsuite/libgomp.c++/cancel-parallel-2.C
+++ gcc/libgomp/testsuite/libgomp.c++/cancel-parallel-2.C
@@ -31,6 +31,7 @@ foo (int *x)
       case 2:
 	usleep (1000);
 	/* FALLTHRU */
+	__builtin_fallthrough ();
       case 1:;
 	#pragma omp cancellation point parallel
 	break;
diff --git gcc/libgomp/testsuite/libgomp.c/cancel-parallel-2.c gcc/libgomp/testsuite/libgomp.c/cancel-parallel-2.c
index 20adb55..054a96e 100644
--- gcc/libgomp/testsuite/libgomp.c/cancel-parallel-2.c
+++ gcc/libgomp/testsuite/libgomp.c/cancel-parallel-2.c
@@ -27,6 +27,7 @@ foo (int *x)
       case 2:
 	usleep (1000);
 	/* FALLTHRU */
+	__builtin_fallthrough ();
       case 1:;
 	#pragma omp cancellation point parallel
 	break;

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: libiberty
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (14 preceding siblings ...)
  2016-07-11 19:57 ` Implement -Wswitch-fallthrough: libgo Marek Polacek
@ 2016-07-11 19:57 ` Marek Polacek
  2016-07-11 19:58 ` Implement -Wswitch-fallthrough: objc Marek Polacek
                   ` (13 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:57 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* cp-demangle.c (d_print_comp_inner): Use D_FALLTHRU.
	(d_print_mod): Likewise.
	* cplus-dem.c (demangle_signature): Likewise.
	(demangle_fund_type): Likewise.
	(do_hpacc_template_const_value): Likewise.
	* d-demangle.c (dlang_value): Likewise.
	* hashtab.c (iterative_hash): Likewise.
	* regex.c (FALLTHRU): Define.
	(byte_re_match_2_internal): Use FALLTHRU.

diff --git gcc/libiberty/cp-demangle.c gcc/libiberty/cp-demangle.c
index 09d6469..6bd8e65 100644
--- gcc/libiberty/cp-demangle.c
+++ gcc/libiberty/cp-demangle.c
@@ -4824,6 +4824,7 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
 	  mod_inner = d_left (sub);
       }
       /* Fall through.  */
+      D_FALLTHRU ();
 
     case DEMANGLE_COMPONENT_RESTRICT_THIS:
     case DEMANGLE_COMPONENT_VOLATILE_THIS:
@@ -5634,11 +5635,13 @@ d_print_mod (struct d_print_info *dpi, int options,
     case DEMANGLE_COMPONENT_REFERENCE_THIS:
       /* For the ref-qualifier, put a space before the &.  */
       d_append_char (dpi, ' ');
+      D_FALLTHRU ();
     case DEMANGLE_COMPONENT_REFERENCE:
       d_append_char (dpi, '&');
       return;
     case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
       d_append_char (dpi, ' ');
+      D_FALLTHRU ();
     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
       d_append_string (dpi, "&&");
       return;
diff --git gcc/libiberty/cplus-dem.c gcc/libiberty/cplus-dem.c
index d04c32a..97aa2c7 100644
--- gcc/libiberty/cplus-dem.c
+++ gcc/libiberty/cplus-dem.c
@@ -1642,6 +1642,7 @@ demangle_signature (struct work_stuff *work,
 	  else
 	    /* fall through */
 	    {;}
+	  D_FALLTHRU ();
 
 	default:
 	  if (AUTO_DEMANGLING || GNU_DEMANGLING)
@@ -3992,6 +3993,8 @@ demangle_fund_type (struct work_stuff *work,
 	  success = 0;
 	  break;
 	}
+      /* XXX Really fallthru?  */
+      D_FALLTHRU ();
     case 'I':
       (*mangled)++;
       if (**mangled == '_')
@@ -4086,7 +4089,8 @@ do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
     {
       case 'N':
         string_append (result, "-");
-        /* fall through */
+	/* fall through */
+	D_FALLTHRU ();
       case 'P':
         (*mangled)++;
         break;
diff --git gcc/libiberty/d-demangle.c gcc/libiberty/d-demangle.c
index 4ad90a6..e7d39e4 100644
--- gcc/libiberty/d-demangle.c
+++ gcc/libiberty/d-demangle.c
@@ -1244,6 +1244,7 @@ dlang_value (string *decl, const char *mangled, const char *name, char type)
       if (*mangled < '0' || *mangled > '9')
 	return NULL;
       /* Fall through */
+     D_FALLTHRU ();
     case '0': case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9':
       mangled = dlang_parse_integer (decl, mangled, type);
diff --git gcc/libiberty/hashtab.c gcc/libiberty/hashtab.c
index 04607ea..cd8d8c5 100644
--- gcc/libiberty/hashtab.c
+++ gcc/libiberty/hashtab.c
@@ -962,18 +962,18 @@ iterative_hash (const PTR k_in /* the key */,
   c += length;
   switch(len)              /* all the case statements fall through */
     {
-    case 11: c+=((hashval_t)k[10]<<24);
-    case 10: c+=((hashval_t)k[9]<<16);
-    case 9 : c+=((hashval_t)k[8]<<8);
+    case 11: c+=((hashval_t)k[10]<<24); D_FALLTHRU ();
+    case 10: c+=((hashval_t)k[9]<<16); D_FALLTHRU ();
+    case 9 : c+=((hashval_t)k[8]<<8); D_FALLTHRU ();
       /* the first byte of c is reserved for the length */
-    case 8 : b+=((hashval_t)k[7]<<24);
-    case 7 : b+=((hashval_t)k[6]<<16);
-    case 6 : b+=((hashval_t)k[5]<<8);
-    case 5 : b+=k[4];
-    case 4 : a+=((hashval_t)k[3]<<24);
-    case 3 : a+=((hashval_t)k[2]<<16);
-    case 2 : a+=((hashval_t)k[1]<<8);
-    case 1 : a+=k[0];
+    case 8 : b+=((hashval_t)k[7]<<24); D_FALLTHRU ();
+    case 7 : b+=((hashval_t)k[6]<<16); D_FALLTHRU ();
+    case 6 : b+=((hashval_t)k[5]<<8); D_FALLTHRU ();
+    case 5 : b+=k[4]; D_FALLTHRU ();
+    case 4 : a+=((hashval_t)k[3]<<24); D_FALLTHRU ();
+    case 3 : a+=((hashval_t)k[2]<<16); D_FALLTHRU ();
+    case 2 : a+=((hashval_t)k[1]<<8); D_FALLTHRU ();
+    case 1 : a+=k[0]; D_FALLTHRU ();
       /* case 0: nothing left to add */
     }
   mix(a,b,c);
diff --git gcc/libiberty/regex.c gcc/libiberty/regex.c
index 9ffc3f4..c8e5ea9 100644
--- gcc/libiberty/regex.c
+++ gcc/libiberty/regex.c
@@ -1368,6 +1368,12 @@ static const char *re_error_msgid[] =
 \f
 #endif /* INSIDE_RECURSION */
 
+#if __GNUC__ >= 7
+# define FALLTHRU() __builtin_fallthrough ()
+#else
+# define FALLTHRU()
+#endif
+
 #ifndef DEFINED_ONCE
 /* Avoiding alloca during matching, to placate r_alloc.  */
 
@@ -2493,6 +2499,7 @@ PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
           if ((syntax & RE_BK_PLUS_QM)
               || (syntax & RE_LIMITED_OPS))
             goto normal_char;
+	  FALLTHRU ();
         handle_plus:
         case '*':
           /* If there is no previous pattern... */
@@ -3654,6 +3661,7 @@ PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
             case '(':
               if (syntax & RE_NO_BK_PARENS)
                 goto normal_backslash;
+	      FALLTHRU ();
 
             handle_open:
               bufp->re_nsub++;
@@ -3711,6 +3719,7 @@ PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
 		  else
 		    FREE_STACK_RETURN (REG_ERPAREN);
 		}
+	      FALLTHRU ();
 
             handle_close:
               if (fixup_alt_jump)
@@ -3774,6 +3783,7 @@ PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
             case '|':					/* `\|'.  */
               if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
                 goto normal_backslash;
+	      FALLTHRU ();
             handle_alt:
               if (syntax & RE_LIMITED_OPS)
                 goto normal_char;
@@ -3824,6 +3834,7 @@ PREFIX(regex_compile) (const char *ARG_PREFIX(pattern),
                         operator.  */
 		  || (syntax & RE_NO_BK_BRACES))
                 goto normal_backslash;
+	      FALLTHRU ();
 
             handle_interval:
               {
@@ -6697,6 +6708,7 @@ byte_re_match_2_internal (struct re_pattern_buffer *bufp,
                 {
                   case jump_n:
 		    is_a_jump_n = true;
+		    FALLTHRU ();
                   case pop_failure_jump:
 		  case maybe_pop_jump:
 		  case jump:
@@ -7126,7 +7138,7 @@ byte_re_match_2_internal (struct re_pattern_buffer *bufp,
 	      goto unconditional_jump;
 	    }
         /* Note fall through.  */
-
+	FALLTHRU ();
 
 	/* The end of a simple repeat has a pop_failure_jump back to
            its matching on_failure_jump, where the latter will push a
@@ -7151,6 +7163,7 @@ byte_re_match_2_internal (struct re_pattern_buffer *bufp,
                                reg_dummy, reg_dummy, reg_info_dummy);
           }
 	  /* Note fall through.  */
+	  FALLTHRU ();
 
 	unconditional_jump:
 #ifdef _LIBC
@@ -7453,6 +7466,7 @@ byte_re_match_2_internal (struct re_pattern_buffer *bufp,
                 {
                 case jump_n:
                   is_a_jump_n = true;
+		  FALLTHRU ();
                 case maybe_pop_jump:
                 case pop_failure_jump:
                 case jump:
@@ -7718,6 +7732,7 @@ PREFIX(common_op_match_null_string_p) (UCHAR_T **p, UCHAR_T *end,
 
     case set_number_at:
       p1 += 2 * OFFSET_ADDRESS_SIZE;
+      FALLTHRU ();
 
     default:
       /* All other opcodes mean we cannot match the empty string.  */

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: libgo
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (13 preceding siblings ...)
  2016-07-11 19:56 ` Implement -Wswitch-fallthrough: libgomp Marek Polacek
@ 2016-07-11 19:57 ` Marek Polacek
  2016-07-11 19:57 ` Implement -Wswitch-fallthrough: libiberty Marek Polacek
                   ` (14 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:57 UTC (permalink / raw)
  To: GCC Patches


2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* runtime/heapdump.c (dumpefacetypes): Add break.

diff --git gcc/libgo/runtime/heapdump.c gcc/libgo/runtime/heapdump.c
index d0cfb01..1ce8aa2 100644
--- gcc/libgo/runtime/heapdump.c
+++ gcc/libgo/runtime/heapdump.c
@@ -766,6 +766,7 @@ dumpefacetypes(void *obj __attribute__ ((unused)), uintptr size, const Type *typ
 		for(i = 0; i <= size - type->__size; i += type->__size)
 			//playgcprog(i, (uintptr*)type->gc + 1, dumpeface_callback, obj);
 		break;
+		break;
 	case TypeInfo_Chan:
 		if(type->__size == 0) // channels may have zero-sized objects in them
 			break;

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: libstdc++
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (16 preceding siblings ...)
  2016-07-11 19:58 ` Implement -Wswitch-fallthrough: objc Marek Polacek
@ 2016-07-11 19:58 ` Marek Polacek
  2016-07-11 22:18   ` Jonathan Wakely
  2016-07-11 19:58 ` Implement -Wswitch-fallthrough: lto Marek Polacek
                   ` (11 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:58 UTC (permalink / raw)
  To: GCC Patches; +Cc: libstdc++


2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* libsupc++/hash_bytes.cc: Use __builtin_fallthrough.

diff --git gcc/libstdc++-v3/libsupc++/hash_bytes.cc gcc/libstdc++-v3/libsupc++/hash_bytes.cc
index 2e5bbfa..818331f 100644
--- gcc/libstdc++-v3/libsupc++/hash_bytes.cc
+++ gcc/libstdc++-v3/libsupc++/hash_bytes.cc
@@ -95,8 +95,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
       case 3:
 	hash ^= static_cast<unsigned char>(buf[2]) << 16;
+	__builtin_fallthrough ();
       case 2:
 	hash ^= static_cast<unsigned char>(buf[1]) << 8;
+	__builtin_fallthrough ();
       case 1:
 	hash ^= static_cast<unsigned char>(buf[0]);
 	hash *= m;

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: lto
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (17 preceding siblings ...)
  2016-07-11 19:58 ` Implement -Wswitch-fallthrough: libstdc++ Marek Polacek
@ 2016-07-11 19:58 ` Marek Polacek
  2016-07-12 10:23   ` Richard Biener
  2016-07-11 19:59 ` Implement -Wswitch-fallthrough: rs6000 Marek Polacek
                   ` (10 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:58 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* lto-plugin.c (lto_fallthrough): Define.
	(parse_table_entry): Use it.

diff --git gcc/lto-plugin/lto-plugin.c gcc/lto-plugin/lto-plugin.c
index 51afc52..ffdf54a 100644
--- gcc/lto-plugin/lto-plugin.c
+++ gcc/lto-plugin/lto-plugin.c
@@ -77,6 +77,12 @@ along with this program; see the file COPYING3.  If not see
 # define O_BINARY 0
 #endif
 
+#if __GNUC__ >= 7
+# define lto_fallthrough() __builtin_fallthrough ()
+#else
+# define lto_fallthrough()
+#endif
+
 /* Segment name for LTO sections.  This is only used for Mach-O.
    FIXME: This needs to be kept in sync with darwin.c.  */
 
@@ -254,6 +260,7 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry,
 	  break;
 	}
     /* FALL-THROUGH.  */
+    lto_fallthrough ();
     case ss_uscore:
       entry->name = concat ("_", p, NULL);
       break;

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: objc
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (15 preceding siblings ...)
  2016-07-11 19:57 ` Implement -Wswitch-fallthrough: libiberty Marek Polacek
@ 2016-07-11 19:58 ` Marek Polacek
  2016-07-11 19:58 ` Implement -Wswitch-fallthrough: libstdc++ Marek Polacek
                   ` (12 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:58 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* objc-encoding.c (encode_type): Add gcc_fallthrough.

diff --git gcc/gcc/objc/objc-encoding.c gcc/gcc/objc/objc-encoding.c
index 41ac6a4..cc64e1b 100644
--- gcc/gcc/objc/objc-encoding.c
+++ gcc/gcc/objc/objc-encoding.c
@@ -622,6 +622,7 @@ encode_type (tree type, int curtype, int format)
 	}
       /* Else, they are encoded exactly like the integer type that is
 	 used by the compiler to store them.  */
+      gcc_fallthrough ();
     case INTEGER_TYPE:
       {
 	char c;

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (18 preceding siblings ...)
  2016-07-11 19:58 ` Implement -Wswitch-fallthrough: lto Marek Polacek
@ 2016-07-11 19:59 ` Marek Polacek
  2016-07-11 20:36   ` Bruce Korb
  2016-07-12 14:11   ` Segher Boessenkool
  2016-07-11 19:59 ` Implement -Wswitch-fallthrough: other archs Marek Polacek
                   ` (9 subsequent siblings)
  29 siblings, 2 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:59 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* config/rs6000/rs6000.c (rs6000_builtin_vectorized_libmass): Likewise.
	(rs6000_legitimate_offset_address_p): Likewise.
	(rs6000_emit_move): Likewise.
	(altivec_expand_ld_builtin): Likewise.
	(altivec_expand_st_builtin): Likewise.
	(rs6000_emit_vector_compare_inner): Likewise.
	(rs6000_adjust_cost): Likewise.
	(insn_must_be_first_in_group): Likewise.
	(rs6000_handle_altivec_attribute): Likewise.
	(rs6000_rtx_costs): Likewise.
	(altivec_expand_vec_perm_const): Likewise.
	(rtx_is_swappable_p): Likewise.
	* config/rs6000/rs6000.md: Likewise.

diff --git gcc/gcc/config/rs6000/rs6000.c gcc/gcc/config/rs6000/rs6000.c
index dd77e1b..a41d6be 100644
--- gcc/gcc/config/rs6000/rs6000.c
+++ gcc/gcc/config/rs6000/rs6000.c
@@ -5459,6 +5459,7 @@ rs6000_builtin_vectorized_libmass (combined_fn fn, tree type_out,
     CASE_CFN_POW:
       n_args = 2;
       /* fall through */
+      gcc_fallthrough ();
 
     CASE_CFN_ACOS:
     CASE_CFN_ACOSH:
@@ -7675,6 +7676,7 @@ rs6000_legitimate_offset_address_p (machine_mode mode, rtx x,
 	return (SPE_CONST_OFFSET_OK (offset)
 		&& SPE_CONST_OFFSET_OK (offset + 8));
       /* fall through */
+      gcc_fallthrough ();
 
     case TDmode:
     case TImode:
@@ -9778,6 +9780,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
       if (FLOAT128_2REG_P (mode))
 	rs6000_eliminate_indexed_memrefs (operands);
       /* fall through */
+      gcc_fallthrough ();
 
     case DFmode:
     case DDmode:
@@ -14398,6 +14401,8 @@ altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
       break;
     case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
       icode = CODE_FOR_vector_altivec_load_v2di;
+      /* XXX Really?  */
+      gcc_fallthrough ();
     case ALTIVEC_BUILTIN_LD_INTERNAL_1ti:
       icode = CODE_FOR_vector_altivec_load_v1ti;
       break;
@@ -14459,6 +14464,8 @@ altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
       break;
     case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
       icode = CODE_FOR_vector_altivec_store_v2di;
+      /* XXX Really?  */
+      gcc_fallthrough ();
     case ALTIVEC_BUILTIN_ST_INTERNAL_1ti:
       icode = CODE_FOR_vector_altivec_store_v1ti;
       break;
@@ -20961,6 +20968,7 @@ print_operand (FILE *file, rtx x, int code)
 	return;
       fputc (',', file);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 'R':
       /* X is a CR register.  Print the mask for `mtcrf'.  */
@@ -22532,6 +22540,7 @@ rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
     case GE:
       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
 	return NULL_RTX;
+      gcc_fallthrough ();
 
     case EQ:
     case GT:
@@ -30191,6 +30200,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
                 && (INSN_CODE (dep_insn) >= 0)
                 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
               return 2;
+	    gcc_fallthrough ();
 
           default:
             break;
@@ -30227,6 +30237,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
             }
         }
       /* Fall through, no cost for output dependency.  */
+      gcc_fallthrough ();
 
     case REG_DEP_ANTI:
       /* Anti dependency; DEP_INSN reads a register that INSN writes some
@@ -31373,6 +31384,7 @@ insn_must_be_first_in_group (rtx_insn *insn)
     case PROCESSOR_POWER5:
       if (is_cracked_insn (insn))
         return true;
+      gcc_fallthrough ();
     case PROCESSOR_POWER4:
       if (is_microcoded_insn (insn))
         return true;
@@ -32290,6 +32302,7 @@ rs6000_handle_altivec_attribute (tree *node,
 	case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
 	case V2DImode: case V2DFmode:
 	  result = type;
+	  gcc_fallthrough ();
 	default: break;
 	}
       break;
@@ -32300,6 +32313,7 @@ rs6000_handle_altivec_attribute (tree *node,
 	case SImode: case V4SImode: result = bool_V4SI_type_node; break;
 	case HImode: case V8HImode: result = bool_V8HI_type_node; break;
 	case QImode: case V16QImode: result = bool_V16QI_type_node;
+	gcc_fallthrough ();
 	default: break;
 	}
       break;
@@ -32307,6 +32321,7 @@ rs6000_handle_altivec_attribute (tree *node,
       switch (mode)
 	{
 	case V8HImode: result = pixel_V8HI_type_node;
+	gcc_fallthrough ();
 	default: break;
 	}
     default: break;
@@ -33912,6 +33927,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST_DOUBLE:
     case CONST_WIDE_INT:
@@ -33973,6 +33989,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return false;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case UDIV:
     case UMOD:
@@ -34086,6 +34103,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return false;
 	}
       /* fall through */
+      gcc_fallthrough ();
 	  
     case ASHIFTRT:
     case LSHIFTRT:
@@ -34124,6 +34142,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return false;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case FLOAT:
     case UNSIGNED_FLOAT:
@@ -34196,6 +34215,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	    }
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case GT:
     case LT:
@@ -34970,6 +34990,7 @@ altivec_expand_vec_perm_const (rtx operands[4])
       if (!rtx_equal_p (op0, op1))
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 2:
       for (i = 0; i < 16; ++i)
@@ -38540,6 +38561,7 @@ rtx_is_swappable_p (rtx op, unsigned int *special)
 	    return 1;
 	  }
       }
+      gcc_fallthrough ();
 
     default:
       break;
diff --git gcc/gcc/config/rs6000/rs6000.md gcc/gcc/config/rs6000/rs6000.md
index a7615b1..3d3cfaa 100644
--- gcc/gcc/config/rs6000/rs6000.md
+++ gcc/gcc/config/rs6000/rs6000.md
@@ -8094,6 +8094,8 @@
     case 0:
       if (TARGET_STRING)
         return \"stswi %1,%P0,16\";
+      /* XXX Really fallthru?  */
+      gcc_fallthrough ();
     case 1:
       return \"#\";
     case 2:
@@ -8103,6 +8105,7 @@
           && ! reg_overlap_mentioned_p (operands[0], operands[1]))
 	return \"lswi %0,%P1,16\";
       /* ... fall through ...  */
+      gcc_fallthrough ();
     case 3:
     case 4:
     case 5:

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: other archs
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (19 preceding siblings ...)
  2016-07-11 19:59 ` Implement -Wswitch-fallthrough: rs6000 Marek Polacek
@ 2016-07-11 19:59 ` Marek Polacek
  2016-07-11 20:00 ` Implement -Wswitch-fallthrough: testsuite Marek Polacek
                   ` (8 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 19:59 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* config/alpha/alpha.c (alpha_rtx_costs): Likewise.
	(alpha_legitimate_constant_p): Likewise.
	(alpha_emit_setcc): Likewise.
	(alpha_emit_xfloating_libcall): Likewise.
	(alpha_function_value_1): Likewise.
	(alpha_fold_builtin): Likewise.
	* config/alpha/predicates.md: Likewise.
	* config/arc/arc.c (arc_init): Likewise.
	(arc_print_operand): Likewise.
	(arc_rtx_costs): Likewise.
	(arc_legitimate_constant_p): Likewise.
	(arc_get_insn_variants): Likewise.
	(arc_ifcvt): Likewise.
	(arc_expand_atomic_op): Likewise.
	* config/arc/predicates.md: Likewise.
	* config/avr/avr-log.c (avr_log_vadump): Likewise.
	* config/avr/avr.c (ashrqi3_out): Likewise.
	(ashrhi3_out): Likewise.
	(avr_out_ashrpsi3): Likewise.
	(ashrsi3_out): Likewise.
	(avr_out_lshrpsi3): Likewise.
	(avr_rtx_costs_1): Likewise.
	* config/bfin/bfin.c (print_operand): Likewise.
	(bfin_rtx_costs): Likewise.
	* config/c6x/c6x.c (c6x_expand_compare): Likewise.
	(c6x_mem_operand): Likewise.
	(c6x_legitimate_address_p_1): Likewise.
	(count_unit_reqs): Likewise.
	(c6x_registers_update): Likewise.
	* config/c6x/c6x.h: Likewise.
	* config/c6x/predicates.md: Likewise.
	* config/cr16/cr16.c (cr16_address_cost): Likewise.
	(cr16_print_operand_address): Likewise.
	* config/cris/cris.c (cris_print_operand): Likewise.
	(cris_rtx_costs): Likewise.
	* config/epiphany/epiphany.c (epiphany_rtx_costs): Likewise.
	(epiphany_address_cost): Likewise.
	(epiphany_print_operand): Likewise.
	(epiphany_mode_needed): Likewise.
	(epiphany_mode_entry_exit): Likewise.
	(epiphany_insert_mode_switch_use): Likewise.
	* config/fr30/fr30.c (fr30_print_operand): Likewise.
	* config/frv/frv.c (frv_print_operand): Likewise.
	(frv_legitimate_address_p_1): Likewise.
	(frv_emit_movsi): Likewise.
	(frv_rtx_costs): Likewise.
	* config/h8300/h8300.c (h8300_print_operand): Likewise.
	(get_shift_alg): Likewise.
	(output_a_shift): Likewise.
	(compute_a_shift_length): Likewise.
	(compute_a_shift_cc): Likewise.
	* config/ia64/ia64.c (ia64_expand_vecint_compare): Likewise.
	(ia64_expand_atomic_op): Likewise.
	(ia64_print_operand): Likewise.
	(ia64_rtx_costs): Likewise.
	(group_barrier_needed): Likewise.
	(ia64_expand_vec_perm_const): Likewise.
	* config/ia64/predicates.md: Likewise.
	* config/iq2000/iq2000.c (iq2000_address_cost): Likewise.
	* config/lm32/lm32.c (lm32_rtx_costs): Likewise.
	* config/m32r/m32r.c (m32r_rtx_costs): Likewise.
	(m32r_print_operand): Likewise.
	* config/m68k/m68k.c (m68k_sched_md_init_global): Likewise.
	* config/m68k/m68k.h: Likewise.
	* config/mips/mips.c (mips_symbolic_constant_p): Likewise.
	(mips_symbol_insns_1): Likewise.
	(mips_const_insns): Likewise.
	(mips_set_reg_reg_cost): Likewise.
	(mips_rtx_costs): Likewise.
	(mips_output_order_conditional_branch): Likewise.
	(mips_expand_vec_perm_const): Likewise.
	* config/mmix/predicates.md: Likewise.
	* config/mn10300/mn10300.c (mn10300_print_operand): Likewise.
	(mn10300_rtx_costs): Likewise.
	(extract_bundle): Likewise.
	* config/mn10300/mn10300.md: Likewise.
	* config/msp430/msp430.c (msp430_initial_elimination_offset): Likewise.
	(msp430_print_operand): Likewise.
	* config/nds32/nds32-cost.c: Likewise.
	* config/nios2/nios2.c (nios2_legitimate_address_p): Likewise.
	(nios2_print_operand): Likewise.
	* config/pa/pa.c (hppa_rtx_costs): Likewise.
	* config/pdp11/pdp11.c (pdp11_rtx_costs): Likewise.
	* config/rl78/rl78-real.md: Likewise.
	* config/rl78/rl78.c (characterize_address): Likewise.
	(rl78_initial_elimination_offset): Likewise.
	* config/rx/rx.c (rx_print_operand_address): Likewise.
	(rx_print_operand): Likewise.
	(rx_option_override): Likewise.
	* config/s390/s390.c (s390_select_ccmode): Likewise.
	(s390_expand_atomic): Likewise.
	* config/sh/sh.c (sh_print_operand): Likewise.
	(output_branch): Likewise.
	(sh_rtx_costs): Likewise.
	* config/sh/sh.md: Likewise.
	* config/sparc/sparc.c (sparc_rtx_costs): Likewise.
	(sparc_emit_membar_for_model): Likewise.
	* config/spu/spu.c (classify_immediate): Likewise.
	* config/tilegx/tilegx.c (tilegx_emit_cc_test): Likewise.
	(tilegx_print_operand): Likewise.
	* config/tilepro/tilepro.c (tilepro_emit_cc_test): Likewise.
	(tilepro_print_operand): Likewise.
	* config/v850/v850.c (v850_print_operand): Likewise.
	* config/vax/vax.c (vax_rtx_costs): Likewise.
	* config/visium/visium.c (visium_expand_int_cstore): Likewise.
	(visium_expand_fp_cstore): Likewise.
	* config/xtensa/xtensa.c (xtensa_expand_atomic): Likewise.
	(xtensa_rtx_costs): Likewise.

diff --git gcc/gcc/config/alpha/alpha.c gcc/gcc/config/alpha/alpha.c
index 94fed102..66f8711 100644
--- gcc/gcc/config/alpha/alpha.c
+++ gcc/gcc/config/alpha/alpha.c
@@ -1400,6 +1400,7 @@ alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST_DOUBLE:
     case CONST_WIDE_INT:
@@ -1468,6 +1469,7 @@ alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
 	  return false;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case ASHIFTRT:
     case LSHIFTRT:
@@ -1504,6 +1506,7 @@ alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
 	  return false;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case ABS:
       if (! float_mode_p)
@@ -1512,6 +1515,7 @@ alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
 	  return false;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case FLOAT:
     case UNSIGNED_FLOAT:
@@ -2130,6 +2134,7 @@ alpha_legitimate_constant_p (machine_mode mode, rtx x)
       if (GET_CODE (x) != SYMBOL_REF)
 	return true;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       /* TLS symbols are never valid.  */
@@ -2161,6 +2166,7 @@ alpha_legitimate_constant_p (machine_mode mode, rtx x)
       if (GET_MODE_SIZE (mode) != 8)
 	return false;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST_INT:
       if (TARGET_BUILD_CONSTANTS)
@@ -2658,6 +2664,7 @@ alpha_emit_setcc (rtx operands[], machine_mode cmp_mode)
       if (cmp_mode == DImode && op1 == const0_rtx)
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case ORDERED:
       cmp_code = reverse_condition (code);
@@ -3095,6 +3102,7 @@ alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
 	case VOIDmode:
 	  gcc_assert (CONST_INT_P (operands[i]));
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case DImode:
 	  reg = gen_rtx_REG (DImode, regno);
 	  regno += 1;
@@ -5787,6 +5795,7 @@ alpha_function_value_1 (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
       if (!(TARGET_ABI_OPEN_VMS && valtype && AGGREGATE_TYPE_P (valtype)))
         PROMOTE_MODE (mode, dummy, valtype);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case MODE_COMPLEX_INT:
     case MODE_VECTOR_INT:
@@ -7092,6 +7101,7 @@ alpha_fold_builtin (tree fndecl, int n_args, tree *op,
     case ALPHA_BUILTIN_ZAP:
       opint[1] ^= 0xff;
       /* FALLTHRU */
+      gcc_fallthrough ();
     case ALPHA_BUILTIN_ZAPNOT:
       return alpha_fold_builtin_zapnot (op, opint, op_const);
 
diff --git gcc/gcc/config/alpha/predicates.md gcc/gcc/config/alpha/predicates.md
index 24fa3c2..c902f3e 100644
--- gcc/gcc/config/alpha/predicates.md
+++ gcc/gcc/config/alpha/predicates.md
@@ -182,6 +182,7 @@
       if (register_operand (op, mode))
 	return 1;
       /* ... fall through ...  */
+      gcc_fallthrough ();
     case MEM:
       return ((TARGET_BWX || (mode != HImode && mode != QImode))
 	      && general_operand (op, mode));
diff --git gcc/gcc/config/arc/arc.c gcc/gcc/config/arc/arc.c
index c0aa075..735e861 100644
--- gcc/gcc/config/arc/arc.c
+++ gcc/gcc/config/arc/arc.c
@@ -734,6 +734,7 @@ arc_init (void)
 	    break;
 	  }
 	/* Fall through.  */
+	gcc_fallthrough ();
       default:
 	arc_multcost = COSTS_N_INSNS (30);
 	break;
@@ -3448,6 +3449,7 @@ arc_print_operand (FILE *file, rtx x, int code)
 	  break;
 	}
       /* Fall through.  Let output_addr_const deal with it.  */
+      gcc_fallthrough ();
     default :
       if (flag_pic
 	  || (GET_CODE (x) == CONST
@@ -4460,6 +4462,7 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  }
       }
       /* FALLTHRU */
+      gcc_fallthrough ();
 
       /*  4 byte values can be fetched as immediate constants -
 	  let's give that the cost of an extra insn.  */
@@ -4609,6 +4612,7 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return true;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     /* scc_insn expands into two insns.  */
     case GTU: case GEU: case LEU:
       if (mode == SImode)
@@ -5408,10 +5412,12 @@ arc_legitimate_constant_p (machine_mode mode, rtx x)
       if (SYMBOL_REF_TLS_MODEL (x))
 	return false;
       /* Fall through.  */
+      gcc_fallthrough ();
     case LABEL_REF:
       if (flag_pic)
 	return false;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       break;
@@ -8035,6 +8041,7 @@ arc_get_insn_variants (rtx_insn *insn, int len, bool, bool target_p,
 	  ilv++;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case TYPE_BRCC_NO_DELAY_SLOT:
       /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
 	 (delay slot) scheduling purposes, but they are longer.  */
@@ -8356,6 +8363,7 @@ arc_ifcvt (void)
 	      continue;
 	    }
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case 4: case 5:
 	  if (!NONDEBUG_INSN_P (insn))
 	    break;
@@ -9820,6 +9828,7 @@ arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
 	}
 
       /* FALLTHRU.  */
+      gcc_fallthrough ();
     default:
       x = gen_rtx_fmt_ee (code, mode, before, val);
       emit_insn (gen_rtx_SET (after, x));
diff --git gcc/gcc/config/arc/predicates.md gcc/gcc/config/arc/predicates.md
index f85f931..450b163 100644
--- gcc/gcc/config/arc/predicates.md
+++ gcc/gcc/config/arc/predicates.md
@@ -517,6 +517,7 @@
       if (GET_MODE (op) == CC_ZNmode)
 	return 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case CC_ZNmode: case CC_Cmode:
       return GET_MODE (op) == CCmode;
     default:
diff --git gcc/gcc/config/avr/avr-log.c gcc/gcc/config/avr/avr-log.c
index fe2cae4..3853471 100644
--- gcc/gcc/config/avr/avr-log.c
+++ gcc/gcc/config/avr/avr-log.c
@@ -229,6 +229,7 @@ avr_log_vadump (FILE *file, const char *caller, va_list ap)
               if (!current_pass)
                 return;
               /* FALLTHRU */
+	      gcc_fallthrough ();
 
             case '?':
               avr_vdump (file, caller, "%F[%f:%P]");
diff --git gcc/gcc/config/avr/avr.c gcc/gcc/config/avr/avr.c
index 18ed766..53d726e 100644
--- gcc/gcc/config/avr/avr.c
+++ gcc/gcc/config/avr/avr.c
@@ -6212,6 +6212,7 @@ ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
 	    break;
 
 	  /* fall through */
+	  gcc_fallthrough ();
 
 	case 7:
 	  *len = 2;
@@ -6377,6 +6378,7 @@ ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
 	    break;
 
 	  /* fall through */
+	  gcc_fallthrough ();
 
 	case 15:
 	  return *len = 3, ("lsl %B0"     CR_TAB
@@ -6434,6 +6436,7 @@ avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
             break;
 
           /* fall through */
+	  gcc_fallthrough ();
 
         case 23:
           return avr_asm_len ("lsl %C0"     CR_TAB
@@ -6524,6 +6527,7 @@ ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
 	    break;
 
 	  /* fall through */
+	  gcc_fallthrough ();
 
 	case 31:
 	  if (AVR_HAVE_MOVW)
@@ -6936,6 +6940,7 @@ avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
             break;
 
           /* fall through */
+	  gcc_fallthrough ();
 
         case 23:
           return avr_asm_len ("clr %A0"    CR_TAB
@@ -10040,6 +10045,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
           return true;
         }
       /* FALLTHRU */
+      gcc_fallthrough ();
     case AND:
     case IOR:
       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
diff --git gcc/gcc/config/bfin/bfin.c gcc/gcc/config/bfin/bfin.c
index 75ddcf0..6d7839d 100644
--- gcc/gcc/config/bfin/bfin.c
+++ gcc/gcc/config/bfin/bfin.c
@@ -1569,6 +1569,7 @@ print_operand (FILE *file, rtx x, char code)
 	    x = GEN_INT (-8 - INTVAL (x));
 
 	  /* fall through */
+	  gcc_fallthrough ();
 
 	case SYMBOL_REF:
 	  output_addr_const (file, x);
@@ -2936,6 +2937,7 @@ bfin_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
 	  return true;
 	}
       /* fall through */
+      gcc_fallthrough ();
 
     case SIGN_EXTEND:
     case ZERO_EXTEND:
diff --git gcc/gcc/config/c6x/c6x.c gcc/gcc/config/c6x/c6x.c
index 4cbe63c..778f76e 100644
--- gcc/gcc/config/c6x/c6x.c
+++ gcc/gcc/config/c6x/c6x.c
@@ -1499,6 +1499,7 @@ c6x_expand_compare (rtx comparison, machine_mode mode)
 	case UNGT:
 	  jump_code = EQ;
 	  /* fall through */
+	  gcc_fallthrough ();
 	case LE:
 	case GE:
 	  code1 = code == LE || code == UNGT ? LT : GT;
@@ -1508,9 +1509,11 @@ c6x_expand_compare (rtx comparison, machine_mode mode)
 	case UNORDERED:
 	  jump_code = EQ;
 	  /* fall through */
+	  gcc_fallthrough ();
 	case ORDERED:
 	  code3 = EQ;
 	  /* fall through */
+	  gcc_fallthrough ();
 	case LTGT:
 	  code1 = LT;
 	  code2 = GT;
@@ -2322,6 +2325,7 @@ c6x_mem_operand (rtx op, enum reg_class c, bool small_offset)
 	}
 
       /* fall through */
+      gcc_fallthrough ();
     case PRE_INC:
     case PRE_DEC:
     case PRE_MODIFY:
@@ -2372,6 +2376,7 @@ c6x_legitimate_address_p_1 (machine_mode mode, rtx x, bool strict,
 	return false;
 
       /* fall through */
+      gcc_fallthrough ();
     case PRE_INC:
     case PRE_DEC:
     case POST_INC:
@@ -2384,6 +2389,7 @@ c6x_legitimate_address_p_1 (machine_mode mode, rtx x, bool strict,
 	return false;
 
       /* fall through */
+      gcc_fallthrough ();
     case REG:
       if (strict)
 	return REGNO_OK_FOR_BASE_STRICT_P (REGNO (x));
@@ -3284,6 +3290,7 @@ count_unit_reqs (unit_req_table reqs, rtx_insn *head, rtx_insn *tail)
 	case 2:
 	  reqs[side2][req2]++;
 	  /* fall through */
+	  gcc_fallthrough ();
 	case 1:
 	  reqs[side1][req1]++;
 	  break;
@@ -4104,6 +4111,7 @@ c6x_registers_update (rtx_insn *insn)
 	    case PRE_DEC:
 	      op = XEXP (op, 0);
 	      /* fall through */
+	      gcc_fallthrough ();
 	    case REG:
 	      c6x_mark_reg_read (op, false);
 	      break;
@@ -4112,6 +4120,7 @@ c6x_registers_update (rtx_insn *insn)
 	      op = XEXP (op, 1);
 	      gcc_assert (GET_CODE (op) == PLUS);
 	      /* fall through */
+	      gcc_fallthrough ();
 	    case PLUS:
 	      c6x_mark_reg_read (XEXP (op, 0), false);
 	      if (REG_P (XEXP (op, 1)))
diff --git gcc/gcc/config/c6x/c6x.h gcc/gcc/config/c6x/c6x.h
index 3209bf6..4e4b41c 100644
--- gcc/gcc/config/c6x/c6x.h
+++ gcc/gcc/config/c6x/c6x.h
@@ -93,6 +93,7 @@ extern c6x_cpu_t c6x_arch;
 	case C6X_CPU_C64XP:			\
 	  builtin_define ("_TMS320C6400_PLUS");	\
 	  /* ... fall through ... */		\
+	  gcc_fallthrough ();			\
 	case C6X_CPU_C64X:			\
 	  builtin_define ("_TMS320C6400");	\
 	  break;				\
@@ -100,6 +101,7 @@ extern c6x_cpu_t c6x_arch;
 	case C6X_CPU_C67XP:			\
 	  builtin_define ("_TMS320C6700_PLUS");	\
 	  /* ... fall through ... */		\
+	  gcc_fallthrough ();			\
 	case C6X_CPU_C67X:			\
 	  builtin_define ("_TMS320C6700");	\
 	  break;				\
diff --git gcc/gcc/config/c6x/predicates.md gcc/gcc/config/c6x/predicates.md
index 9db6002..3f6e968 100644
--- gcc/gcc/config/c6x/predicates.md
+++ gcc/gcc/config/c6x/predicates.md
@@ -193,6 +193,7 @@
       offset = INTVAL (XEXP (op, 1));
       op = XEXP (op, 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       /* For shared libraries, only allow symbols we know are local.
diff --git gcc/gcc/config/cr16/cr16.c gcc/gcc/config/cr16/cr16.c
index 141b8bc..b7a95c0 100644
--- gcc/gcc/config/cr16/cr16.c
+++ gcc/gcc/config/cr16/cr16.c
@@ -1309,6 +1309,7 @@ cr16_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
     case CR16_REGP_REL:
       cost += 2;
       /* Fall through.  */
+      gcc_fallthrough ();
     case CR16_REG_REL:
       cost += 3;
       if (address.disp)
@@ -1575,6 +1576,7 @@ cr16_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
     case CR16_INDEX_REGP_REL:
       fprintf (file, "[%s]", reg_names[REGNO (address.index)]);
       /* Fall through.  */
+      gcc_fallthrough ();
     case CR16_REGP_REL:
       if (address.disp)
 	{
diff --git gcc/gcc/config/cris/cris.c gcc/gcc/config/cris/cris.c
index 971d07f..447cfc9 100644
--- gcc/gcc/config/cris/cris.c
+++ gcc/gcc/config/cris/cris.c
@@ -961,6 +961,7 @@ cris_print_operand (FILE *file, rtx x, int code)
 	 and %E (and %e) and state passed between those modifiers.  */
       cris_output_insn_is_bound = 0;
       /* FALL THROUGH.  */
+      gcc_fallthrough ();
     case 'E':
       /* Print 's' if operand is SIGN_EXTEND or 'u' if ZERO_EXTEND unless
 	 cris_output_insn_is_bound is nonzero.  */
@@ -2187,6 +2188,7 @@ cris_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
       if (outer_code != COMPARE)
         return false;
       /* fall through */
+      gcc_fallthrough ();
 
     case ZERO_EXTEND: case SIGN_EXTEND:
       *total = rtx_cost (XEXP (x, 0), VOIDmode, (enum rtx_code) outer_code,
diff --git gcc/gcc/config/epiphany/epiphany.c gcc/gcc/config/epiphany/epiphany.c
index f09a657..7f4a2ea 100644
--- gcc/gcc/config/epiphany/epiphany.c
+++ gcc/gcc/config/epiphany/epiphany.c
@@ -771,6 +771,7 @@ epiphany_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST:
     case LABEL_REF:
@@ -872,11 +873,13 @@ epiphany_address_cost (rtx addr, machine_mode mode,
 	  return 1;
 	i >>= 1;
 	/* Fall through.  */
+	gcc_fallthrough ();
       case 2:
 	if (i & 1)
 	  return 1;
 	i >>= 1;
 	/* Fall through.  */
+	gcc_fallthrough ();
       case 1:
 	return i < -7 || i > 7;
     }
@@ -1352,6 +1355,7 @@ epiphany_print_operand (FILE *file, rtx x, int code)
 	  break;
 	}
       /* Fall through.  Let output_addr_const deal with it.  */
+      gcc_fallthrough ();
     case CONST_INT:
       fprintf(file,"%s",IMMEDIATE_PREFIX);
       if (code == 'C' || code == 'X')
@@ -1361,6 +1365,7 @@ epiphany_print_operand (FILE *file, rtx x, int code)
 	  break;
 	}
       /* Fall through */
+      gcc_fallthrough ();
     default :
       output_addr_const (file, x);
       break;
@@ -2421,6 +2426,7 @@ epiphany_mode_needed (int entity, rtx_insn *insn)
     if (recog_memoized (insn) == CODE_FOR_set_fp_mode)
       mode = (enum attr_fp_mode) epiphany_mode_after (entity, mode, insn);
     /* Fall through.  */
+    gcc_fallthrough ();
   case EPIPHANY_MSW_ENTITY_NEAREST:
   case EPIPHANY_MSW_ENTITY_TRUNC:
     if (mode == FP_MODE_ROUND_UNKNOWN)
@@ -2469,6 +2475,7 @@ epiphany_mode_entry_exit (int entity, bool exit)
 	  || normal_mode == FP_MODE_ROUND_TRUNC)
       return FP_MODE_ROUND_UNKNOWN;
       /* Fall through.  */
+      gcc_fallthrough ();
     case EPIPHANY_MSW_ENTITY_NEAREST:
     case EPIPHANY_MSW_ENTITY_TRUNC:
     case EPIPHANY_MSW_ENTITY_ROUND_KNOWN:
@@ -2715,6 +2722,7 @@ epiphany_insert_mode_switch_use (rtx_insn *insn,
 	near = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, FP_ANYFP_REGNUM));
 	trunc = copy_rtx (near);
 	/* Fall through.  */
+	gcc_fallthrough ();
       case FP_MODE_INT:
       case FP_MODE_CALLER:
 	near = gen_rtx_USE (VOIDmode, near);
diff --git gcc/gcc/config/fr30/fr30.c gcc/gcc/config/fr30/fr30.c
index f4fef2b..044a337 100644
--- gcc/gcc/config/fr30/fr30.c
+++ gcc/gcc/config/fr30/fr30.c
@@ -685,6 +685,7 @@ fr30_print_operand (FILE *file, rtx x, int code)
 	}
 
       /* Fall through.  Let output_addr_const deal with it.  */
+      gcc_fallthrough ();
     default:
       output_addr_const (file, x);
       break;
diff --git gcc/gcc/config/frv/frv.c gcc/gcc/config/frv/frv.c
index 957ff03..e3ce9bc 100644
--- gcc/gcc/config/frv/frv.c
+++ gcc/gcc/config/frv/frv.c
@@ -2990,6 +2990,7 @@ frv_print_operand (FILE * file, rtx x, int code)
 	}
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case '\0':
       if (GET_CODE (x) == REG)
@@ -3336,6 +3337,7 @@ frv_legitimate_address_p_1 (machine_mode mode,
         break;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case REG:
       ret = frv_regno_ok_for_base_p (REGNO (x), strict_p);
@@ -3396,6 +3398,7 @@ frv_legitimate_address_p_1 (machine_mode mode,
 	    break;
 
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case REG:
 	  /* Do not allow reg+reg addressing for modes > 1 word if we
@@ -4094,6 +4097,7 @@ frv_emit_movsi (rtx dest, rtx src)
 			break;
 		      }
 		    /* Fall through.  */
+		    gcc_fallthrough ();
 		  default:
 		    if (TARGET_GPREL_RO)
 		      unspec = R_FRV_GPREL12;
@@ -9455,6 +9459,7 @@ frv_rtx_costs (rtx x,
 	  return true;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case CONST:
     case LABEL_REF:
diff --git gcc/gcc/config/h8300/h8300.c gcc/gcc/config/h8300/h8300.c
index 1818684..0d83310 100644
--- gcc/gcc/config/h8300/h8300.c
+++ gcc/gcc/config/h8300/h8300.c
@@ -1744,6 +1744,7 @@ h8300_print_operand (FILE *file, rtx x, int code)
 		     processing bit operations on H8/300 or H8/300H
 		     because 'U' constraint does not allow bit
 		     operations on the tiny area on these machines.  */
+		  gcc_fallthrough ();
 
 		case 'X':
 		case 'T':
@@ -4109,6 +4110,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
     case SHIFT_INLINE:
       info->remainder = count;
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case SHIFT_LOOP:
       /* It is up to the caller to know that looping clobbers cc.  */
@@ -4624,6 +4626,7 @@ output_a_shift (rtx *operands)
     case SHIFT_SPECIAL:
       output_asm_insn (info.special, operands);
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case SHIFT_INLINE:
       n = info.remainder;
@@ -4805,6 +4808,7 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
 	    wlength++;
 
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	case SHIFT_INLINE:
 	  n = info.remainder;
@@ -4942,6 +4946,7 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
 	return info.cc_special;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case SHIFT_INLINE:
       return info.cc_inline;
diff --git gcc/gcc/config/ia64/ia64.c gcc/gcc/config/ia64/ia64.c
index 6ab3400..e0f8be7 100644
--- gcc/gcc/config/ia64/ia64.c
+++ gcc/gcc/config/ia64/ia64.c
@@ -1889,6 +1889,7 @@ ia64_expand_vecint_compare (enum rtx_code code, machine_mode mode,
       code = reverse_condition (code);
       negate = true;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case LT:
     case LTU:
@@ -2359,6 +2360,7 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
 	case MEMMODEL_SYNC_SEQ_CST:
 	  emit_insn (gen_memory_barrier ());
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 	case MEMMODEL_RELAXED:
 	case MEMMODEL_ACQUIRE:
 	case MEMMODEL_SYNC_ACQUIRE:
@@ -5547,6 +5549,7 @@ ia64_print_operand (FILE * file, rtx x, int code)
     case POST_MODIFY:
       x = XEXP (x, 0);
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case REG:
       fputs (reg_names [REGNO (x)], file);
@@ -5648,6 +5651,7 @@ ia64_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case ASHIFT:
     case ASHIFTRT:
@@ -6879,6 +6883,7 @@ group_barrier_needed (rtx_insn *insn)
 	  break;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case INSN:
       if (GET_CODE (PATTERN (insn)) == USE
@@ -11723,6 +11728,7 @@ ia64_expand_vec_perm_const (rtx operands[4])
 	if (d.perm[i] >= nelt)
 	  d.perm[i] -= nelt;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 1:
       d.op1 = d.op0;
diff --git gcc/gcc/config/ia64/predicates.md gcc/gcc/config/ia64/predicates.md
index 02347f7..d2cb450 100644
--- gcc/gcc/config/ia64/predicates.md
+++ gcc/gcc/config/ia64/predicates.md
@@ -50,6 +50,7 @@
       offset = INTVAL (XEXP (op, 1));
       op = XEXP (op, 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       if (CONSTANT_POOL_ADDRESS_P (op))
@@ -114,6 +115,7 @@
 	return false;
       op = XEXP (op, 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
 	return SYMBOL_REF_LOCAL_P (op);
@@ -137,6 +139,7 @@
 	return false;
       op = XEXP (op, 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       return SYMBOL_REF_SMALL_ADDR_P (op);
@@ -190,6 +193,7 @@
       addend = INTVAL (XEXP (op, 1));
       op = XEXP (op, 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       /* These symbols shouldn't be used with got loads.  */
@@ -272,6 +276,7 @@
 	return false;
       op = XEXP (op, 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
@@ -295,6 +300,7 @@
         return false;
       op = XEXP (op, 0);
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
diff --git gcc/gcc/config/iq2000/iq2000.c gcc/gcc/config/iq2000/iq2000.c
index 73b9cdb..9670103 100644
--- gcc/gcc/config/iq2000/iq2000.c
+++ gcc/gcc/config/iq2000/iq2000.c
@@ -804,6 +804,7 @@ iq2000_address_cost (rtx addr, machine_mode mode, addr_space_t as,
       }
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case SYMBOL_REF:
       return SYMBOL_REF_FLAG (addr) ? 1 : 2;
diff --git gcc/gcc/config/lm32/lm32.c gcc/gcc/config/lm32/lm32.c
index 4a8079f..379b465 100644
--- gcc/gcc/config/lm32/lm32.c
+++ gcc/gcc/config/lm32/lm32.c
@@ -1122,6 +1122,7 @@ lm32_rtx_costs (rtx x, machine_mode mode, int outer_code,
 		return true;
 	      }
 	    /* Fall through.  */ 
+	    gcc_fallthrough ();
 
 	  default:
             if (satisfies_constraint_K (x))
@@ -1151,6 +1152,7 @@ lm32_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case LABEL_REF:
     case CONST_DOUBLE:
diff --git gcc/gcc/config/m32r/m32r.c gcc/gcc/config/m32r/m32r.c
index b40c53c..487a6b5 100644
--- gcc/gcc/config/m32r/m32r.c
+++ gcc/gcc/config/m32r/m32r.c
@@ -1375,6 +1375,7 @@ m32r_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST:
     case LABEL_REF:
@@ -2175,6 +2176,7 @@ m32r_print_operand (FILE * file, rtx x, int code)
 	      return;
 	    }
 	  /* fall through */
+	  gcc_fallthrough ();
 	case LABEL_REF :
 	  fputs (code == 'T' ? "shigh(" : "low(", file);
 	  output_addr_const (file, x);
@@ -2275,6 +2277,7 @@ m32r_print_operand (FILE * file, rtx x, int code)
 	}
 
       /* Fall through.  Let output_addr_const deal with it.  */
+      gcc_fallthrough ();
 
     default :
       output_addr_const (file, x);
diff --git gcc/gcc/config/m68k/m68k.c gcc/gcc/config/m68k/m68k.c
index 03f474e..1896290 100644
--- gcc/gcc/config/m68k/m68k.c
+++ gcc/gcc/config/m68k/m68k.c
@@ -6153,6 +6153,7 @@ m68k_sched_md_init_global (FILE *sched_dump ATTRIBUTE_UNUSED,
       sched_ib.filled = 0;
 
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CPU_CFV1:
     case CPU_CFV2:
diff --git gcc/gcc/config/m68k/m68k.h gcc/gcc/config/m68k/m68k.h
index 2aa858f..554bb2d 100644
--- gcc/gcc/config/m68k/m68k.h
+++ gcc/gcc/config/m68k/m68k.h
@@ -90,6 +90,7 @@ along with GCC; see the file COPYING3.  If not see
 	case u68020_60:							\
 	  builtin_define_std ("mc68060");				\
 	  /* Fall through.  */						\
+	  gcc_fallthrough ();						\
 	case u68020_40:							\
 	  builtin_define_std ("mc68040");				\
 	  builtin_define_std ("mc68030");				\
diff --git gcc/gcc/config/mips/mips.c gcc/gcc/config/mips/mips.c
index df7b1da..2086d2a 100644
--- gcc/gcc/config/mips/mips.c
+++ gcc/gcc/config/mips/mips.c
@@ -2189,6 +2189,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_context context,
 	return true;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case SYMBOL_GP_RELATIVE:
       /* Make sure that the offset refers to something within the
@@ -2284,6 +2285,7 @@ mips_symbol_insns_1 (enum mips_symbol_type type, machine_mode mode)
 	return 0;
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case SYMBOL_GOT_PAGE_OFST:
       /* Unless -funit-at-a-time is in effect, we can't be sure whether the
@@ -2847,6 +2849,7 @@ mips_const_insns (rtx x)
 	  && mips_const_vector_same_int_p (x, GET_MODE (x), -512, 511))
 	return 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     case CONST_DOUBLE:
       /* Allow zeros for normal mode, where we can use $0.  */
       return !TARGET_MIPS16 && x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
@@ -4023,6 +4026,7 @@ mips_set_reg_reg_cost (machine_mode mode)
       if (TARGET_HARD_FLOAT)
 	return mips_set_reg_reg_piece_cost (mode, UNITS_PER_HWFPVALUE);
       /* Fall through */
+      gcc_fallthrough ();
 
     default:
       return mips_set_reg_reg_piece_cost (mode, UNITS_PER_WORD);
@@ -4096,6 +4100,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	    }
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case CONST:
     case SYMBOL_REF:
@@ -4209,6 +4214,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	}
 	    
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case IOR:
     case XOR:
@@ -4297,6 +4303,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	    }
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case PLUS:
       if (float_mode_p)
@@ -4395,6 +4402,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return true;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case SQRT:
     case MOD:
@@ -4404,6 +4412,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return false;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case UDIV:
     case UMOD:
@@ -13778,6 +13787,7 @@ mips_output_order_conditional_branch (rtx_insn *insn, rtx *operands,
 	    case LTU:
 	      inverted_p = !inverted_p;
 	      /* Fall through.  */
+	      gcc_fallthrough ();
 	    case GE:
 	    case GEU:
 	      branch[!inverted_p] = MIPS_BRANCH_C ("b", "%0");
@@ -13801,6 +13811,7 @@ mips_output_order_conditional_branch (rtx_insn *insn, rtx *operands,
 	case LEU:
 	  inverted_p = !inverted_p;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case GTU:
 	  if (TARGET_CB_MAYBE)
 	    {
@@ -13818,6 +13829,7 @@ mips_output_order_conditional_branch (rtx_insn *insn, rtx *operands,
 	case LTU:
 	  inverted_p = !inverted_p;
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 	case GEU:
 	  if (TARGET_CB_MAYBE)
 	    {
@@ -21196,6 +21208,7 @@ mips_expand_vec_perm_const (rtx operands[4])
       if (!rtx_equal_p (d.op0, d.op1))
 	break;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 2:
       for (i = 0; i < nelt; ++i)
diff --git gcc/gcc/config/mmix/predicates.md gcc/gcc/config/mmix/predicates.md
index 8e920c2..c856c46 100644
--- gcc/gcc/config/mmix/predicates.md
+++ gcc/gcc/config/mmix/predicates.md
@@ -117,6 +117,7 @@
 		  && GET_MODE (XEXP (op, 1)) == VOIDmode)))
 	return 1;
       /* Fall through.  */
+      gcc_fallthrough ();
     default:
       return mmix_address_operand (op, mode);
     }
diff --git gcc/gcc/config/mn10300/mn10300.c gcc/gcc/config/mn10300/mn10300.c
index 71815d6..befd623 100644
--- gcc/gcc/config/mn10300/mn10300.c
+++ gcc/gcc/config/mn10300/mn10300.c
@@ -397,6 +397,7 @@ mn10300_print_operand (FILE *file, rtx x, int code)
 	  break;
 	}
       /* FALL THROUGH */
+      gcc_fallthrough ();
 
     default:
       switch (GET_CODE (x))
@@ -2455,6 +2456,7 @@ mn10300_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	    goto alldone;
 	  }
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case ASHIFTRT:
     case LSHIFTRT:
@@ -3011,6 +3013,7 @@ extract_bundle (rtx_insn *insn, struct liw_data * pdata)
       /* The AND, OR and XOR long instruction words only accept register arguments.  */
       allow_consts = false;
       /* Fall through.  */
+      gcc_fallthrough ();
     default:
       pdata->dest = SET_DEST (p);
       pdata->src = XEXP (SET_SRC (p), 1);
diff --git gcc/gcc/config/mn10300/mn10300.md gcc/gcc/config/mn10300/mn10300.md
index decda0e..e9f137c 100644
--- gcc/gcc/config/mn10300/mn10300.md
+++ gcc/gcc/config/mn10300/mn10300.md
@@ -306,6 +306,7 @@
 	  && REGNO_EXTENDED_P (REGNO (operands[0]), 1))
 	return "movu %1,%0";
       /* FALLTHRU */
+      gcc_fallthrough ();
     case 5:
     case 6:
     case 2:
@@ -454,6 +455,7 @@
 	    return "movu %1,%0";
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
     case 3:  /* reg-reg */
     case 4:  /* reg-mem */
     case 5:  /* mem-reg */
diff --git gcc/gcc/config/msp430/msp430.c gcc/gcc/config/msp430/msp430.c
index dba4d19..d260eb2 100644
--- gcc/gcc/config/msp430/msp430.c
+++ gcc/gcc/config/msp430/msp430.c
@@ -979,6 +979,7 @@ msp430_initial_elimination_offset (int from, int to)
       rv += cfun->machine->framesize_outgoing;
       rv += cfun->machine->framesize_locals;
       /* Fall through.  */
+      gcc_fallthrough ();
     case FRAME_POINTER_REGNUM:
       rv += cfun->machine->framesize_regs;
       /* Allow for the saved return address.  */
@@ -996,6 +997,7 @@ msp430_initial_elimination_offset (int from, int to)
       /* Allow for the fall through above.  */
       rv -= (TARGET_LARGE ? 4 : 2);
       rv -= cfun->machine->framesize_regs;
+      gcc_fallthrough ();
     case ARG_POINTER_REGNUM:
       break;
     default:
@@ -3651,6 +3653,7 @@ msp430_print_operand (FILE * file, rtx op, int letter)
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
     case CONST_INT:
     case SYMBOL_REF:
     case LABEL_REF:
diff --git gcc/gcc/config/nds32/nds32-cost.c gcc/gcc/config/nds32/nds32-cost.c
index e6a29fc..9d7a1d0 100644
--- gcc/gcc/config/nds32/nds32-cost.c
+++ gcc/gcc/config/nds32/nds32-cost.c
@@ -191,6 +191,7 @@ performance_cost:
   /* This is section for performance cost model.  */
 
   /* FALLTHRU, currently we use same cost model as size_cost.  */
+  gcc_fallthrough ();
 
 size_cost:
   /* This is section for size cost model.  */
diff --git gcc/gcc/config/nios2/nios2.c gcc/gcc/config/nios2/nios2.c
index 18fcbb3..3e5aed8 100644
--- gcc/gcc/config/nios2/nios2.c
+++ gcc/gcc/config/nios2/nios2.c
@@ -1975,11 +1975,13 @@ nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
 	return false;
 
       /* Else, fall through.  */
+      gcc_fallthrough ();
     case CONST:
       if (gprel_constant_p (operand))
 	return true;
 
       /* Else, fall through.  */
+      gcc_fallthrough ();
     case LABEL_REF:
     case CONST_INT:
     case CONST_DOUBLE:
@@ -2583,6 +2585,7 @@ nios2_print_operand (FILE *file, rtx op, int letter)
       }
 
       /* Else, fall through.  */
+      gcc_fallthrough ();
 
     case CONST:
     case LABEL_REF:
diff --git gcc/gcc/config/pa/pa.c gcc/gcc/config/pa/pa.c
index 1047f3d..a0e95bc 100644
--- gcc/gcc/config/pa/pa.c
+++ gcc/gcc/config/pa/pa.c
@@ -1530,6 +1530,7 @@ hppa_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case UDIV:
     case MOD:
diff --git gcc/gcc/config/pdp11/pdp11.c gcc/gcc/config/pdp11/pdp11.c
index ec3d61a..00e2e3a 100644
--- gcc/gcc/config/pdp11/pdp11.c
+++ gcc/gcc/config/pdp11/pdp11.c
@@ -905,6 +905,7 @@ pdp11_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST:
     case LABEL_REF:
diff --git gcc/gcc/config/rl78/rl78-real.md gcc/gcc/config/rl78/rl78-real.md
index 530b2fe..400431c 100644
--- gcc/gcc/config/rl78/rl78-real.md
+++ gcc/gcc/config/rl78/rl78-real.md
@@ -467,6 +467,7 @@
         if (rl78_flags_already_set (operands[0], operands[1]))
 	  return "sk%C0\; br\t!!%3\; # cmpw eliminated";
 	/* else fall through.  */
+	gcc_fallthrough ();
       case 1:
 	return "cmpw\t%1, %2\; sk%C0\; br\t!!%3";
       case 2:
diff --git gcc/gcc/config/rl78/rl78.c gcc/gcc/config/rl78/rl78.c
index 3ddb198..936c6d8 100644
--- gcc/gcc/config/rl78/rl78.c
+++ gcc/gcc/config/rl78/rl78.c
@@ -928,6 +928,7 @@ characterize_address (rtx x, rtx *base, rtx *index, rtx *addend)
 	  return true;
 	}
       /* fall through */
+      gcc_fallthrough ();
     case MEM:
     case REG:
       return false;
@@ -1259,6 +1260,7 @@ rl78_initial_elimination_offset (int from, int to)
       rv += cfun->machine->framesize_outgoing;
       rv += cfun->machine->framesize_locals;
       /* Fall through.  */
+      gcc_fallthrough ();
     case FRAME_POINTER_REGNUM:
       rv += cfun->machine->framesize_regs;
       rv += 4;
diff --git gcc/gcc/config/rx/rx.c gcc/gcc/config/rx/rx.c
index 8dfc885..b829f52 100644
--- gcc/gcc/config/rx/rx.c
+++ gcc/gcc/config/rx/rx.c
@@ -454,10 +454,12 @@ rx_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
     case UNSPEC:
       addr = XVECEXP (addr, 0, 0);
       /* Fall through.  */
+      gcc_fallthrough ();
     case LABEL_REF:
     case SYMBOL_REF:
       fprintf (file, "#");
       /* Fall through.  */
+      gcc_fallthrough ();
     default:
       output_addr_const (file, addr);
       break;
@@ -735,6 +737,7 @@ rx_print_operand (FILE * file, rtx op, int letter)
       gcc_assert (GET_MODE_SIZE (GET_MODE (op)) <= 4);
       unsigned_load = true;
       /* Fall through.  */
+      gcc_fallthrough ();
     case 'Q':
       if (MEM_P (op))
 	{
@@ -797,6 +800,7 @@ rx_print_operand (FILE * file, rtx op, int letter)
 	}
 
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default:
       if (GET_CODE (op) == CONST
@@ -910,6 +914,7 @@ rx_print_operand (FILE * file, rtx op, int letter)
 	      }
 	    }
 	  /* Fall through */
+	  gcc_fallthrough ();
 
 	case CONST:
 	case SYMBOL_REF:
@@ -2787,15 +2792,19 @@ rx_option_override (void)
 	      case 4:
 		fixed_regs[10] = call_used_regs [10] = 1;
 		/* Fall through.  */
+		gcc_fallthrough ();
 	      case 3:
 		fixed_regs[11] = call_used_regs [11] = 1;
 		/* Fall through.  */
+		gcc_fallthrough ();
 	      case 2:
 		fixed_regs[12] = call_used_regs [12] = 1;
 		/* Fall through.  */
+		gcc_fallthrough ();
 	      case 1:
 		fixed_regs[13] = call_used_regs [13] = 1;
 		/* Fall through.  */
+		gcc_fallthrough ();
 	      case 0:
 		rx_num_interrupt_regs = opt->value;
 		break;
diff --git gcc/gcc/config/s390/s390.c gcc/gcc/config/s390/s390.c
index ee0187c..a99c7d4 100644
--- gcc/gcc/config/s390/s390.c
+++ gcc/gcc/config/s390/s390.c
@@ -1472,6 +1472,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
 	      return CCAPmode;
 	  }
 	/* Fall through.  */
+	gcc_fallthrough ();
       case UNORDERED:
       case ORDERED:
       case UNEQ:
@@ -6684,6 +6685,7 @@ s390_expand_atomic (machine_mode mode, enum rtx_code code,
       val = expand_simple_binop (SImode, AND, val, ac.modemask,
 				 NULL_RTX, 1, OPTAB_DIRECT);
       /* FALLTHRU */
+      gcc_fallthrough ();
     case SET:
       if (ac.aligned && MEM_P (val))
 	store_bit_field (new_rtx, GET_MODE_BITSIZE (mode), 0,
diff --git gcc/gcc/config/sh/sh.c gcc/gcc/config/sh/sh.c
index 0960a99..d10f469 100644
--- gcc/gcc/config/sh/sh.c
+++ gcc/gcc/config/sh/sh.c
@@ -1282,6 +1282,7 @@ sh_print_operand (FILE *stream, rtx x, int code)
       gcc_assert (MEM_P (x));
       x = XEXP (x, 0);
       /* Fall through.  */
+      gcc_fallthrough ();
     case 'U':
       switch (GET_CODE (x))
 	{
@@ -1338,6 +1339,7 @@ sh_print_operand (FILE *stream, rtx x, int code)
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     default_output:
     default:
@@ -1395,6 +1397,7 @@ sh_print_operand (FILE *stream, rtx x, int code)
 
 	  x = SUBREG_REG (x);
 	  /* Fall through.  */
+	  gcc_fallthrough ();
 
 	reg:
 	case REG:
@@ -2690,6 +2693,7 @@ output_branch (int logic, rtx_insn *insn, rtx *operands)
 	  return "";
 	}
       /* When relaxing, fall through.  */
+      gcc_fallthrough ();
     case 4:
       {
 	char buffer[10];
@@ -3420,6 +3424,7 @@ sh_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
 	  return true;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case XOR:
     case IOR:
@@ -3455,6 +3460,7 @@ sh_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
 	  return true;
 	}
       /* Fall through to shiftcosts.  */
+      gcc_fallthrough ();
     case ASHIFT:
     case ASHIFTRT:
       {
diff --git gcc/gcc/config/sh/sh.md gcc/gcc/config/sh/sh.md
index edc4d15..8c58669 100644
--- gcc/gcc/config/sh/sh.md
+++ gcc/gcc/config/sh/sh.md
@@ -5845,6 +5845,7 @@
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case PLUS:
       emit_insn (gen_movsf_ie (reg0, operands[1]));
@@ -5906,6 +5907,7 @@
 	  break;
 	}
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case PLUS:
       /* Since REG+DISP addressing has already been decided upon by gcc
diff --git gcc/gcc/config/sparc/sparc.c gcc/gcc/config/sparc/sparc.c
index 1d2ecaa..66af776 100644
--- gcc/gcc/config/sparc/sparc.c
+++ gcc/gcc/config/sparc/sparc.c
@@ -11160,6 +11160,7 @@ sparc_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return false;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case ABS:
     case FLOAT:
@@ -11656,6 +11657,7 @@ sparc_emit_membar_for_model (enum memmodel model,
       if (load_store == 3 && before_after == 1)
 	implied |= StoreLoad;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SMM_PSO:
       /* Partial Store Ordering: all memory transactions with load semantics
@@ -11667,6 +11669,7 @@ sparc_emit_membar_for_model (enum memmodel model,
       if (load_store == 3 && before_after == 2)
 	implied |= StoreLoad | StoreStore;
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case SMM_RMO:
       /* Relaxed Memory Ordering: no implicit bits.  */
diff --git gcc/gcc/config/spu/spu.c gcc/gcc/config/spu/spu.c
index c3757eb..297be7e 100644
--- gcc/gcc/config/spu/spu.c
+++ gcc/gcc/config/spu/spu.c
@@ -3200,6 +3200,7 @@ classify_immediate (rtx op, machine_mode mode)
 	    && GET_CODE (CONST_VECTOR_ELT (op, i)) != CONST_DOUBLE)
 	  return IC_POOL;
       /* Fall through. */
+      gcc_fallthrough ();
 
     case CONST_INT:
     case CONST_DOUBLE:
diff --git gcc/gcc/config/tilegx/tilegx.c gcc/gcc/config/tilegx/tilegx.c
index 06c832c..953ced6 100644
--- gcc/gcc/config/tilegx/tilegx.c
+++ gcc/gcc/config/tilegx/tilegx.c
@@ -2547,6 +2547,7 @@ tilegx_emit_cc_test (enum rtx_code code, rtx op0, rtx op1,
 	  if (n == -1)
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case LTU:
 	  /* Change ((unsigned)x < 0x1000) into !((int)x >> 12), etc.
@@ -5236,6 +5237,7 @@ tilegx_print_operand (FILE *file, rtx x, int code)
 	}
       }
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 'h':
       {
@@ -5386,6 +5388,7 @@ tilegx_print_operand (FILE *file, rtx x, int code)
 	  return;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 0:
       if (REG_P (x))
diff --git gcc/gcc/config/tilepro/tilepro.c gcc/gcc/config/tilepro/tilepro.c
index 628cd04..7185dda 100644
--- gcc/gcc/config/tilepro/tilepro.c
+++ gcc/gcc/config/tilepro/tilepro.c
@@ -2351,6 +2351,7 @@ tilepro_emit_cc_test (enum rtx_code code, rtx op0, rtx op1,
 	  if (n == -1)
 	    break;
 	  /* FALLTHRU */
+	  gcc_fallthrough ();
 
 	case LTU:
 	  /* Change ((unsigned)x < 0x1000) into !((unsigned)x >> 12),
@@ -4792,6 +4793,7 @@ tilepro_print_operand (FILE *file, rtx x, int code)
 	  return;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case 0:
       if (REG_P (x))
diff --git gcc/gcc/config/v850/v850.c gcc/gcc/config/v850/v850.c
index e0e4215..9529e27 100644
--- gcc/gcc/config/v850/v850.c
+++ gcc/gcc/config/v850/v850.c
@@ -411,6 +411,7 @@ v850_print_operand (FILE * file, rtx x, int code)
           break;
         }
       /* Fall through.  */
+      gcc_fallthrough ();
     case 'b':
     case 'B':
     case 'C':
diff --git gcc/gcc/config/vax/vax.c gcc/gcc/config/vax/vax.c
index 804f0c7..35a62de 100644
--- gcc/gcc/config/vax/vax.c
+++ gcc/gcc/config/vax/vax.c
@@ -785,6 +785,7 @@ vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  return true;
 	}
       /* FALLTHRU */
+      gcc_fallthrough ();
 
     case CONST:
     case LABEL_REF:
diff --git gcc/gcc/config/visium/visium.c gcc/gcc/config/visium/visium.c
index 6712fed..be91ad7 100644
--- gcc/gcc/config/visium/visium.c
+++ gcc/gcc/config/visium/visium.c
@@ -2219,6 +2219,7 @@ visium_expand_int_cstore (rtx *operands, enum machine_mode mode)
       reverse = true;
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case LTU:
     case GTU:
@@ -2267,6 +2268,7 @@ visium_expand_fp_cstore (rtx *operands,
       reverse = true;
 
       /* ... fall through ...  */
+      gcc_fallthrough ();
 
     case LT:
     case GT:
diff --git gcc/gcc/config/xtensa/xtensa.c gcc/gcc/config/xtensa/xtensa.c
index 64d089b..fa0140e 100644
--- gcc/gcc/config/xtensa/xtensa.c
+++ gcc/gcc/config/xtensa/xtensa.c
@@ -1565,6 +1565,7 @@ xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val,
       val = expand_simple_binop (SImode, AND, val, ac.modemask,
 				 NULL_RTX, 1, OPTAB_DIRECT);
       /* FALLTHRU */
+      gcc_fallthrough ();
     case SET:
       tmp = expand_simple_binop (SImode, AND, old, ac.modemaski,
 				 NULL_RTX, 1, OPTAB_DIRECT);
@@ -2424,6 +2425,7 @@ print_operand (FILE *file, rtx x, int letter)
 	}
 
       /* fall through */
+      gcc_fallthrough ();
 
     default:
       if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
@@ -3739,6 +3741,7 @@ xtensa_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	  }
       }
       /* Fall through.  */
+      gcc_fallthrough ();
 
     case UDIV:
     case UMOD:

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: testsuite
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (20 preceding siblings ...)
  2016-07-11 19:59 ` Implement -Wswitch-fallthrough: other archs Marek Polacek
@ 2016-07-11 20:00 ` Marek Polacek
  2016-07-11 20:00 ` Implement -Wswitch-fallthrough Andrew Pinski
                   ` (7 subsequent siblings)
  29 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 20:00 UTC (permalink / raw)
  To: GCC Patches

2016-07-11  Marek Polacek  <polacek@redhat.com>

	PR c/7652
	* c-c++-common/Wswitch-unreachable-1.c: Add __builtin_fallthrough.
	* c-c++-common/pr44832.c: Likewise.
	* g++.dg/lto/20090128_0.C: Likewise.
	* g++.dg/opt/pr14029.C: Likewise.
	* g++.dg/opt/pr45412.C: Likewise.
	* g++.dg/opt/pr56999.C: Likewise.
	* g++.dg/pr48484.C: Likewise.
	* g++.dg/pr57662.C: Likewise.
	* g++.dg/torture/pr64565.C: Likewise.
	* gcc.dg/pr20017.c: Likewise.
	* gcc.dg/pr27531-1.c: Likewise.
	* gcc.dg/switch-1.c: Likewise.
	* gcc.dg/torture/pr64284.c: Likewise.
	* c-c++-common/Wmisleading-indentation-2.c: Use -Wno-switch-fallthrough.
	* g++.dg/opt/eh5.C: Likewise.
	* g++.dg/torture/pr49615.C: Likewise.
	* g++.dg/warn/sequence-pt-pr17880.C: Likewise.
	* gcc.dg/sequence-pt-pr17880.c: Likewise.
	* gcc.dg/Wjump-misses-init-2.c: Likewise.
	* gcc.dg/c99-vla-jump-5.c: Likewise.
	* gcc.dg/duff-1.c: Likewise.
	* gcc.dg/duff-2.c: Likewise.
	* gcc.dg/duff-3.c: Likewise.
	* gcc.dg/duff-4.c: Likewise.
	* gcc.dg/ipa/pr57539.c: Likewise.
	* gcc.dg/noncompile/920923-1.c: Likewise.
	* gcc.dg/pr42388.c: Likewise.
	* gcc.dg/pr45055.c: Likewise.
	* gcc.dg/pr52139.c: Likewise.
	* gcc.dg/pr53881-2.c: Likewise.
	* gcc.dg/pr53887.c: Likewise.
	* gcc.dg/pr55150-2.c: Likewise.
	* gcc.dg/pr59418.c: Likewise.
	* gcc.dg/pr65658.c: Likewise.
	* gcc.dg/pr71084.c: Likewise.
	* gcc.dg/torture/pr38948.c: Likewise.
	* gcc.dg/tree-ssa/20030814-2.c: Likewise.
	* gcc.dg/tree-ssa/20030814-3.c: Likewise.
	* gcc.dg/tree-ssa/inline-10.c: Likewise.
	* gcc.dg/tree-ssa/ssa-dom-thread-9.c: Likewise.
	* gcc.dg/tree-ssa/ssa-fre-10.c: Likewise.
	* gcc.target/aarch64/pic-symrefplus.c: Likewise.
	* gcc.target/i386/avx2-vperm2i128-2.c: Likewise.
	* gcc.target/i386/pr46939.c: Likewise.

diff --git gcc/gcc/testsuite/c-c++-common/Wmisleading-indentation-2.c gcc/gcc/testsuite/c-c++-common/Wmisleading-indentation-2.c
index b4ee700..b00ccc2 100644
--- gcc/gcc/testsuite/c-c++-common/Wmisleading-indentation-2.c
+++ gcc/gcc/testsuite/c-c++-common/Wmisleading-indentation-2.c
@@ -1,4 +1,4 @@
-/* { dg-options "-Wmisleading-indentation" } */
+/* { dg-options "-Wmisleading-indentation -Wno-switch-fallthrough" } */
 /* { dg-do compile } */
 
 /* Based on get_attr_athlon_decode from the generated insn-attrtab.c
diff --git gcc/gcc/testsuite/c-c++-common/Wswitch-unreachable-1.c gcc/gcc/testsuite/c-c++-common/Wswitch-unreachable-1.c
index ee6ecc1..26e085d 100644
--- gcc/gcc/testsuite/c-c++-common/Wswitch-unreachable-1.c
+++ gcc/gcc/testsuite/c-c++-common/Wswitch-unreachable-1.c
@@ -108,6 +108,7 @@ X:
     {
 L:
       j = 16;
+      __builtin_fallthrough ();
       default:
 	if (j < 5)
 	  goto L;
diff --git gcc/gcc/testsuite/c-c++-common/pr44832.c gcc/gcc/testsuite/c-c++-common/pr44832.c
index b57e525..a8d0b4d 100644
--- gcc/gcc/testsuite/c-c++-common/pr44832.c
+++ gcc/gcc/testsuite/c-c++-common/pr44832.c
@@ -93,6 +93,7 @@ half:
     case V16QImode:
       if (!((ix86_isa_flags & (1 << 19)) != 0))
  break;
+      __builtin_fallthrough ();
 
     case V8HImode:
       if (!((ix86_isa_flags & (1 << 17)) != 0))
diff --git gcc/gcc/testsuite/g++.dg/lto/20090128_0.C gcc/gcc/testsuite/g++.dg/lto/20090128_0.C
index d03cfc6..c639d92 100644
--- gcc/gcc/testsuite/g++.dg/lto/20090128_0.C
+++ gcc/gcc/testsuite/g++.dg/lto/20090128_0.C
@@ -79,6 +79,7 @@ Class1::f3 (const char *src, char *dst, const char *end)
 	{
 	case KXYYZ:
 	  *dst = '\0';
+	  __builtin_fallthrough ();
 	case KXFI9:
  	  if (!f2 (p9t42, &src, &dst, end))
 	    ;
diff --git gcc/gcc/testsuite/g++.dg/opt/eh5.C gcc/gcc/testsuite/g++.dg/opt/eh5.C
index 3557ab2..92580ac 100644
--- gcc/gcc/testsuite/g++.dg/opt/eh5.C
+++ gcc/gcc/testsuite/g++.dg/opt/eh5.C
@@ -1,6 +1,6 @@
 // PR 41377
 // { dg-do compile }
-// { dg-options "-O3" }
+// { dg-options "-O3 -Wno-switch-fallthrough" }
 
 struct A
 {
diff --git gcc/gcc/testsuite/g++.dg/opt/pr14029.C gcc/gcc/testsuite/g++.dg/opt/pr14029.C
index 1673edf..5a67b17 100644
--- gcc/gcc/testsuite/g++.dg/opt/pr14029.C
+++ gcc/gcc/testsuite/g++.dg/opt/pr14029.C
@@ -28,6 +28,7 @@ Iterator find_7(Iterator first, Iterator last)
     case 1:
           if (*first.ptr == 7) return first;
           ++first;
+    __builtin_fallthrough ();
     case 0:
     default:
           return last;
diff --git gcc/gcc/testsuite/g++.dg/opt/pr45412.C gcc/gcc/testsuite/g++.dg/opt/pr45412.C
index e374f52..4259c7c 100644
--- gcc/gcc/testsuite/g++.dg/opt/pr45412.C
+++ gcc/gcc/testsuite/g++.dg/opt/pr45412.C
@@ -18,6 +18,7 @@ S::vm ()
     {
       case 0:
 	  bar ();
+	  __builtin_fallthrough ();
       case 1:
 	  delete this;
     }
diff --git gcc/gcc/testsuite/g++.dg/opt/pr56999.C gcc/gcc/testsuite/g++.dg/opt/pr56999.C
index 8d89ffa..6c48a72 100644
--- gcc/gcc/testsuite/g++.dg/opt/pr56999.C
+++ gcc/gcc/testsuite/g++.dg/opt/pr56999.C
@@ -131,6 +131,7 @@ namespace js
 	    JITScript *jit = script->getJIT (constructing, barriers);
 	    if (!jit)
 	      return false;
+	    __builtin_fallthrough ();
 	  }
 	case ParallelIon:
 	  return true;
diff --git gcc/gcc/testsuite/g++.dg/pr48484.C gcc/gcc/testsuite/g++.dg/pr48484.C
index 1380c45..f8595da 100644
--- gcc/gcc/testsuite/g++.dg/pr48484.C
+++ gcc/gcc/testsuite/g++.dg/pr48484.C
@@ -96,6 +96,7 @@ bool
 	       _stack._vals[_i_._arg2], _i_._arg2, _i_._arg1, tojump);
 
 	    ci += tojump;  /* { dg-warning "uninitialized" "warning" }  */
+	    __builtin_fallthrough ();
 	  }
 	case 1:
 	  _stack.fff (_i_._arg1);
diff --git gcc/gcc/testsuite/g++.dg/pr57662.C gcc/gcc/testsuite/g++.dg/pr57662.C
index bd5793d..0c77b65 100644
--- gcc/gcc/testsuite/g++.dg/pr57662.C
+++ gcc/gcc/testsuite/g++.dg/pr57662.C
@@ -328,6 +328,7 @@ static bool cp_parser_pragma(cp_parser * parser, enum pragma_context context)
 	switch (id) {
 	case PRAGMA_OMP_DECLARE_REDUCTION:
 		cp_parser_omp_declare(parser, pragma_tok, context);
+		__builtin_fallthrough ();
 	case PRAGMA_OMP_TARGET:
 		return cp_parser_omp_target(parser, pragma_tok, context);
 	}
diff --git gcc/gcc/testsuite/g++.dg/torture/pr49615.C gcc/gcc/testsuite/g++.dg/torture/pr49615.C
index 98a2f95..2aa641a 100644
--- gcc/gcc/testsuite/g++.dg/torture/pr49615.C
+++ gcc/gcc/testsuite/g++.dg/torture/pr49615.C
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-g" } */
+/* { dg-options "-g -Wno-switch-fallthrough" } */
 
 template <class T>
 static inline bool Dispatch (T* obj, void (T::*func) ())
diff --git gcc/gcc/testsuite/g++.dg/torture/pr64565.C gcc/gcc/testsuite/g++.dg/torture/pr64565.C
index 42b0239..eeb5f10 100644
--- gcc/gcc/testsuite/g++.dg/torture/pr64565.C
+++ gcc/gcc/testsuite/g++.dg/torture/pr64565.C
@@ -75,6 +75,7 @@ J::m_fn2 ()
         F query = 0;
         if (Refresh_hasDomain)
           return NS_OK;
+	__builtin_fallthrough ();
       }
     case 0:
       {
@@ -82,6 +83,7 @@ J::m_fn2 ()
         F query = Refresh___trans_tmp_5.m_fn4 (0);
         history.m_fn7 ();
         Refresh___trans_tmp_6.m_fn5 (0);
+	__builtin_fallthrough ();
       }
     case 3:
       m_fn2 ();
diff --git gcc/gcc/testsuite/g++.dg/warn/sequence-pt-pr17880.C gcc/gcc/testsuite/g++.dg/warn/sequence-pt-pr17880.C
index 01d87be..58de858 100644
--- gcc/gcc/testsuite/g++.dg/warn/sequence-pt-pr17880.C
+++ gcc/gcc/testsuite/g++.dg/warn/sequence-pt-pr17880.C
@@ -1,6 +1,6 @@
 // PR 17880
 // { dg-do compile }
-// { dg-options "-Wsequence-point" }
+// { dg-options "-Wsequence-point -Wno-switch-fallthrough" }
 
 int
 foo (int x)
diff --git gcc/gcc/testsuite/gcc.dg/Wjump-misses-init-2.c gcc/gcc/testsuite/gcc.dg/Wjump-misses-init-2.c
index 042c02a..c66e5da 100644
--- gcc/gcc/testsuite/gcc.dg/Wjump-misses-init-2.c
+++ gcc/gcc/testsuite/gcc.dg/Wjump-misses-init-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Wjump-misses-init -std=c99" } */
+/* { dg-options "-Wjump-misses-init -std=c99 -Wno-switch-fallthrough" } */
 extern void f1 ();
 int
 f2 (int a)
diff --git gcc/gcc/testsuite/gcc.dg/c99-vla-jump-5.c gcc/gcc/testsuite/gcc.dg/c99-vla-jump-5.c
index 5b5fc74..9003279 100644
--- gcc/gcc/testsuite/gcc.dg/c99-vla-jump-5.c
+++ gcc/gcc/testsuite/gcc.dg/c99-vla-jump-5.c
@@ -9,7 +9,7 @@
 
 /* Origin: Joseph Myers <joseph@codesourcery.com> */
 /* { dg-do compile } */
-/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors -Wno-switch-fallthrough" } */
 
 void
 f (int a, int b)
diff --git gcc/gcc/testsuite/gcc.dg/duff-1.c gcc/gcc/testsuite/gcc.dg/duff-1.c
index b718f6c..3d47576 100644
--- gcc/gcc/testsuite/gcc.dg/duff-1.c
+++ gcc/gcc/testsuite/gcc.dg/duff-1.c
@@ -5,7 +5,7 @@
    Derived from PR 3846.  */
 
 /* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-switch-fallthrough" } */
 
 extern void abort (void);
 extern void exit (int);
diff --git gcc/gcc/testsuite/gcc.dg/duff-2.c gcc/gcc/testsuite/gcc.dg/duff-2.c
index 8b8923e..e7287f3 100644
--- gcc/gcc/testsuite/gcc.dg/duff-2.c
+++ gcc/gcc/testsuite/gcc.dg/duff-2.c
@@ -6,7 +6,7 @@
    See also PR 5230.  */
 
 /* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-switch-fallthrough" } */
 
 extern void abort (void);
 extern void exit (int);
diff --git gcc/gcc/testsuite/gcc.dg/duff-3.c gcc/gcc/testsuite/gcc.dg/duff-3.c
index 23cddef..53f8990 100644
--- gcc/gcc/testsuite/gcc.dg/duff-3.c
+++ gcc/gcc/testsuite/gcc.dg/duff-3.c
@@ -5,7 +5,7 @@
    Derived from Tom Duff's original usenet message about the device.  */
 
 /* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-switch-fallthrough" } */
 
 extern void abort (void);
 extern void exit (int);
diff --git gcc/gcc/testsuite/gcc.dg/duff-4.c gcc/gcc/testsuite/gcc.dg/duff-4.c
index 7032285..a8b2c63 100644
--- gcc/gcc/testsuite/gcc.dg/duff-4.c
+++ gcc/gcc/testsuite/gcc.dg/duff-4.c
@@ -5,7 +5,7 @@
    Derived from duff-2.c.  */
 
 /* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-switch-fallthrough" } */
 
 extern void abort (void);
 extern void exit (int);
diff --git gcc/gcc/testsuite/gcc.dg/ipa/pr57539.c gcc/gcc/testsuite/gcc.dg/ipa/pr57539.c
index 514b600..9b5505e 100644
--- gcc/gcc/testsuite/gcc.dg/ipa/pr57539.c
+++ gcc/gcc/testsuite/gcc.dg/ipa/pr57539.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O3" } */
+/* { dg-options "-O3 -Wno-switch-fallthrough" } */
 
 typedef long unsigned int size_t;
 typedef struct
diff --git gcc/gcc/testsuite/gcc.dg/noncompile/920923-1.c gcc/gcc/testsuite/gcc.dg/noncompile/920923-1.c
index 1cb140e..713918d 100644
--- gcc/gcc/testsuite/gcc.dg/noncompile/920923-1.c
+++ gcc/gcc/testsuite/gcc.dg/noncompile/920923-1.c
@@ -1,3 +1,4 @@
+/* { dg-options "-Wno-switch-fallthrough" } */
 /* { dg-message "undeclared identifier is reported only once" "reminder for mmu_base" { target *-*-* } 0 } */
 typedef BYTE unsigned char;	/* { dg-error "expected" } */
 typedef int item_n;
diff --git gcc/gcc/testsuite/gcc.dg/pr20017.c gcc/gcc/testsuite/gcc.dg/pr20017.c
index 47c048f..f77d7e8 100644
--- gcc/gcc/testsuite/gcc.dg/pr20017.c
+++ gcc/gcc/testsuite/gcc.dg/pr20017.c
@@ -32,6 +32,7 @@ foo (int *buf, int *p)
       result = *p;
 
       /* Fall through.  */
+      __builtin_fallthrough ();
     default:
       if (result)
 	return 1;
diff --git gcc/gcc/testsuite/gcc.dg/pr27531-1.c gcc/gcc/testsuite/gcc.dg/pr27531-1.c
index 990c183..e28f56cc 100644
--- gcc/gcc/testsuite/gcc.dg/pr27531-1.c
+++ gcc/gcc/testsuite/gcc.dg/pr27531-1.c
@@ -41,14 +41,19 @@ int main (int argc, char **argv)
         {
             case 'L':
                 onlylockflag = 1;
+		__builtin_fallthrough ();
             case 'N':
                 shownames = 0;
+		__builtin_fallthrough ();
             case 'R':
                 t = a;
+		__builtin_fallthrough ();
             case 'b':
                 branchflag = 1;
+		__builtin_fallthrough ();
             case 'r':
                 getrevpairs(a);
+		__builtin_fallthrough ();
         }
         if (onlylockflag && !Locks)
             fprintf(out, "%s\n", RCSname);
diff --git gcc/gcc/testsuite/gcc.dg/pr42388.c gcc/gcc/testsuite/gcc.dg/pr42388.c
index a68a2e8..4ac4b0d 100644
--- gcc/gcc/testsuite/gcc.dg/pr42388.c
+++ gcc/gcc/testsuite/gcc.dg/pr42388.c
@@ -1,5 +1,5 @@
 /* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O2 -fselective-scheduling -fmodulo-sched" } */
+/* { dg-options "-O2 -fselective-scheduling -fmodulo-sched -Wno-switch-fallthrough" } */
 
 enum rtx_code
 {
diff --git gcc/gcc/testsuite/gcc.dg/pr45055.c gcc/gcc/testsuite/gcc.dg/pr45055.c
index 899de50..36f11e9 100644
--- gcc/gcc/testsuite/gcc.dg/pr45055.c
+++ gcc/gcc/testsuite/gcc.dg/pr45055.c
@@ -1,6 +1,6 @@
 /* PR debug/45055 */
 /* { dg-do compile } */
-/* { dg-options "-O2 -ftracer -fsched-pressure -funroll-loops -fschedule-insns -fcompare-debug" } */
+/* { dg-options "-O2 -ftracer -fsched-pressure -funroll-loops -fschedule-insns -fcompare-debug -Wno-switch-fallthrough" } */
 /* { dg-require-effective-target scheduling } */
 
 int colormap[10];
diff --git gcc/gcc/testsuite/gcc.dg/pr52139.c gcc/gcc/testsuite/gcc.dg/pr52139.c
index b2a08a6..4e691aa 100644
--- gcc/gcc/testsuite/gcc.dg/pr52139.c
+++ gcc/gcc/testsuite/gcc.dg/pr52139.c
@@ -1,6 +1,6 @@
 /* PR rtl-optimization/52139 */
 /* { dg-do compile } */
-/* { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre" } */
+/* { dg-options "-O -fno-tree-dominator-opts -fno-tree-fre -Wno-switch-fallthrough" } */
 /* { dg-additional-options "-fpic" { target fpic } } */
 /* { dg-require-effective-target label_values } */
 
diff --git gcc/gcc/testsuite/gcc.dg/pr53881-2.c gcc/gcc/testsuite/gcc.dg/pr53881-2.c
index f6f8f8b..735580c 100644
--- gcc/gcc/testsuite/gcc.dg/pr53881-2.c
+++ gcc/gcc/testsuite/gcc.dg/pr53881-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-switch-fallthrough" } */
 
 int a,b,c;
 void
diff --git gcc/gcc/testsuite/gcc.dg/pr53887.c gcc/gcc/testsuite/gcc.dg/pr53887.c
index b46126c..9a73c4b 100644
--- gcc/gcc/testsuite/gcc.dg/pr53887.c
+++ gcc/gcc/testsuite/gcc.dg/pr53887.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-switch-fallthrough" } */
 
 enum
 { Failed, NoError, NoDiskette }
diff --git gcc/gcc/testsuite/gcc.dg/pr55150-2.c gcc/gcc/testsuite/gcc.dg/pr55150-2.c
index ed571d6..5b05ca1 100644
--- gcc/gcc/testsuite/gcc.dg/pr55150-2.c
+++ gcc/gcc/testsuite/gcc.dg/pr55150-2.c
@@ -1,7 +1,7 @@
 /* PR middle-end/55150 */
 /* { dg-do compile } */
 /* { dg-require-effective-target fpic } */
-/* { dg-options "-Os -g -fPIC" } */
+/* { dg-options "-Os -g -fPIC -Wno-switch-fallthrough" } */
 
 typedef unsigned char DES_cblock[8];
  typedef struct DES_ks {
diff --git gcc/gcc/testsuite/gcc.dg/pr59418.c gcc/gcc/testsuite/gcc.dg/pr59418.c
index 12999aa..57bbf53 100644
--- gcc/gcc/testsuite/gcc.dg/pr59418.c
+++ gcc/gcc/testsuite/gcc.dg/pr59418.c
@@ -2,7 +2,7 @@
 /* Reported by Ryan Mansfield <rmansfield@qnx.com> */
 
 /* { dg-do compile } */
-/* { dg-options "-Os -g" } */
+/* { dg-options "-Os -g -Wno-switch-fallthrough" } */
 /* { dg-options "-march=armv7-a -mfloat-abi=hard -Os -g" { target { arm*-*-* && { ! arm_thumb1 } } } } */
 
 extern int printf (const char *__format, ...);
diff --git gcc/gcc/testsuite/gcc.dg/pr65658.c gcc/gcc/testsuite/gcc.dg/pr65658.c
index bb5c37a..83a2cb1 100644
--- gcc/gcc/testsuite/gcc.dg/pr65658.c
+++ gcc/gcc/testsuite/gcc.dg/pr65658.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Wuninitialized -O2 -Wno-implicit" } */
+/* { dg-options "-Wuninitialized -O2 -Wno-implicit -Wno-switch-fallthrough" } */
 /* { dg-require-effective-target ptr32plus } */
 
 extern int optind;
diff --git gcc/gcc/testsuite/gcc.dg/pr71084.c gcc/gcc/testsuite/gcc.dg/pr71084.c
index 46fdf9f..0994932 100644
--- gcc/gcc/testsuite/gcc.dg/pr71084.c
+++ gcc/gcc/testsuite/gcc.dg/pr71084.c
@@ -1,6 +1,6 @@
 /* PR tree-optimization/71084 */
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-switch-fallthrough" } */
 
 void babl_format (void);
 void gimp_drawable_get_format (void);
diff --git gcc/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c gcc/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c
index df706e5..c5ed973 100644
--- gcc/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c
+++ gcc/gcc/testsuite/gcc.dg/sequence-pt-pr17880.c
@@ -1,6 +1,6 @@
 /* PR 17880 */
 /* { dg-do compile } */
-/* { dg-options "-Wsequence-point" } */
+/* { dg-options "-Wsequence-point -Wno-switch-fallthrough" } */
 
 int
 foo (int x)
diff --git gcc/gcc/testsuite/gcc.dg/switch-1.c gcc/gcc/testsuite/gcc.dg/switch-1.c
index 1879790..2534f3e 100644
--- gcc/gcc/testsuite/gcc.dg/switch-1.c
+++ gcc/gcc/testsuite/gcc.dg/switch-1.c
@@ -10,6 +10,7 @@ void f (char *s)
 	{
 	case 2:
 	  *s = '2';
+	  __builtin_fallthrough ();
 	case 6: case 4: case 3: case 1:
 	  break;
 	}
diff --git gcc/gcc/testsuite/gcc.dg/torture/pr38948.c gcc/gcc/testsuite/gcc.dg/torture/pr38948.c
index 90906ee..0a3aad6 100644
--- gcc/gcc/testsuite/gcc.dg/torture/pr38948.c
+++ gcc/gcc/testsuite/gcc.dg/torture/pr38948.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fno-tree-sra" } */
+/* { dg-options "-fno-tree-sra -Wno-switch-fallthrough" } */
 /* { dg-options "-fno-tree-sra -march=v32" { target cris-*-* } } */
 typedef unsigned char byte;
 typedef unsigned int uint;
diff --git gcc/gcc/testsuite/gcc.dg/torture/pr64284.c gcc/gcc/testsuite/gcc.dg/torture/pr64284.c
index 4254381..dae08a3 100644
--- gcc/gcc/testsuite/gcc.dg/torture/pr64284.c
+++ gcc/gcc/testsuite/gcc.dg/torture/pr64284.c
@@ -9,6 +9,7 @@ fn1() {
 	switch (*a) {
 	  case '\'':
 	  c = 0;
+	  __builtin_fallthrough ();
 	  default:
 	  switch (c)
 	  case 0:
diff --git gcc/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c gcc/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c
index a99abf4..8dde43f 100644
--- gcc/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c
+++ gcc/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-dom2" } */
+/* { dg-options "-O1 -fdump-tree-dom2 -Wno-switch-fallthrough" } */
     
 extern void abort (void);
 extern void blah (void);
diff --git gcc/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c gcc/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c
index 149da1b..d95e780 100644
--- gcc/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c
+++ gcc/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-dom2" } */
+/* { dg-options "-O1 -fdump-tree-dom2 -Wno-switch-fallthrough" } */
     
 extern void abort (void);
 extern void blah (void);
diff --git gcc/gcc/testsuite/gcc.dg/tree-ssa/inline-10.c gcc/gcc/testsuite/gcc.dg/tree-ssa/inline-10.c
index 118e19e..38048bb 100644
--- gcc/gcc/testsuite/gcc.dg/tree-ssa/inline-10.c
+++ gcc/gcc/testsuite/gcc.dg/tree-ssa/inline-10.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Os -fdump-tree-optimized -fno-partial-inlining" } */
+/* { dg-options "-Os -fdump-tree-optimized -fno-partial-inlining -Wno-switch-fallthrough" } */
 void do_something1(void);
 void do_something2(void);
 void do_something3(void);
diff --git gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c
index 2d9028d..d9f80f6 100644
--- gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c
+++ gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c
@@ -1,6 +1,6 @@
 /* PR 65048 */
 /* { dg-do compile } */
-/* { dg-options "-O3 -std=gnu89" } */
+/* { dg-options "-O3 -std=gnu89 -Wno-switch-fallthrough" } */
 
 int a, b, c, d;
 void fn (void);
diff --git gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-10.c gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-10.c
index 7f2d1eb..d04335e 100644
--- gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-10.c
+++ gcc/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-10.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -Wno-switch-fallthrough" } */
 
 union loc {  unsigned reg; signed offset; };
 void __frame_state_for (volatile char *state_in, int x)
diff --git gcc/gcc/testsuite/gcc.target/aarch64/pic-symrefplus.c gcc/gcc/testsuite/gcc.target/aarch64/pic-symrefplus.c
index 406568c..53e36b9 100644
--- gcc/gcc/testsuite/gcc.target/aarch64/pic-symrefplus.c
+++ gcc/gcc/testsuite/gcc.target/aarch64/pic-symrefplus.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -mcmodel=small -fPIC -fno-builtin" }  */
+/* { dg-options "-O2 -mcmodel=small -fPIC -fno-builtin -Wno-switch-fallthrough" }  */
 /* { dg-do compile } */
 
 typedef long unsigned int size_t;
diff --git gcc/gcc/testsuite/gcc.target/i386/avx2-vperm2i128-2.c gcc/gcc/testsuite/gcc.target/i386/avx2-vperm2i128-2.c
index 96f32b8..5a8b1ef 100644
--- gcc/gcc/testsuite/gcc.target/i386/avx2-vperm2i128-2.c
+++ gcc/gcc/testsuite/gcc.target/i386/avx2-vperm2i128-2.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-mavx2 -O2" } */
+/* { dg-options "-mavx2 -O2 -Wno-switch-fallthrough" } */
 /* { dg-require-effective-target avx2 } */
 
 #include "avx2-check.h"
diff --git gcc/gcc/testsuite/gcc.target/i386/pr46939.c gcc/gcc/testsuite/gcc.target/i386/pr46939.c
index 0fd8607..646b6a1 100644
--- gcc/gcc/testsuite/gcc.target/i386/pr46939.c
+++ gcc/gcc/testsuite/gcc.target/i386/pr46939.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-switch-fallthrough" } */
 
 __extension__ typedef __SIZE_TYPE__ size_t;
 

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (21 preceding siblings ...)
  2016-07-11 20:00 ` Implement -Wswitch-fallthrough: testsuite Marek Polacek
@ 2016-07-11 20:00 ` Andrew Pinski
  2016-07-11 20:01   ` Marek Polacek
  2016-07-11 20:01 ` Andi Kleen
                   ` (6 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Andrew Pinski @ 2016-07-11 20:00 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 12:43 PM, Marek Polacek <polacek@redhat.com> wrote:
> The switch fallthrough has been widely considered a design defect in C, a
> misfeature or, to use Marshall Cline's definition, evil.  The overwhelming
> majority of the time you don't want to fall through to the next case, but it is
> easy to forget to "break" at the end of the case, making this far too error
> prone.  Yet GCC (and probably other compilers, too) doesn't have the ability to
> warn in this case.  A feature request for such warning was opened back in 2002,
> but it's mostly been untouched since.  But then the [[fallthrough]] attribute was
> approved for C++17 [1], and that's what has got me to do all this.
>
> The following series attempts to implement the fabled -Wswitch-fallthrough
> warning.  The warning would be quite easy to implement were it not for control
> statements, nested scopes, gotos, and such.  I took great pains to try to
> handle all of that before I succeeded in getting all the pieces in place.  So
> GCC ought to do the right thing for e.g.:
>
>   switch (n)
>     {
>     case 1:
>       if (n > 20)
>         break;
>       else if (n > 10)
>         {
>           foo (9);
>           __builtin_fallthrough ();
>         }
>       else
>         foo (8); // warn here
>     case 2:;
>     }
>
> Since approximately 3% of fall throughs are desirable, I added a new builtin,
> __builtin_fallthrough, that prevents the warning from occurring.  It can only
> be used in a switch; the compiler will issue an error otherwise.  The new C++
> attribute can then be implemented in terms of this builtin.  There was an idea
> floating around about not warning for /* FALLTHRU */ etc. comments but I
> rejected this after I'd spent time thinking about it: the preprocessor can't
> know that we're in a switch statement so we might reject valid programs, the
> "falls through" comments vary wildly, occur even in if-statements, etc.  The
> warning doesn't warn when the block is empty, e.g. on case 1: case 2: ...  The
> warning does, inevitably, trigger on Duff's devices.  Too bad.  I guess I'd
> suggest using #pragma GCC warning then.  (I think Perl uses the "continue"
> keyword for exactly this purpose -- an interesting idea...)
>
> After I'd completed the warning, I kicked off a bootstrap so as to add various
> gcc_fallthrough calls.  There were a good amount of them, as expected.  I also
> grepped various FALLTHRU/Falls through/...fall thru.../... comments in config/
> and added gcc_fallthroughs to make it easier for people.  Wherever I wasn't
> sure that the gcc_fallthrough was appropriate, I added an 'XXX' comment.  This
> must not be relied upon as I don't know most of the compiler code.  The same
> goes for relevant libraries where I introduced various gomp_fallthrough
> macros conditional on __GNUC__ (I'd tried to use a configure check but then
> decided I won't put up with all the vagaries of autoconf).
>
> This patch is accompanied by more than 2000 lines of new tests to get the
> warning covered though I'm sure folks will come up with other test cases
> that I hadn't considered (hi Martin S. ;).
>
> This warning is enabled by default for C/C++.  I was more inclined to put this
> into -Wall, but our common.opt machinery doesn't seem to allow that (ugh!).
> The clang version I have installed doesn't have this warning so I couldn't
> compare my implementation with others.

I don't like it being default turned on or even part of -Wall.  As
evidence all of the patches that comes after this is the main reason
why.

Thanks,
Andrew

>
> I plan to plunge into the C++ [[fallthrough]] thingie after this core part is
> dealt with.
>
> Since the patch is too large, I split it into various parts, the core and then
> various __builtin_fallthrough additions.
>
> This patch has been tested on powerpc64le-unknown-linux-gnu, aarch64-linux-gnu,
> x86_64-redhat-linux, and also on powerpc-ibm-aix7.1.0.0, though due to PR71816
> I was unable to bootstrap.
>
> Thanks,
>
> [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0188r0.pdf
>
>         Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (22 preceding siblings ...)
  2016-07-11 20:00 ` Implement -Wswitch-fallthrough Andrew Pinski
@ 2016-07-11 20:01 ` Andi Kleen
  2016-07-11 20:04   ` Marek Polacek
  2016-07-11 20:08 ` Eric Botcazou
                   ` (5 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Andi Kleen @ 2016-07-11 20:01 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

Marek Polacek <polacek@redhat.com> writes:
>
> This warning is enabled by default for C/C++.

That's purely evil. So have to put your non standard builtin all over
standards compliant code just to shut off a warning that is likely
common. And you're not even supporting the classic lint style comment either.

I think it's ok to make this a separate option, but even putting it in
-Wall would annoy far too many people (including me) for good reasons.
Making it default is just totally wrong.

-Andi

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:00 ` Implement -Wswitch-fallthrough Andrew Pinski
@ 2016-07-11 20:01   ` Marek Polacek
  2016-07-11 20:03     ` Andrew Pinski
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 20:01 UTC (permalink / raw)
  To: Andrew Pinski; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 12:59:51PM -0700, Andrew Pinski wrote:
> I don't like it being default turned on or even part of -Wall.  As
> evidence all of the patches that comes after this is the main reason
> why.

Ok, moving this to -Wextra is rather trivial.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:01   ` Marek Polacek
@ 2016-07-11 20:03     ` Andrew Pinski
  0 siblings, 0 replies; 77+ messages in thread
From: Andrew Pinski @ 2016-07-11 20:03 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 1:01 PM, Marek Polacek <polacek@redhat.com> wrote:
> On Mon, Jul 11, 2016 at 12:59:51PM -0700, Andrew Pinski wrote:
>> I don't like it being default turned on or even part of -Wall.  As
>> evidence all of the patches that comes after this is the main reason
>> why.
>
> Ok, moving this to -Wextra is rather trivial.

Even -Wextra is not useful either.  If anything maybe -Wc++1z-compat :).

>
>         Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:01 ` Andi Kleen
@ 2016-07-11 20:04   ` Marek Polacek
  2016-07-11 20:18     ` Andi Kleen
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 20:04 UTC (permalink / raw)
  To: Andi Kleen; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 01:01:05PM -0700, Andi Kleen wrote:
> Marek Polacek <polacek@redhat.com> writes:
> >
> > This warning is enabled by default for C/C++.
> 
> That's purely evil. So have to put your non standard builtin all over
> standards compliant code just to shut off a warning that is likely
> common. And you're not even supporting the classic lint style comment either.
 
I explained why supporting the classic lint style comment wouldn't fly.

> I think it's ok to make this a separate option, but even putting it in
> -Wall would annoy far too many people (including me) for good reasons.
> Making it default is just totally wrong.

Ok.  As I mentioned elsewhere, moving this to -Wextra (or even out of -Wall/-Wextra)
is a one liner change.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (23 preceding siblings ...)
  2016-07-11 20:01 ` Andi Kleen
@ 2016-07-11 20:08 ` Eric Botcazou
  2016-07-11 20:12   ` Jakub Jelinek
  2016-07-11 20:28 ` NightStrike
                   ` (4 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Eric Botcazou @ 2016-07-11 20:08 UTC (permalink / raw)
  To: Marek Polacek; +Cc: gcc-patches

> After I'd completed the warning, I kicked off a bootstrap so as to add
> various gcc_fallthrough calls.  There were a good amount of them, as
> expected.  I also grepped various FALLTHRU/Falls through/...fall
> thru.../... comments in config/ and added gcc_fallthroughs to make it
> easier for people.  Wherever I wasn't sure that the gcc_fallthrough was
> appropriate, I added an 'XXX' comment.  This must not be relied upon as I
> don't know most of the compiler code.  The same goes for relevant libraries
> where I introduced various gomp_fallthrough macros conditional on __GNUC__
> (I'd tried to use a configure check but then decided I won't put up with
> all the vagaries of autoconf).

Do we really want to clutter up the entire tree like that?  The result is 
particularly ugly IMO.  Just add -Wno-switch-fallthrough somewhere I'd say.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:08 ` Eric Botcazou
@ 2016-07-11 20:12   ` Jakub Jelinek
  2016-07-11 20:20     ` Marek Polacek
  0 siblings, 1 reply; 77+ messages in thread
From: Jakub Jelinek @ 2016-07-11 20:12 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: Marek Polacek, gcc-patches

On Mon, Jul 11, 2016 at 10:08:02PM +0200, Eric Botcazou wrote:
> > After I'd completed the warning, I kicked off a bootstrap so as to add
> > various gcc_fallthrough calls.  There were a good amount of them, as
> > expected.  I also grepped various FALLTHRU/Falls through/...fall
> > thru.../... comments in config/ and added gcc_fallthroughs to make it
> > easier for people.  Wherever I wasn't sure that the gcc_fallthrough was
> > appropriate, I added an 'XXX' comment.  This must not be relied upon as I
> > don't know most of the compiler code.  The same goes for relevant libraries
> > where I introduced various gomp_fallthrough macros conditional on __GNUC__
> > (I'd tried to use a configure check but then decided I won't put up with
> > all the vagaries of autoconf).
> 
> Do we really want to clutter up the entire tree like that?  The result is 
> particularly ugly IMO.  Just add -Wno-switch-fallthrough somewhere I'd say.

Well, we already have the /* FALLTHRU */ etc. comments in most of the
places.  Perhaps if we replace those comments just with GCC_FALLTHRU,
a macro that expands to __builtin_fallthrough (); for GCC >= 7, or
to [[fallthrough]] for C++17, or nothing?
IMHO it doesn't make sense to keep both the gomp_fallthrough (); macro and
/* FALLTHROUGH */ etc. comments in the source.

	Jakub

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:04   ` Marek Polacek
@ 2016-07-11 20:18     ` Andi Kleen
  2016-07-11 20:23       ` Marek Polacek
  0 siblings, 1 reply; 77+ messages in thread
From: Andi Kleen @ 2016-07-11 20:18 UTC (permalink / raw)
  To: Marek Polacek; +Cc: Andi Kleen, GCC Patches

> I explained why supporting the classic lint style comment wouldn't fly.

Not convincing, it worked fine for 30+ years of lints.

-Andi
-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:12   ` Jakub Jelinek
@ 2016-07-11 20:20     ` Marek Polacek
  2016-07-11 20:30       ` Eric Botcazou
  2016-07-11 20:39       ` David Malcolm
  0 siblings, 2 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 20:20 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Eric Botcazou, gcc-patches

On Mon, Jul 11, 2016 at 10:11:52PM +0200, Jakub Jelinek wrote:
> On Mon, Jul 11, 2016 at 10:08:02PM +0200, Eric Botcazou wrote:
> > > After I'd completed the warning, I kicked off a bootstrap so as to add
> > > various gcc_fallthrough calls.  There were a good amount of them, as
> > > expected.  I also grepped various FALLTHRU/Falls through/...fall
> > > thru.../... comments in config/ and added gcc_fallthroughs to make it
> > > easier for people.  Wherever I wasn't sure that the gcc_fallthrough was
> > > appropriate, I added an 'XXX' comment.  This must not be relied upon as I
> > > don't know most of the compiler code.  The same goes for relevant libraries
> > > where I introduced various gomp_fallthrough macros conditional on __GNUC__
> > > (I'd tried to use a configure check but then decided I won't put up with
> > > all the vagaries of autoconf).
> > 
> > Do we really want to clutter up the entire tree like that?  The result is 
> > particularly ugly IMO.  Just add -Wno-switch-fallthrough somewhere I'd say.
 
I think that if *we* refuse to use __builtin_fallthrough, then we can't
expect users to use it.

> Well, we already have the /* FALLTHRU */ etc. comments in most of the
> places.  Perhaps if we replace those comments just with GCC_FALLTHRU,
> a macro that expands to __builtin_fallthrough (); for GCC >= 7, or
> to [[fallthrough]] for C++17, or nothing?
> IMHO it doesn't make sense to keep both the gomp_fallthrough (); macro and
> /* FALLTHROUGH */ etc. comments in the source.

Yea, that's a possibility, though sometimes the comment explains why the
fall through is desirable.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:18     ` Andi Kleen
@ 2016-07-11 20:23       ` Marek Polacek
  2016-07-11 20:35         ` Jakub Jelinek
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-11 20:23 UTC (permalink / raw)
  To: Andi Kleen; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 01:18:02PM -0700, Andi Kleen wrote:
> > I explained why supporting the classic lint style comment wouldn't fly.
> 
> Not convincing, it worked fine for 30+ years of lints.

So how can the compiler handle
/* Never ever fall through here */
?

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (24 preceding siblings ...)
  2016-07-11 20:08 ` Eric Botcazou
@ 2016-07-11 20:28 ` NightStrike
  2016-07-13 18:16   ` Marek Polacek
  2016-07-12 10:27 ` Richard Biener
                   ` (3 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: NightStrike @ 2016-07-11 20:28 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 3:43 PM, Marek Polacek <polacek@redhat.com> wrote:
> But then the [[fallthrough]] attribute was
> approved for C++17 [1], and that's what has got me to do all this.
>  ...
> I added a new builtin,
> __builtin_fallthrough, that prevents the warning from occurring.  It can only
> be used in a switch; the compiler will issue an error otherwise.  The new C++
> attribute can then be implemented in terms of this builtin.

This is a stupid question I'm sure, but if C++ can have the attribute
version, why can't C have __attribute__((fallthrough)) ?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:20     ` Marek Polacek
@ 2016-07-11 20:30       ` Eric Botcazou
  2016-07-11 20:39       ` David Malcolm
  1 sibling, 0 replies; 77+ messages in thread
From: Eric Botcazou @ 2016-07-11 20:30 UTC (permalink / raw)
  To: Marek Polacek; +Cc: gcc-patches, Jakub Jelinek

> I think that if *we* refuse to use __builtin_fallthrough, then we can't
> expect users to use it.

No disagreement, but this doesn't change my mind on the thing...  IMO there 
ought to be a simple & standard way of silencing the warning if it is enabled 
by default, otherwise this will very likely badly backfire.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:23       ` Marek Polacek
@ 2016-07-11 20:35         ` Jakub Jelinek
  2016-07-11 20:44           ` David Malcolm
  2016-07-12 13:57           ` NightStrike
  0 siblings, 2 replies; 77+ messages in thread
From: Jakub Jelinek @ 2016-07-11 20:35 UTC (permalink / raw)
  To: Marek Polacek, Joseph S. Myers, Jason Merrill; +Cc: Andi Kleen, GCC Patches

On Mon, Jul 11, 2016 at 10:23:30PM +0200, Marek Polacek wrote:
> On Mon, Jul 11, 2016 at 01:18:02PM -0700, Andi Kleen wrote:
> > > I explained why supporting the classic lint style comment wouldn't fly.
> > 
> > Not convincing, it worked fine for 30+ years of lints.
> 
> So how can the compiler handle
> /* Never ever fall through here */
> ?

It can't.  But it perhaps could handle a couple of documented most common
comment styles, perhaps only if followed by break token, and turn say
/* FALLTHROUGH */
break
(and say:
/* FALL THROUGH */
/* FALLTHRU */
/* FALL THRU */
/*-fallthrough*/
/* Fallthrough */
/* Fall through */
/* Fallthru */
/* Fall thru */
/* fallthrough */
/* fall through */
/* fallthru */
/* fall thru */
// FALLTHROUGH
// FALL THROUGH
// FALLTHRU
// FALL THRU
//-fallthrough
// Fallthrough
// Fall through
// Fallthru
// Fall thru
// fallthrough
// fall through
// fallthru
// fall thru
)
into:
#pragma GCC fallthrough
break
and make sure that if the pragma appears outside of switch or say in
if (...)
#pragma GCC fallthrough
break
and similar spots, then it is actually ignored, rather than affecting the
parsed code.
Supporting also __builtin_fallthrough (); and [[fallthrough]] is desirable,
the transformation of the above comments into the pragma should be
controllable by some separate switch?

	Jakub

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-11 19:59 ` Implement -Wswitch-fallthrough: rs6000 Marek Polacek
@ 2016-07-11 20:36   ` Bruce Korb
  2016-07-13 18:23     ` Marek Polacek
  2016-07-12 14:11   ` Segher Boessenkool
  1 sibling, 1 reply; 77+ messages in thread
From: Bruce Korb @ 2016-07-11 20:36 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

I'm curious about this.  In the process of developing a code analysis
tool, I found some GCC code that was, basically:

switch (v) {
case 0:
  if (e) {
    do_something();
  } else {
case 1:
    do_something_else();
  }
}

Does this patch mean that the above got fixed?  I mean, if you're
going to fret over linguistic tags to make falling through explicit,
it would seem the above code is pretty sore-thumby, yes?

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:20     ` Marek Polacek
  2016-07-11 20:30       ` Eric Botcazou
@ 2016-07-11 20:39       ` David Malcolm
  1 sibling, 0 replies; 77+ messages in thread
From: David Malcolm @ 2016-07-11 20:39 UTC (permalink / raw)
  To: Marek Polacek, Jakub Jelinek; +Cc: Eric Botcazou, gcc-patches

On Mon, 2016-07-11 at 22:20 +0200, Marek Polacek wrote:
> On Mon, Jul 11, 2016 at 10:11:52PM +0200, Jakub Jelinek wrote:
> > On Mon, Jul 11, 2016 at 10:08:02PM +0200, Eric Botcazou wrote:
> > > > After I'd completed the warning, I kicked off a bootstrap so as
> > > > to add
> > > > various gcc_fallthrough calls.  There were a good amount of
> > > > them, as
> > > > expected.  I also grepped various FALLTHRU/Falls
> > > > through/...fall
> > > > thru.../... comments in config/ and added gcc_fallthroughs to
> > > > make it
> > > > easier for people.  Wherever I wasn't sure that the
> > > > gcc_fallthrough was
> > > > appropriate, I added an 'XXX' comment.  This must not be relied
> > > > upon as I
> > > > don't know most of the compiler code.  The same goes for
> > > > relevant libraries
> > > > where I introduced various gomp_fallthrough macros conditional
> > > > on __GNUC__
> > > > (I'd tried to use a configure check but then decided I won't
> > > > put up with
> > > > all the vagaries of autoconf).
> > > 
> > > Do we really want to clutter up the entire tree like that?  The
> > > result is 
> > > particularly ugly IMO.  Just add -Wno-switch-fallthrough
> > > somewhere I'd say.
>  
> I think that if *we* refuse to use __builtin_fallthrough, then we
> can't
> expect users to use it.
> 
> > Well, we already have the /* FALLTHRU */ etc. comments in most of
> > the
> > places.  Perhaps if we replace those comments just with
> > GCC_FALLTHRU,
> > a macro that expands to __builtin_fallthrough (); for GCC >= 7, or
> > to [[fallthrough]] for C++17, or nothing?
> > IMHO it doesn't make sense to keep both the gomp_fallthrough ();
> > macro and
> > /* FALLTHROUGH */ etc. comments in the source.
> 
> Yea, that's a possibility, though sometimes the comment explains why
> the
> fall through is desirable.

Is there no way to use the comment itself, somehow?  Looking over the
patches you had to do, it looks like using the comments themselves
would make it significantly easier for users to use this warning
without having to patch their code.  Of course this adds the
philosophical risk of making the content of the comment be significant,
for some meaning of "significant".

Brainstorming... how about looking for comments containing the
substrings "fall" and either "through" or "thru", case-insensitively?
This could be only done if we're about to emit a warning: maybe look
through the pertinent lines via the input.c interface?  Or maybe have
the preprocessor detect such comments during lexing (perhaps if the
warning is enabled), and store them somewhere... (maybe a bitmap of
source_location values within the line_table, or somesuch, giving the
locations of "fallthrough" comments).

I appreciate that my suggestions above are kludges, but maybe someone
else can think of a cleaner way to do it.

Dave

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:35         ` Jakub Jelinek
@ 2016-07-11 20:44           ` David Malcolm
  2016-07-11 20:50             ` Jakub Jelinek
  2016-07-12 13:57           ` NightStrike
  1 sibling, 1 reply; 77+ messages in thread
From: David Malcolm @ 2016-07-11 20:44 UTC (permalink / raw)
  To: Jakub Jelinek, Marek Polacek, Joseph S. Myers, Jason Merrill
  Cc: Andi Kleen, GCC Patches

On Mon, 2016-07-11 at 22:34 +0200, Jakub Jelinek wrote:
> On Mon, Jul 11, 2016 at 10:23:30PM +0200, Marek Polacek wrote:
> > On Mon, Jul 11, 2016 at 01:18:02PM -0700, Andi Kleen wrote:
> > > > I explained why supporting the classic lint style comment
> > > > wouldn't fly.
> > > 
> > > Not convincing, it worked fine for 30+ years of lints.
> > 
> > So how can the compiler handle
> > /* Never ever fall through here */
> > ?
> 
> It can't.  But it perhaps could handle a couple of documented most
> common
> comment styles, perhaps only if followed by break token, and turn say
> /* FALLTHROUGH */
> break

Presumably you mean "case" here?   A "break" token is surely the thing
we're *not* expecting, right?

> (and say:
> /* FALL THROUGH */
> /* FALLTHRU */
> /* FALL THRU */
> /*-fallthrough*/
> /* Fallthrough */
> /* Fall through */
> /* Fallthru */
> /* Fall thru */
> /* fallthrough */
> /* fall through */
> /* fallthru */
> /* fall thru */
> // FALLTHROUGH
> // FALL THROUGH
> // FALLTHRU
> // FALL THRU
> //-fallthrough
> // Fallthrough
> // Fall through
> // Fallthru
> // Fall thru
> // fallthrough
> // fall through
> // fallthru
> // fall thru
> )
> into:
> #pragma GCC fallthrough
> break
> and make sure that if the pragma appears outside of switch or say in
> if (...)
> #pragma GCC fallthrough
> break
> and similar spots, then it is actually ignored, rather than affecting
> the
> parsed code.
> Supporting also __builtin_fallthrough (); and [[fallthrough]] is
> desirable,
> the transformation of the above comments into the pragma should be
> controllable by some separate switch?

...or maybe we could detect such comments and store, say, a bitmap of
all source_location/location_t values at which we've seen a
"fallthrough" style comment, and then have the warning code query this
bitmap for a comment in the pertinent range.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:44           ` David Malcolm
@ 2016-07-11 20:50             ` Jakub Jelinek
  0 siblings, 0 replies; 77+ messages in thread
From: Jakub Jelinek @ 2016-07-11 20:50 UTC (permalink / raw)
  To: David Malcolm
  Cc: Marek Polacek, Joseph S. Myers, Jason Merrill, Andi Kleen, GCC Patches

On Mon, Jul 11, 2016 at 04:43:57PM -0400, David Malcolm wrote:
> On Mon, 2016-07-11 at 22:34 +0200, Jakub Jelinek wrote:
> > On Mon, Jul 11, 2016 at 10:23:30PM +0200, Marek Polacek wrote:
> > > On Mon, Jul 11, 2016 at 01:18:02PM -0700, Andi Kleen wrote:
> > > > > I explained why supporting the classic lint style comment
> > > > > wouldn't fly.
> > > > 
> > > > Not convincing, it worked fine for 30+ years of lints.
> > > 
> > > So how can the compiler handle
> > > /* Never ever fall through here */
> > > ?
> > 
> > It can't.  But it perhaps could handle a couple of documented most
> > common
> > comment styles, perhaps only if followed by break token, and turn say
> > /* FALLTHROUGH */
> > break
> 
> Presumably you mean "case" here?   A "break" token is surely the thing
> we're *not* expecting, right?

Sure, I meant case token.

> ...or maybe we could detect such comments and store, say, a bitmap of
> all source_location/location_t values at which we've seen a
> "fallthrough" style comment, and then have the warning code query this
> bitmap for a comment in the pertinent range.

It can be flag on the case token too.  The thing is if we care about
-save-temps, ccache, distcc and non-integrated preprocessing (I'm currently
trying to convince ccache to start using -fdirectives-only, but they don't
want to, see https://github.com/ccache/ccache/issues/93 for details).

	Jakub

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: java
  2016-07-11 19:54 ` Implement -Wswitch-fallthrough: java Marek Polacek
@ 2016-07-11 21:26   ` Tom Tromey
  0 siblings, 0 replies; 77+ messages in thread
From: Tom Tromey @ 2016-07-11 21:26 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

>>>>> "Marek" == Marek Polacek <polacek@redhat.com> writes:

Marek> +++ gcc/gcc/java/jcf-dump.c
Marek> @@ -926,6 +926,8 @@ print_constant (FILE *out, JCF *jcf, int index, int verbosity)
Marek>  	  if (verbosity > 0)
Marek>  	    fprintf (out, "Fieldref: %ld=", (long) JPOOL_USHORT2 (jcf, index));
Marek>  	  print_constant (out, jcf, JPOOL_USHORT2 (jcf, index), 0);
Marek> +	  /* XXX Really fallthru?  */
Marek> +	  gcc_fallthrough ();

I think this one is a bug.

Tom

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: libstdc++
  2016-07-11 19:58 ` Implement -Wswitch-fallthrough: libstdc++ Marek Polacek
@ 2016-07-11 22:18   ` Jonathan Wakely
  0 siblings, 0 replies; 77+ messages in thread
From: Jonathan Wakely @ 2016-07-11 22:18 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches, libstdc++

On 11 July 2016 at 20:57, Marek Polacek wrote:
>
> 2016-07-11  Marek Polacek  <polacek@redhat.com>
>
>         PR c/7652
>         * libsupc++/hash_bytes.cc: Use __builtin_fallthrough.
>
> diff --git gcc/libstdc++-v3/libsupc++/hash_bytes.cc gcc/libstdc++-v3/libsupc++/hash_bytes.cc
> index 2e5bbfa..818331f 100644
> --- gcc/libstdc++-v3/libsupc++/hash_bytes.cc
> +++ gcc/libstdc++-v3/libsupc++/hash_bytes.cc
> @@ -95,8 +95,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>        {
>        case 3:
>         hash ^= static_cast<unsigned char>(buf[2]) << 16;
> +       __builtin_fallthrough ();
>        case 2:
>         hash ^= static_cast<unsigned char>(buf[1]) << 8;
> +       __builtin_fallthrough ();
>        case 1:
>         hash ^= static_cast<unsigned char>(buf[0]);
>         hash *= m;

Nice to see this feature implemented!

The libstdc++ change is gladly approved with much rejoicing. Thanks.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: lto
  2016-07-11 19:58 ` Implement -Wswitch-fallthrough: lto Marek Polacek
@ 2016-07-12 10:23   ` Richard Biener
  2016-07-12 10:28     ` Marek Polacek
  0 siblings, 1 reply; 77+ messages in thread
From: Richard Biener @ 2016-07-12 10:23 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 9:58 PM, Marek Polacek <polacek@redhat.com> wrote:
> 2016-07-11  Marek Polacek  <polacek@redhat.com>
>
>         PR c/7652
>         * lto-plugin.c (lto_fallthrough): Define.
>         (parse_table_entry): Use it.
>
> diff --git gcc/lto-plugin/lto-plugin.c gcc/lto-plugin/lto-plugin.c
> index 51afc52..ffdf54a 100644
> --- gcc/lto-plugin/lto-plugin.c
> +++ gcc/lto-plugin/lto-plugin.c
> @@ -77,6 +77,12 @@ along with this program; see the file COPYING3.  If not see
>  # define O_BINARY 0
>  #endif
>
> +#if __GNUC__ >= 7
> +# define lto_fallthrough() __builtin_fallthrough ()
> +#else
> +# define lto_fallthrough()
> +#endif
> +
>  /* Segment name for LTO sections.  This is only used for Mach-O.
>     FIXME: This needs to be kept in sync with darwin.c.  */
>
> @@ -254,6 +260,7 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry,
>           break;
>         }
>      /* FALL-THROUGH.  */
> +    lto_fallthrough ();

This shows me that it would be nice to simply get this correct by
parsing comments...

I don't like __builtin_fallthrough () too much.

Richard.

>      case ss_uscore:
>        entry->name = concat ("_", p, NULL);
>        break;

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (25 preceding siblings ...)
  2016-07-11 20:28 ` NightStrike
@ 2016-07-12 10:27 ` Richard Biener
  2016-07-12 10:31   ` Marek Polacek
  2016-07-12 11:24 ` Bernd Schmidt
                   ` (2 subsequent siblings)
  29 siblings, 1 reply; 77+ messages in thread
From: Richard Biener @ 2016-07-12 10:27 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 9:43 PM, Marek Polacek <polacek@redhat.com> wrote:
> The switch fallthrough has been widely considered a design defect in C, a
> misfeature or, to use Marshall Cline's definition, evil.  The overwhelming
> majority of the time you don't want to fall through to the next case, but it is
> easy to forget to "break" at the end of the case, making this far too error
> prone.  Yet GCC (and probably other compilers, too) doesn't have the ability to
> warn in this case.  A feature request for such warning was opened back in 2002,
> but it's mostly been untouched since.  But then the [[fallthrough]] attribute was
> approved for C++17 [1], and that's what has got me to do all this.

I don't like this too much given the churn it requires in GCC itself.
If [[fallthrough]]
was approved for C++17 is there sth similar proposed for C?  Like a keyword
__Fallthrough?

Richard.

> The following series attempts to implement the fabled -Wswitch-fallthrough
> warning.  The warning would be quite easy to implement were it not for control
> statements, nested scopes, gotos, and such.  I took great pains to try to
> handle all of that before I succeeded in getting all the pieces in place.  So
> GCC ought to do the right thing for e.g.:
>
>   switch (n)
>     {
>     case 1:
>       if (n > 20)
>         break;
>       else if (n > 10)
>         {
>           foo (9);
>           __builtin_fallthrough ();
>         }
>       else
>         foo (8); // warn here
>     case 2:;
>     }
>
> Since approximately 3% of fall throughs are desirable, I added a new builtin,
> __builtin_fallthrough, that prevents the warning from occurring.  It can only
> be used in a switch; the compiler will issue an error otherwise.  The new C++
> attribute can then be implemented in terms of this builtin.  There was an idea
> floating around about not warning for /* FALLTHRU */ etc. comments but I
> rejected this after I'd spent time thinking about it: the preprocessor can't
> know that we're in a switch statement so we might reject valid programs, the
> "falls through" comments vary wildly, occur even in if-statements, etc.  The
> warning doesn't warn when the block is empty, e.g. on case 1: case 2: ...  The
> warning does, inevitably, trigger on Duff's devices.  Too bad.  I guess I'd
> suggest using #pragma GCC warning then.  (I think Perl uses the "continue"
> keyword for exactly this purpose -- an interesting idea...)
>
> After I'd completed the warning, I kicked off a bootstrap so as to add various
> gcc_fallthrough calls.  There were a good amount of them, as expected.  I also
> grepped various FALLTHRU/Falls through/...fall thru.../... comments in config/
> and added gcc_fallthroughs to make it easier for people.  Wherever I wasn't
> sure that the gcc_fallthrough was appropriate, I added an 'XXX' comment.  This
> must not be relied upon as I don't know most of the compiler code.  The same
> goes for relevant libraries where I introduced various gomp_fallthrough
> macros conditional on __GNUC__ (I'd tried to use a configure check but then
> decided I won't put up with all the vagaries of autoconf).
>
> This patch is accompanied by more than 2000 lines of new tests to get the
> warning covered though I'm sure folks will come up with other test cases
> that I hadn't considered (hi Martin S. ;).
>
> This warning is enabled by default for C/C++.  I was more inclined to put this
> into -Wall, but our common.opt machinery doesn't seem to allow that (ugh!).
> The clang version I have installed doesn't have this warning so I couldn't
> compare my implementation with others.
>
> I plan to plunge into the C++ [[fallthrough]] thingie after this core part is
> dealt with.
>
> Since the patch is too large, I split it into various parts, the core and then
> various __builtin_fallthrough additions.
>
> This patch has been tested on powerpc64le-unknown-linux-gnu, aarch64-linux-gnu,
> x86_64-redhat-linux, and also on powerpc-ibm-aix7.1.0.0, though due to PR71816
> I was unable to bootstrap.
>
> Thanks,
>
> [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0188r0.pdf
>
>         Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: lto
  2016-07-12 10:23   ` Richard Biener
@ 2016-07-12 10:28     ` Marek Polacek
  0 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-12 10:28 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches

On Tue, Jul 12, 2016 at 12:22:55PM +0200, Richard Biener wrote:
> > @@ -254,6 +260,7 @@ parse_table_entry (char *p, struct ld_plugin_symbol *entry,
> >           break;
> >         }
> >      /* FALL-THROUGH.  */
> > +    lto_fallthrough ();
> 
> This shows me that it would be nice to simply get this correct by
> parsing comments...
 
Yea, seems that became a prerequisite for moving this forward.  Not sure if
I'll be able to manage that, but let me try what Jakub and David suggested
(turn the commend into a pragma).

> I don't like __builtin_fallthrough () too much.

Understood.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 10:27 ` Richard Biener
@ 2016-07-12 10:31   ` Marek Polacek
  2016-07-12 15:59     ` Jeff Law
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-12 10:31 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches

On Tue, Jul 12, 2016 at 12:27:31PM +0200, Richard Biener wrote:
> On Mon, Jul 11, 2016 at 9:43 PM, Marek Polacek <polacek@redhat.com> wrote:
> > The switch fallthrough has been widely considered a design defect in C, a
> > misfeature or, to use Marshall Cline's definition, evil.  The overwhelming
> > majority of the time you don't want to fall through to the next case, but it is
> > easy to forget to "break" at the end of the case, making this far too error
> > prone.  Yet GCC (and probably other compilers, too) doesn't have the ability to
> > warn in this case.  A feature request for such warning was opened back in 2002,
> > but it's mostly been untouched since.  But then the [[fallthrough]] attribute was
> > approved for C++17 [1], and that's what has got me to do all this.
> 
> I don't like this too much given the churn it requires in GCC itself.
> If [[fallthrough]]
> was approved for C++17 is there sth similar proposed for C?  Like a keyword
> __Fallthrough?

I don't think there is.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (26 preceding siblings ...)
  2016-07-12 10:27 ` Richard Biener
@ 2016-07-12 11:24 ` Bernd Schmidt
  2016-07-12 11:36   ` Marek Polacek
  2016-07-12 16:10 ` Jeff Law
  2016-07-12 21:00 ` Martin Sebor
  29 siblings, 1 reply; 77+ messages in thread
From: Bernd Schmidt @ 2016-07-12 11:24 UTC (permalink / raw)
  To: Marek Polacek, GCC Patches

On 07/11/2016 09:43 PM, Marek Polacek wrote:
> This warning is enabled by default for C/C++.  I was more inclined to put this
> into -Wall, but our common.opt machinery doesn't seem to allow that (ugh!).

Add me to the list of folks opposed to enabling this unconditionally or 
as part of any other -W flag. The false positive rate would be enormous 
as shown by your patch series.


Bernd

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 11:24 ` Bernd Schmidt
@ 2016-07-12 11:36   ` Marek Polacek
  0 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-12 11:36 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

On Tue, Jul 12, 2016 at 01:24:15PM +0200, Bernd Schmidt wrote:
> On 07/11/2016 09:43 PM, Marek Polacek wrote:
> > This warning is enabled by default for C/C++.  I was more inclined to put this
> > into -Wall, but our common.opt machinery doesn't seem to allow that (ugh!).
> 
> Add me to the list of folks opposed to enabling this unconditionally or as
> part of any other -W flag. The false positive rate would be enormous as
> shown by your patch series.

I feel that, given all the pushback, I have to explain that it was never my
intent to enable this by default.  I was thinking of -Wall/-Wextra (given
-Wmisleading-indentation is in -Wall).  It's been enabled by default only to
get better testing coverage when doing various bootstraps and I failed to
move it to -Wextra, or even out of it.

As discussed elsewhere, I/we'll have to suppress the warning for various
"falls through" comments, which should cut the verbosity substantially.
Whether to put this warning into -Wall/-Wextra when that's done is still
to be discussed, but we all know that if a warning is out of -Wall/-Wextra,
no one will use it.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:35         ` Jakub Jelinek
  2016-07-11 20:44           ` David Malcolm
@ 2016-07-12 13:57           ` NightStrike
  2016-07-12 14:08             ` Marek Polacek
  1 sibling, 1 reply; 77+ messages in thread
From: NightStrike @ 2016-07-12 13:57 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Marek Polacek, Joseph S. Myers, Jason Merrill, Andi Kleen, GCC Patches

On Mon, Jul 11, 2016 at 4:34 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Mon, Jul 11, 2016 at 10:23:30PM +0200, Marek Polacek wrote:
>> On Mon, Jul 11, 2016 at 01:18:02PM -0700, Andi Kleen wrote:
>> > > I explained why supporting the classic lint style comment wouldn't fly.
>> >
>> > Not convincing, it worked fine for 30+ years of lints.
>>
>> So how can the compiler handle
>> /* Never ever fall through here */
>> ?
>
> It can't.  But it perhaps could handle a couple of documented most common
> comment styles, perhaps only if followed by break token, and turn say
> /* FALLTHROUGH */
> break
> (and say:
> /* FALL THROUGH */
> /* FALLTHRU */
> /* FALL THRU */
> /*-fallthrough*/
> /* Fallthrough */
> /* Fall through */
> /* Fallthru */
> /* Fall thru */
> /* fallthrough */
> /* fall through */
> /* fallthru */
> /* fall thru */
> // FALLTHROUGH
> // FALL THROUGH
> // FALLTHRU
> // FALL THRU
> //-fallthrough
> // Fallthrough
> // Fall through
> // Fallthru
> // Fall thru
> // fallthrough
> // fall through
> // fallthru
> // fall thru

From http://security.coverity.com/blog/2013/Sep/gimme-a-break.html:

We also suppress a case label if there is a comment that matches
[^#]fall.?thro?u, even if it's not on the last line.

Maybe that's enough?

The page has other exclusions that might be desirable.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 13:57           ` NightStrike
@ 2016-07-12 14:08             ` Marek Polacek
  2016-07-12 14:14               ` Jakub Jelinek
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-12 14:08 UTC (permalink / raw)
  To: NightStrike
  Cc: Jakub Jelinek, Joseph S. Myers, Jason Merrill, Andi Kleen, GCC Patches

On Tue, Jul 12, 2016 at 09:57:01AM -0400, NightStrike wrote:
> From http://security.coverity.com/blog/2013/Sep/gimme-a-break.html:
 
Thanks, this is useful.

> We also suppress a case label if there is a comment that matches
> [^#]fall.?thro?u, even if it's not on the last line.

Our current plan is to handle sth like
[ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]*
[ \t]*Fall(s | |-)?[Tt]hr(ough|u)\.?[ \t]*
[ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]*

> Maybe that's enough?

We'll see ;).

> The page has other exclusions that might be desirable.

Yea, I wonder how do they recognize Duff's device, in particular.
But I think it shouldn't be a big deal if we warn on them.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-11 19:59 ` Implement -Wswitch-fallthrough: rs6000 Marek Polacek
  2016-07-11 20:36   ` Bruce Korb
@ 2016-07-12 14:11   ` Segher Boessenkool
  2016-07-12 14:20     ` Marek Polacek
  1 sibling, 1 reply; 77+ messages in thread
From: Segher Boessenkool @ 2016-07-12 14:11 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

Hi Marek,

On Mon, Jul 11, 2016 at 09:59:39PM +0200, Marek Polacek wrote:
> 2016-07-11  Marek Polacek  <polacek@redhat.com>
> 
> 	PR c/7652
> 	* config/rs6000/rs6000.c (rs6000_builtin_vectorized_libmass): Likewise.

Likewise?  Like what?  :-)

> --- gcc/gcc/config/rs6000/rs6000.c
> +++ gcc/gcc/config/rs6000/rs6000.c
> @@ -5459,6 +5459,7 @@ rs6000_builtin_vectorized_libmass (combined_fn fn, tree type_out,
>      CASE_CFN_POW:
>        n_args = 2;
>        /* fall through */
> +      gcc_fallthrough ();

As mentioned elsewhere, please remove comments saying just "fall through"
when adding the new statement.

> @@ -14398,6 +14401,8 @@ altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
>        break;
>      case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
>        icode = CODE_FOR_vector_altivec_load_v2di;
> +      /* XXX Really?  */
> +      gcc_fallthrough ();
>      case ALTIVEC_BUILTIN_LD_INTERNAL_1ti:
>        icode = CODE_FOR_vector_altivec_load_v1ti;
>        break;

Yeah, that's a bug obviously.  We'll fix it.

> @@ -30191,6 +30200,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
>                  && (INSN_CODE (dep_insn) >= 0)
>                  && (get_attr_type (dep_insn) == TYPE_MFFGPR))
>                return 2;
> +	    gcc_fallthrough ();
>  
>            default:
>              break;

Better to put an extra "break" here.  That is usually true if the next
statement (after one or more labels) is a break.

> --- gcc/gcc/config/rs6000/rs6000.md
> +++ gcc/gcc/config/rs6000/rs6000.md
> @@ -8094,6 +8094,8 @@
>      case 0:
>        if (TARGET_STRING)
>          return \"stswi %1,%P0,16\";
> +      /* XXX Really fallthru?  */
> +      gcc_fallthrough ();
>      case 1:
>        return \"#\";

Yes, really :-)  This code is probably better written without a switch
statement at all, but oh well.

I like the new warning, and I'd like to see it in -Wextra.  It finds real
problems that are easy to correct.  It does trigger a lot on existing code,
but -Wextra is not -Wall.


Segher

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 14:08             ` Marek Polacek
@ 2016-07-12 14:14               ` Jakub Jelinek
  2016-07-12 14:22                 ` Bernd Schmidt
  0 siblings, 1 reply; 77+ messages in thread
From: Jakub Jelinek @ 2016-07-12 14:14 UTC (permalink / raw)
  To: Marek Polacek
  Cc: NightStrike, Joseph S. Myers, Jason Merrill, Andi Kleen, GCC Patches

On Tue, Jul 12, 2016 at 04:08:02PM +0200, Marek Polacek wrote:
> On Tue, Jul 12, 2016 at 09:57:01AM -0400, NightStrike wrote:
> > From http://security.coverity.com/blog/2013/Sep/gimme-a-break.html:
>  
> Thanks, this is useful.
> 
> > We also suppress a case label if there is a comment that matches
> > [^#]fall.?thro?u, even if it's not on the last line.
> 
> Our current plan is to handle sth like
> [ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]*
> [ \t]*Fall(s | |-)?[Tt]hr(ough|u)\.?[ \t]*
> [ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]*

And
/*-fallthrough*/
/*@fallthrough@*/
//-fallthrough
//@fallthrough@
(those 4 as standardized lint comments only in lowercase, the
above regexps are meant to match the whole comment content, i.e.
everything between /* and */ or // and \n.

	Jakub

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-12 14:11   ` Segher Boessenkool
@ 2016-07-12 14:20     ` Marek Polacek
  2016-07-12 14:42       ` Bernd Schmidt
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-12 14:20 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: GCC Patches

On Tue, Jul 12, 2016 at 09:10:54AM -0500, Segher Boessenkool wrote:
> Hi Marek,
> 
> On Mon, Jul 11, 2016 at 09:59:39PM +0200, Marek Polacek wrote:
> > 2016-07-11  Marek Polacek  <polacek@redhat.com>
> > 
> > 	PR c/7652
> > 	* config/rs6000/rs6000.c (rs6000_builtin_vectorized_libmass): Likewise.
> 
> Likewise?  Like what?  :-)
 
Yikes, I goofed this up when spliting the big patch.

> > --- gcc/gcc/config/rs6000/rs6000.c
> > +++ gcc/gcc/config/rs6000/rs6000.c
> > @@ -5459,6 +5459,7 @@ rs6000_builtin_vectorized_libmass (combined_fn fn, tree type_out,
> >      CASE_CFN_POW:
> >        n_args = 2;
> >        /* fall through */
> > +      gcc_fallthrough ();
> 
> As mentioned elsewhere, please remove comments saying just "fall through"
> when adding the new statement.
 
Yep, I'm working on this.

> > @@ -14398,6 +14401,8 @@ altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
> >        break;
> >      case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
> >        icode = CODE_FOR_vector_altivec_load_v2di;
> > +      /* XXX Really?  */
> > +      gcc_fallthrough ();
> >      case ALTIVEC_BUILTIN_LD_INTERNAL_1ti:
> >        icode = CODE_FOR_vector_altivec_load_v1ti;
> >        break;
> 
> Yeah, that's a bug obviously.  We'll fix it.
 
Great.

> > @@ -30191,6 +30200,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
> >                  && (INSN_CODE (dep_insn) >= 0)
> >                  && (get_attr_type (dep_insn) == TYPE_MFFGPR))
> >                return 2;
> > +	    gcc_fallthrough ();
> >  
> >            default:
> >              break;
> 
> Better to put an extra "break" here.  That is usually true if the next
> statement (after one or more labels) is a break.
 
The next version of the warning should recognize this scenario and shouldn't
warn, thus no change will be needed.

> > --- gcc/gcc/config/rs6000/rs6000.md
> > +++ gcc/gcc/config/rs6000/rs6000.md
> > @@ -8094,6 +8094,8 @@
> >      case 0:
> >        if (TARGET_STRING)
> >          return \"stswi %1,%P0,16\";
> > +      /* XXX Really fallthru?  */
> > +      gcc_fallthrough ();
> >      case 1:
> >        return \"#\";
> 
> Yes, really :-)  This code is probably better written without a switch
> statement at all, but oh well.
 
Yeah, or it at least should have a comment.

> I like the new warning, and I'd like to see it in -Wextra.  It finds real
> problems that are easy to correct.  It does trigger a lot on existing code,
> but -Wextra is not -Wall.

The next version of the warning should be significantly less verbose, because
it will take "falls through" comments into account.

Thanks.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 14:14               ` Jakub Jelinek
@ 2016-07-12 14:22                 ` Bernd Schmidt
  2016-07-12 14:36                   ` Jakub Jelinek
  0 siblings, 1 reply; 77+ messages in thread
From: Bernd Schmidt @ 2016-07-12 14:22 UTC (permalink / raw)
  To: Jakub Jelinek, Marek Polacek
  Cc: NightStrike, Joseph S. Myers, Jason Merrill, Andi Kleen, GCC Patches



On 07/12/2016 04:14 PM, Jakub Jelinek wrote:
> On Tue, Jul 12, 2016 at 04:08:02PM +0200, Marek Polacek wrote:
>> On Tue, Jul 12, 2016 at 09:57:01AM -0400, NightStrike wrote:
>>> From http://security.coverity.com/blog/2013/Sep/gimme-a-break.html:
>>
>> Thanks, this is useful.
>>
>>> We also suppress a case label if there is a comment that matches
>>> [^#]fall.?thro?u, even if it's not on the last line.
>>
>> Our current plan is to handle sth like
>> [ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]*
>> [ \t]*Fall(s | |-)?[Tt]hr(ough|u)\.?[ \t]*
>> [ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]*
>
> And
> /*-fallthrough*/
> /*@fallthrough@*/
> //-fallthrough
> //@fallthrough@
> (those 4 as standardized lint comments only in lowercase, the
> above regexps are meant to match the whole comment content, i.e.
> everything between /* and */ or // and \n.

I think this approach is doomed to fail, because it takes only one 
language into account, and fails with preprocessed sources.


Bernd

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 14:22                 ` Bernd Schmidt
@ 2016-07-12 14:36                   ` Jakub Jelinek
  0 siblings, 0 replies; 77+ messages in thread
From: Jakub Jelinek @ 2016-07-12 14:36 UTC (permalink / raw)
  To: Bernd Schmidt
  Cc: Marek Polacek, NightStrike, Joseph S. Myers, Jason Merrill,
	Andi Kleen, GCC Patches

On Tue, Jul 12, 2016 at 04:22:30PM +0200, Bernd Schmidt wrote:
> On 07/12/2016 04:14 PM, Jakub Jelinek wrote:
> >On Tue, Jul 12, 2016 at 04:08:02PM +0200, Marek Polacek wrote:
> >>On Tue, Jul 12, 2016 at 09:57:01AM -0400, NightStrike wrote:
> >>>From http://security.coverity.com/blog/2013/Sep/gimme-a-break.html:
> >>
> >>Thanks, this is useful.
> >>
> >>>We also suppress a case label if there is a comment that matches
> >>>[^#]fall.?thro?u, even if it's not on the last line.
> >>
> >>Our current plan is to handle sth like
> >>[ \t]*FALL(S | |-)?THR(OUGH|U)\.?[ \t]*
> >>[ \t]*Fall(s | |-)?[Tt]hr(ough|u)\.?[ \t]*
> >>[ \t]*fall(s | |-)?thr(ough|u)\.?[ \t]*
> >
> >And
> >/*-fallthrough*/
> >/*@fallthrough@*/
> >//-fallthrough
> >//@fallthrough@
> >(those 4 as standardized lint comments only in lowercase, the
> >above regexps are meant to match the whole comment content, i.e.
> >everything between /* and */ or // and \n.
> 
> I think this approach is doomed to fail, because it takes only one language
> into account, and fails with preprocessed sources.

It takes C/C++/ObjC/ObjC++ into account (I believe Go has fallthrough
keyword in the language, but perhaps it handles everything in the FE).
For C++11, people can use [[gnu::fallthrough]], for
C++17 [[fallthrough]] (standardized), and we are
going to offer some other way in all cases (__builtin_fallthrough () and/or
#pragma GCC fallthrough).  The parsing of comments is just an attempt to
handle the most common case in user-friendly way.

For non-integrated preprocessing, the options are either let people
use some other way than comment, recommend them to use -C or -CC,
add some new option like -C/-CC that emits during preprocessing
standardized /*FALLTHROUGH*/ comments only when before case/default
keywords or identifier followed by semicolon into the -E output,
or emitting #pragma GCC fallthrough in that case instead.

As usual for warnings, changes are contentious, on the other side as could
be seen in the patchset Marek posted it discovered multiple real bugs in GCC
already.

	Jakub

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-12 14:20     ` Marek Polacek
@ 2016-07-12 14:42       ` Bernd Schmidt
  2016-07-12 14:45         ` Jakub Jelinek
  0 siblings, 1 reply; 77+ messages in thread
From: Bernd Schmidt @ 2016-07-12 14:42 UTC (permalink / raw)
  To: Marek Polacek, Segher Boessenkool; +Cc: GCC Patches

On 07/12/2016 04:19 PM, Marek Polacek wrote:
>
>>> @@ -30191,6 +30200,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
>>>                  && (INSN_CODE (dep_insn) >= 0)
>>>                  && (get_attr_type (dep_insn) == TYPE_MFFGPR))
>>>                return 2;
>>> +	    gcc_fallthrough ();
>>>
>>>            default:
>>>              break;
>>
>> Better to put an extra "break" here.  That is usually true if the next
>> statement (after one or more labels) is a break.
>
> The next version of the warning should recognize this scenario and shouldn't
> warn, thus no change will be needed.

Actually I think this is one case where you could unconditionally warn - 
falling through to a break seems like bad practice, it invites errors 
when someone places new code before the break.


Bernd

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-12 14:42       ` Bernd Schmidt
@ 2016-07-12 14:45         ` Jakub Jelinek
  0 siblings, 0 replies; 77+ messages in thread
From: Jakub Jelinek @ 2016-07-12 14:45 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: Marek Polacek, Segher Boessenkool, GCC Patches

On Tue, Jul 12, 2016 at 04:42:21PM +0200, Bernd Schmidt wrote:
> On 07/12/2016 04:19 PM, Marek Polacek wrote:
> >
> >>>@@ -30191,6 +30200,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx link, rtx_insn *dep_insn, int cost)
> >>>                 && (INSN_CODE (dep_insn) >= 0)
> >>>                 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
> >>>               return 2;
> >>>+	    gcc_fallthrough ();
> >>>
> >>>           default:
> >>>             break;
> >>
> >>Better to put an extra "break" here.  That is usually true if the next
> >>statement (after one or more labels) is a break.
> >
> >The next version of the warning should recognize this scenario and shouldn't
> >warn, thus no change will be needed.
> 
> Actually I think this is one case where you could unconditionally warn -
> falling through to a break seems like bad practice, it invites errors when
> someone places new code before the break.

You get the warning when you place the new code there.
I think the falling into a case with only break; or falling into default:;}
is harmless.

	Jakub

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 10:31   ` Marek Polacek
@ 2016-07-12 15:59     ` Jeff Law
  2016-07-12 16:04       ` Marek Polacek
  0 siblings, 1 reply; 77+ messages in thread
From: Jeff Law @ 2016-07-12 15:59 UTC (permalink / raw)
  To: Marek Polacek, Richard Biener; +Cc: GCC Patches

On 07/12/2016 04:30 AM, Marek Polacek wrote:
> On Tue, Jul 12, 2016 at 12:27:31PM +0200, Richard Biener wrote:
>> On Mon, Jul 11, 2016 at 9:43 PM, Marek Polacek <polacek@redhat.com> wrote:
>>> The switch fallthrough has been widely considered a design defect in C, a
>>> misfeature or, to use Marshall Cline's definition, evil.  The overwhelming
>>> majority of the time you don't want to fall through to the next case, but it is
>>> easy to forget to "break" at the end of the case, making this far too error
>>> prone.  Yet GCC (and probably other compilers, too) doesn't have the ability to
>>> warn in this case.  A feature request for such warning was opened back in 2002,
>>> but it's mostly been untouched since.  But then the [[fallthrough]] attribute was
>>> approved for C++17 [1], and that's what has got me to do all this.
>>
>> I don't like this too much given the churn it requires in GCC itself.
>> If [[fallthrough]]
>> was approved for C++17 is there sth similar proposed for C?  Like a keyword
>> __Fallthrough?
>
> I don't think there is.
But maybe there should be ;-)  We've got a couple folks (Martin S and 
Carlos) that participate in that standards body and could propose it.

jeff

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 15:59     ` Jeff Law
@ 2016-07-12 16:04       ` Marek Polacek
  2016-07-12 17:40         ` Martin Sebor
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-12 16:04 UTC (permalink / raw)
  To: Jeff Law; +Cc: Richard Biener, GCC Patches, Martin Sebor

On Tue, Jul 12, 2016 at 09:59:37AM -0600, Jeff Law wrote:
> On 07/12/2016 04:30 AM, Marek Polacek wrote:
> > On Tue, Jul 12, 2016 at 12:27:31PM +0200, Richard Biener wrote:
> > > If [[fallthrough]]
> > > was approved for C++17 is there sth similar proposed for C?  Like a keyword
> > > __Fallthrough?
> > 
> > I don't think there is.
> But maybe there should be ;-)  We've got a couple folks (Martin S and
> Carlos) that participate in that standards body and could propose it.

I think you're right.  I'd happily participate in proposing / implementing
__Fallthrough.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (27 preceding siblings ...)
  2016-07-12 11:24 ` Bernd Schmidt
@ 2016-07-12 16:10 ` Jeff Law
  2016-07-28 17:04   ` Marek Polacek
  2016-07-12 21:00 ` Martin Sebor
  29 siblings, 1 reply; 77+ messages in thread
From: Jeff Law @ 2016-07-12 16:10 UTC (permalink / raw)
  To: Marek Polacek, GCC Patches

On 07/11/2016 01:43 PM, Marek Polacek wrote:
> The switch fallthrough has been widely considered a design defect in C, a
> misfeature or, to use Marshall Cline's definition, evil.  The overwhelming
> majority of the time you don't want to fall through to the next case, but it is
> easy to forget to "break" at the end of the case, making this far too error
> prone.  Yet GCC (and probably other compilers, too) doesn't have the ability to
> warn in this case.  A feature request for such warning was opened back in 2002,
> but it's mostly been untouched since.  But then the [[fallthrough]] attribute was
> approved for C++17 [1], and that's what has got me to do all this.
[ ... ]
This is going to be rather contentious.  So as we're hashing through 
that, can you split off the patches which fix bugs rather than those 
which add fallthru annotations?
jeff

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 16:04       ` Marek Polacek
@ 2016-07-12 17:40         ` Martin Sebor
  2016-07-12 17:52           ` Marek Polacek
  0 siblings, 1 reply; 77+ messages in thread
From: Martin Sebor @ 2016-07-12 17:40 UTC (permalink / raw)
  To: Marek Polacek, Jeff Law; +Cc: Richard Biener, GCC Patches, Martin Sebor

On 07/12/2016 10:04 AM, Marek Polacek wrote:
> On Tue, Jul 12, 2016 at 09:59:37AM -0600, Jeff Law wrote:
>> On 07/12/2016 04:30 AM, Marek Polacek wrote:
>>> On Tue, Jul 12, 2016 at 12:27:31PM +0200, Richard Biener wrote:
>>>> If [[fallthrough]]
>>>> was approved for C++17 is there sth similar proposed for C?  Like a keyword
>>>> __Fallthrough?
>>>
>>> I don't think there is.
>> But maybe there should be ;-)  We've got a couple folks (Martin S and
>> Carlos) that participate in that standards body and could propose it.
>
> I think you're right.  I'd happily participate in proposing / implementing
> __Fallthrough.

Given that the C++ attribute has been approved for C++ 17 I think
it would make sense to consider its equivalent for C2X.  I can help
you put a proposal together for the upcoming C meeting in October.

Martin

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 17:40         ` Martin Sebor
@ 2016-07-12 17:52           ` Marek Polacek
  0 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-12 17:52 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jeff Law, Richard Biener, GCC Patches, Martin Sebor

On Tue, Jul 12, 2016 at 11:40:01AM -0600, Martin Sebor wrote:
> On 07/12/2016 10:04 AM, Marek Polacek wrote:
> > On Tue, Jul 12, 2016 at 09:59:37AM -0600, Jeff Law wrote:
> > > On 07/12/2016 04:30 AM, Marek Polacek wrote:
> > > > On Tue, Jul 12, 2016 at 12:27:31PM +0200, Richard Biener wrote:
> > > > > If [[fallthrough]]
> > > > > was approved for C++17 is there sth similar proposed for C?  Like a keyword
> > > > > __Fallthrough?
> > > > 
> > > > I don't think there is.
> > > But maybe there should be ;-)  We've got a couple folks (Martin S and
> > > Carlos) that participate in that standards body and could propose it.
> > 
> > I think you're right.  I'd happily participate in proposing / implementing
> > __Fallthrough.
> 
> Given that the C++ attribute has been approved for C++ 17 I think
> it would make sense to consider its equivalent for C2X.  I can help
> you put a proposal together for the upcoming C meeting in October.

Sounds good.  I think by that time the warning will have been committed
and tested and so we should have enough time for that.  Thanks Martin.  

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
                   ` (28 preceding siblings ...)
  2016-07-12 16:10 ` Jeff Law
@ 2016-07-12 21:00 ` Martin Sebor
  2016-07-28 17:03   ` Marek Polacek
  29 siblings, 1 reply; 77+ messages in thread
From: Martin Sebor @ 2016-07-12 21:00 UTC (permalink / raw)
  To: Marek Polacek, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 2476 bytes --]

> This patch is accompanied by more than 2000 lines of new tests to get the
> warning covered though I'm sure folks will come up with other test cases
> that I hadn't considered (hi Martin S. ;).
>
> This warning is enabled by default for C/C++.  I was more inclined to put this
> into -Wall, but our common.opt machinery doesn't seem to allow that (ugh!).
> The clang version I have installed doesn't have this warning so I couldn't
> compare my implementation with others.
>
> I plan to plunge into the C++ [[fallthrough]] thingie after this core part is
> dealt with.

I think this is a useful feature though like others I'm not
entirely sure that a built-in is the right interface.  I think
I would find a pragma or an attribute preferable.  At a minimum,
it would obviate some questions raised by my testing (i.e.,
whether the built-in be accepted when an attribute would
otherwise not be syntactically allowed).

I applied the core patch and ran a few experiments with it on
the assumption that __builtin_fallthrough() should behave roughly
correspondingly to [[fallthrough]].  I.e., be rejected where
[[fallthrough]] is rejected (but where attributes are otherwise
valid) and be accepted where the latter is accepted.  This may
not be intended but the text added to the manual is too vague
to tell.  I also compared the results to Clang's [[fallthrough]]
to make sure I wasn't missing something (or too much).

I ran into a few of what seems like subtle bugs or limitations
some of which I'm not sure are going to be solvable in the middle
end (at least not after the control flow graph has been built)
because by the time the middle end sees the code (certainly by
the time it gets to expansion) some of it has been eliminated.
An illustrative example of this class of problems might be this
function:

   void f (void)
   {
     if (0) __builtin_fallthrough ();   // never diagnosed

     int i = 0;
     if (i) __builtin_fallthrough ();   // not diagnosed with -O
   }

With the built-in replaced by [[fallthrough]] Clang diagnoses
both of these.

This may be an okay limitation for __builtin_fallthrough since
it's GCC-specific, but it won't do for the C++ attribute or for
the C attribute if one is added with matching constraints.

The tests I tried are in the attached file.  Most of them are
edge cases but some I think point out more serious problems
(the checker getting confused/disabled by a prior switch
statement).

Hopefully this will be useful.

Martin

[-- Attachment #2: t.c --]
[-- Type: text/plain, Size: 2053 bytes --]

#ifdef __clang__
#  define FALLTHROUGH [[fallthrough]]
#  define __builtin_fallthrough() (void)0
#else
#  define FALLTHROUGH __builtin_fallthrough ()
#endif

void f0 (void)
{
  // This would be an invalid [[fallthrough]] and GCC rejects it
  // as expected with:
  //   error: invalid use of '__builtin_fallthrough ()'
  FALLTHROUGH;

  {
    // This would be invalid [[fallthrough]] but is silently accepted 
    // by GCC.
    0 ? __builtin_fallthrough () : (void)0;
  }
  {
    switch (0)
      // This is invalid with [[fallthrough]] because there's no
      // preceding statement within the switch statement, and no
      // subsequent one.  Clang rejects it but GCC silently accepts
      // it (it issues -Wswitch-unreachable).
      FALLTHROUGH;
  }

  {
    // This is invalid but GCC gives:
    //   warning: not preceding a label
    // It seems that it should give an error like in the first case
    // above.  I suspect it's confused by the preceding switch.
    // Clang gives an error.
    FALLTHROUGH;
  }
}

void f1 (void)
{
  {
    switch (0)
      // This also seems invalid because there is no preceding
      // statement and no subsequent case-labeled statement but
      // GCC silently accepts it (as does Clang).  It seems that
      // GCC gets tricked by the A label.
      default: FALLTHROUGH; A: ;
  }

  {
    // Unlike the same block at the end of f0 this is an error
    // as it should be`.
    FALLTHROUGH;
  }
}

void f2 (int i)
{
  {
    switch (i)
    {
      case 0:
        // Both of the following are invalid with [[fallthrough]]
        // because neither is followed by a case-labeled statement.
        // GCC only only rejects the second of the two.  Clang
        // accepts both.
        FALLTHROUGH;
        FALLTHROUGH;
    }
  }
}

// The following function triggers an ICE.
void f3 (void)
{
  {
    // Invalid but without the ICE silently accepted by GCC.
    int i = 0;
    if (i) __builtin_fallthrough ();
  }
  {
    switch (0)
      __builtin_fallthrough ();
  }

  __builtin_fallthrough ();
}


^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-11 20:28 ` NightStrike
@ 2016-07-13 18:16   ` Marek Polacek
  2016-07-13 18:39     ` Marc Glisse
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-13 18:16 UTC (permalink / raw)
  To: NightStrike; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 04:28:32PM -0400, NightStrike wrote:
> On Mon, Jul 11, 2016 at 3:43 PM, Marek Polacek <polacek@redhat.com> wrote:
> > But then the [[fallthrough]] attribute was
> > approved for C++17 [1], and that's what has got me to do all this.
> >  ...
> > I added a new builtin,
> > __builtin_fallthrough, that prevents the warning from occurring.  It can only
> > be used in a switch; the compiler will issue an error otherwise.  The new C++
> > attribute can then be implemented in terms of this builtin.
> 
> This is a stupid question I'm sure, but if C++ can have the attribute
> version, why can't C have __attribute__((fallthrough)) ?

We could, but why?  I already added __builtin_fallthrough() and
__attribute__((fallthrough)) would just be turned into that.  C++17 adds the
fallthrough attribute for a null statement, so we need to implement that, but
again I expect that I just turn that to __builtin_fallthrough().  We plan to
add __Fallthrough to C, but that is a long way off.  Does
"__attribute__((fallthrough));" have any advantages over "__builtin_fallthrough()"?

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-11 20:36   ` Bruce Korb
@ 2016-07-13 18:23     ` Marek Polacek
  2016-07-13 18:31       ` Bruce Korb
  2016-07-13 22:36       ` Bruce Korb
  0 siblings, 2 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-13 18:23 UTC (permalink / raw)
  To: Bruce Korb; +Cc: GCC Patches

On Mon, Jul 11, 2016 at 01:36:02PM -0700, Bruce Korb wrote:
> I'm curious about this.  In the process of developing a code analysis
> tool, I found some GCC code that was, basically:
> 
> switch (v) {
> case 0:
>   if (e) {
>     do_something();
>   } else {
> case 1:
>     do_something_else();
>   }
> }
 
Yeah, I saw this too, somewhere in the C++ FE.

> Does this patch mean that the above got fixed?  I mean, if you're
> going to fret over linguistic tags to make falling through explicit,
> it would seem the above code is pretty sore-thumby, yes?

My current implementation warns here, but the warning can be suppressed
by adding /* FALLTHRU */ or __builtin_fallthrough(); before the
do_something_else() line.

Does that answer your question?

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-13 18:23     ` Marek Polacek
@ 2016-07-13 18:31       ` Bruce Korb
  2016-07-13 18:40         ` Marek Polacek
  2016-07-13 22:36       ` Bruce Korb
  1 sibling, 1 reply; 77+ messages in thread
From: Bruce Korb @ 2016-07-13 18:31 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

> On Mon, Jul 11, 2016 at 01:36:02PM -0700, Bruce Korb wrote:
> [[putrid code deleted]]
>> Does this patch mean that the above got fixed?  I mean, if you're
>> going to fret over linguistic tags to make falling through explicit,
>> it would seem the above code is pretty sore-thumby, yes?
>
> My current implementation warns here, but the warning can be suppressed
> by adding /* FALLTHRU */ or __builtin_fallthrough(); before the
> do_something_else() line.
>
> Does that answer your question?

Not in a satisfying way. :)  I understand that syntactically, you can
drop a "case" in wherever you can drop a statement label.  That
doesn't mean you should.  Since I wasn't fixing GCC code, I just
rolled my eyes and moved on.  However, if the code is going to be
changed, then contortions like that ought to be addressed.  Both for
aesthetics and for code clarity.

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-13 18:16   ` Marek Polacek
@ 2016-07-13 18:39     ` Marc Glisse
  2016-07-13 18:47       ` Marek Polacek
  0 siblings, 1 reply; 77+ messages in thread
From: Marc Glisse @ 2016-07-13 18:39 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On Wed, 13 Jul 2016, Marek Polacek wrote:

> Does "__attribute__((fallthrough));" have any advantages over 
> "__builtin_fallthrough()"?

Not a strong argument, but compilers that don't know the construct will 
give an error on the builtin, and just a warning on the attribute (and 
ignore the comment, which makes both other versions less relevant).

Unrelated question: are there cases where __builtin_fallthrough() has any 
impact on code generation?

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-13 18:31       ` Bruce Korb
@ 2016-07-13 18:40         ` Marek Polacek
  2016-07-13 18:48           ` Bruce Korb
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-13 18:40 UTC (permalink / raw)
  To: Bruce Korb; +Cc: GCC Patches

On Wed, Jul 13, 2016 at 11:30:34AM -0700, Bruce Korb wrote:
> > On Mon, Jul 11, 2016 at 01:36:02PM -0700, Bruce Korb wrote:
> > [[putrid code deleted]]
> >> Does this patch mean that the above got fixed?  I mean, if you're
> >> going to fret over linguistic tags to make falling through explicit,
> >> it would seem the above code is pretty sore-thumby, yes?
> >
> > My current implementation warns here, but the warning can be suppressed
> > by adding /* FALLTHRU */ or __builtin_fallthrough(); before the
> > do_something_else() line.
> >
> > Does that answer your question?
> 
> Not in a satisfying way. :)  I understand that syntactically, you can

Ah, sorry.

> drop a "case" in wherever you can drop a statement label.  That
> doesn't mean you should.  Since I wasn't fixing GCC code, I just
> rolled my eyes and moved on.  However, if the code is going to be
> changed, then contortions like that ought to be addressed.  Both for
> aesthetics and for code clarity.

Most likely what you saw was in cxx_pretty_printer::declaration_specifiers.
I will have to do something about this, either add /* FALLTHRU */ or rewrite
the code slightly, as you suggest.  But that will involve duplicating the
c_pretty_printer::declaration_specifiers (t);
line, so some people might be against it.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-13 18:39     ` Marc Glisse
@ 2016-07-13 18:47       ` Marek Polacek
  2016-07-13 19:05         ` Marc Glisse
  0 siblings, 1 reply; 77+ messages in thread
From: Marek Polacek @ 2016-07-13 18:47 UTC (permalink / raw)
  To: Marc Glisse; +Cc: GCC Patches

On Wed, Jul 13, 2016 at 08:39:28PM +0200, Marc Glisse wrote:
> On Wed, 13 Jul 2016, Marek Polacek wrote:
> 
> > Does "__attribute__((fallthrough));" have any advantages over
> > "__builtin_fallthrough()"?
> 
> Not a strong argument, but compilers that don't know the construct will give
> an error on the builtin, and just a warning on the attribute (and ignore the
> comment, which makes both other versions less relevant).
 
Hmm, I'd expect that people add something like 

#if GCC_VERSION >= 7000
# define gcc_fallthrough() __builtin_fallthrough ()
#else
# define gcc_fallthrough()
#endif

and not use the builtin directly.

> Unrelated question: are there cases where __builtin_fallthrough() has any
> impact on code generation?

It should not -- my implementation gets rid of all __builtin_fallthrough()
during gimple-low, before most of the optimizations kick in, so it shouldn't
make any real difference.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-13 18:40         ` Marek Polacek
@ 2016-07-13 18:48           ` Bruce Korb
  0 siblings, 0 replies; 77+ messages in thread
From: Bruce Korb @ 2016-07-13 18:48 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On Wed, Jul 13, 2016 at 11:39 AM, Marek Polacek <polacek@redhat.com> wrote:
> Most likely what you saw was in cxx_pretty_printer::declaration_specifiers.

I only saw it once and, of course, it was once too often. ;)
If you fix it, it would sooth my sensibilities as the fixincludes maintainer,
making mine a small voice in the GCC world.

Still, for what it's worth, I'd back you :)

Cheers - Bruce

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-13 18:47       ` Marek Polacek
@ 2016-07-13 19:05         ` Marc Glisse
  2016-08-12 14:42           ` Marek Polacek
  0 siblings, 1 reply; 77+ messages in thread
From: Marc Glisse @ 2016-07-13 19:05 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

On Wed, 13 Jul 2016, Marek Polacek wrote:

> On Wed, Jul 13, 2016 at 08:39:28PM +0200, Marc Glisse wrote:
>> On Wed, 13 Jul 2016, Marek Polacek wrote:
>>
>>> Does "__attribute__((fallthrough));" have any advantages over
>>> "__builtin_fallthrough()"?
>>
>> Not a strong argument, but compilers that don't know the construct will give
>> an error on the builtin, and just a warning on the attribute (and ignore the
>> comment, which makes both other versions less relevant).
>
> Hmm, I'd expect that people add something like
>
> #if GCC_VERSION >= 7000
> # define gcc_fallthrough() __builtin_fallthrough ()
> #else
> # define gcc_fallthrough()
> #endif
>
> and not use the builtin directly.

I expect people will mostly use the comment, or maybe the C++17 attribute 
in a few years in C++ code. But accidents happen. I did say it was a weak 
argument ;-)

>> Unrelated question: are there cases where __builtin_fallthrough() has any
>> impact on code generation?
>
> It should not -- my implementation gets rid of all __builtin_fallthrough()
> during gimple-low, before most of the optimizations kick in, so it shouldn't
> make any real difference.

"should", "most", "real"... This is a bit like compare-debug, as a user I 
expect it to only affect warnings, and if it can affect code generation, 
even in small ways, I would like the doc to tell me.

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-13 18:23     ` Marek Polacek
  2016-07-13 18:31       ` Bruce Korb
@ 2016-07-13 22:36       ` Bruce Korb
  2016-07-13 22:53         ` Marek Polacek
  1 sibling, 1 reply; 77+ messages in thread
From: Bruce Korb @ 2016-07-13 22:36 UTC (permalink / raw)
  To: Marek Polacek; +Cc: GCC Patches

Actually, it occurs to me:

On Wed, Jul 13, 2016 at 11:23 AM, Marek Polacek <polacek@redhat.com> wrote:
> My current implementation warns here, but the warning can be suppressed
> by adding /* FALLTHRU */ or [...]

that the traditional "lint-ean" spelling is "/* FALLTHROUGH */", so
why would the abbrev be accepted and the full spelling not?  I think
"FALLTHRU" was added a mere 20 years ago and I go back farther than
that.  (40+, actually).

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: rs6000
  2016-07-13 22:36       ` Bruce Korb
@ 2016-07-13 22:53         ` Marek Polacek
  0 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-13 22:53 UTC (permalink / raw)
  To: Bruce Korb; +Cc: GCC Patches

On Wed, Jul 13, 2016 at 03:35:10PM -0700, Bruce Korb wrote:
> Actually, it occurs to me:
> 
> On Wed, Jul 13, 2016 at 11:23 AM, Marek Polacek <polacek@redhat.com> wrote:
> > My current implementation warns here, but the warning can be suppressed
> > by adding /* FALLTHRU */ or [...]
> 
> that the traditional "lint-ean" spelling is "/* FALLTHROUGH */", so
> why would the abbrev be accepted and the full spelling not?  I think
> "FALLTHRU" was added a mere 20 years ago and I go back farther than
> that.  (40+, actually).

We plan to support wide range of such "falls through" comments, see
the list here <https://gcc.gnu.org/ml/gcc-patches/2016-07/msg00647.html>.
We're hoping this will be enough.

Thanks,

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough: aarch64 + arm
  2016-07-11 19:53 ` Implement -Wswitch-fallthrough: aarch64 + arm Marek Polacek
@ 2016-07-14  9:05   ` Richard Earnshaw (lists)
  0 siblings, 0 replies; 77+ messages in thread
From: Richard Earnshaw (lists) @ 2016-07-14  9:05 UTC (permalink / raw)
  To: Marek Polacek, GCC Patches

Where the comments just say "Fall through", or equivalent, and there's
no other explanation I think those comments are now redundant and should
be removed.

So remove:

       /* Fall through.  */

but keep things like:

 	      /* Fall through - if the lane index isn't a constant then
 		 the next case will error.  */

OK with that change.

R.

On 11/07/16 20:53, Marek Polacek wrote:
> 2016-07-11  Marek Polacek  <polacek@redhat.com>
> 
> 	PR c/7652
> 	* config/aarch64/aarch64-builtins.c (aarch64_simd_expand_args): Add gcc_fallthrough.
> 	* config/aarch64/aarch64-simd.md: Likewise.
> 	* config/aarch64/aarch64.c (aarch64_expand_mov_immediate): Likewise.
> 	(aarch64_print_operand): Likewise.
> 	(aarch64_rtx_costs): Likewise.
> 	(aarch64_expand_compare_and_swap): Likewise.
> 	(aarch64_gen_atomic_ldop): Likewise.
> 	(aarch64_split_atomic_op): Likewise.
> 	(aarch64_expand_vec_perm_const): Likewise.
> 	* config/aarch64/predicates.md: Likewise.
> 	* config/arm/arm-builtins.c (arm_expand_neon_args): Likewise.
> 	* config/arm/arm.c (const_ok_for_op): Likewise.
> 	(arm_rtx_costs_1): Likewise.
> 	(thumb1_size_rtx_costs): Likewise.
> 	(arm_size_rtx_costs): Likewise.
> 	(arm_new_rtx_costs): Likewise.
> 	(thumb2_reorg): Likewise.
> 	(output_move_double): Likewise.
> 	(output_move_neon): Likewise.
> 	(arm_print_operand): Likewise.
> 	(arm_expand_compare_and_swap): Likewise.
> 	(arm_split_atomic_op): Likewise.
> 	(arm_expand_vec_perm_const): Likewise.
> 	* config/arm/neon.md: Likewise.
> 
> diff --git gcc/gcc/config/aarch64/aarch64-builtins.c gcc/gcc/config/aarch64/aarch64-builtins.c
> index 6b90b2a..fe37ea2 100644
> --- gcc/gcc/config/aarch64/aarch64-builtins.c
> +++ gcc/gcc/config/aarch64/aarch64-builtins.c
> @@ -999,6 +999,7 @@ aarch64_simd_expand_args (rtx target, int icode, int have_retval,
>  		}
>  	      /* Fall through - if the lane index isn't a constant then
>  		 the next case will error.  */
> +	      gcc_fallthrough ();
>  	    case SIMD_ARG_CONSTANT:
>  constant_arg:
>  	      if (!(*insn_data[icode].operand[opc].predicate)
> diff --git gcc/gcc/config/aarch64/aarch64-simd.md gcc/gcc/config/aarch64/aarch64-simd.md
> index a19d171..110a070 100644
> --- gcc/gcc/config/aarch64/aarch64-simd.md
> +++ gcc/gcc/config/aarch64/aarch64-simd.md
> @@ -2328,6 +2328,7 @@
>        if (operands[5] == CONST0_RTX (<MODE>mode))
>          break;
>        /* Fall through, as may need to load into register.  */
> +      gcc_fallthrough ();
>      default:
>        if (!REG_P (operands[5]))
>          operands[5] = force_reg (<MODE>mode, operands[5]);
> @@ -2430,6 +2431,7 @@
>  	  break;
>  	}
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      default:
>        if (!REG_P (operands[5]))
>  	operands[5] = force_reg (<VDQF:MODE>mode, operands[5]);
> @@ -2441,6 +2443,7 @@
>      case UNLT:
>        inverse = 1;
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      case GE:
>      case UNGE:
>      case ORDERED:
> @@ -2452,6 +2455,7 @@
>      case UNLE:
>        inverse = 1;
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      case GT:
>      case UNGT:
>        base_comparison = gen_aarch64_cmgt<VDQF:mode>;
> @@ -2545,6 +2549,7 @@
>  	 Swapping the operands to BSL will give the UNORDERED case.  */
>       swap_bsl_operands = 1;
>       /* Fall through.  */
> +     gcc_fallthrough ();
>      case ORDERED:
>        emit_insn (gen_aarch64_cmgt<VDQF:mode> (tmp, operands[4], operands[5]));
>        emit_insn (gen_aarch64_cmge<VDQF:mode> (mask, operands[5], operands[4]));
> diff --git gcc/gcc/config/aarch64/aarch64.c gcc/gcc/config/aarch64/aarch64.c
> index 512ef10..3ecf244 100644
> --- gcc/gcc/config/aarch64/aarch64.c
> +++ gcc/gcc/config/aarch64/aarch64.c
> @@ -1833,6 +1833,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
>  	      return;
>  	    }
>  	  /* FALLTHRU */
> +	  gcc_fallthrough ();
>  
>  	case SYMBOL_SMALL_ABSOLUTE:
>  	case SYMBOL_TINY_ABSOLUTE:
> @@ -4541,6 +4542,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
>  	      break;
>  	    }
>  	  /* Fall through.  */
> +	  gcc_fallthrough ();
>  
>  	default:
>  	  output_operand_lossage ("Unsupported operand for code '%c'", code);
> @@ -4713,6 +4715,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
>  	}
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>  
>      case 0:
>        /* Print a normal operand, if it's a general register, then we
> @@ -6192,6 +6195,7 @@ aarch64_rtx_costs (rtx x, machine_mode mode, int outer ATTRIBUTE_UNUSED,
>  	    *cost += rtx_cost (SUBREG_REG (op0), VOIDmode, SET, 0, speed);
>  
>  	  /* Fall through.  */
> +	  gcc_fallthrough ();
>  	case REG:
>  	  /* The cost is one per vector-register copied.  */
>  	  if (VECTOR_MODE_P (GET_MODE (op0)) && REG_P (op1))
> @@ -6685,6 +6689,7 @@ cost_plus:
>            return true;
>          }
>      /* Fall through.  */
> +    gcc_fallthrough ();
>      case XOR:
>      case AND:
>      cost_logic:
> @@ -7081,6 +7086,7 @@ cost_plus:
>  	}
>  
>      /* Fall-through.  */
> +    gcc_fallthrough ();
>      case UMOD:
>        if (speed)
>  	{
> @@ -7356,6 +7362,7 @@ cost_plus:
>          }
>  
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      default:
>        break;
>      }
> @@ -11422,6 +11429,7 @@ aarch64_expand_compare_and_swap (rtx operands[])
>        rval = gen_reg_rtx (SImode);
>        oldval = convert_modes (SImode, mode, oldval, true);
>        /* Fall through.  */
> +      gcc_fallthrough ();
>  
>      case SImode:
>      case DImode:
> @@ -11777,6 +11785,7 @@ aarch64_gen_atomic_ldop (enum rtx_code code, rtx out_data, rtx out_result,
>  	  src = gen_lowpart (mode, src);
>        }
>        /* Fall-through.  */
> +      gcc_fallthrough ();
>      case PLUS:
>        ldop_code = AARCH64_LDOP_PLUS;
>        break;
> @@ -11904,6 +11913,7 @@ aarch64_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
>  	  code = PLUS;
>  	}
>        /* Fall through.  */
> +      gcc_fallthrough ();
>  
>      default:
>        x = gen_rtx_fmt_ee (code, wmode, old_out, value);
> @@ -12817,6 +12827,7 @@ aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel)
>  	 of the permutation by folding the permutation into the single
>  	 input vector.  */
>        /* Fall Through.  */
> +      gcc_fallthrough ();
>      case 2:
>        for (i = 0; i < nelt; ++i)
>  	d.perm[i] &= nelt - 1;
> diff --git gcc/gcc/config/aarch64/predicates.md gcc/gcc/config/aarch64/predicates.md
> index 8f2726d..9a7b336 100644
> --- gcc/gcc/config/aarch64/predicates.md
> +++ gcc/gcc/config/aarch64/predicates.md
> @@ -180,6 +180,7 @@
>  	  || GET_CODE (XEXP (op, 1)) != CONST_INT)
>  	return false;
>        op = XEXP (op, 0);
> +      gcc_fallthrough ();
>  
>      case SYMBOL_REF:
>        return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC;
> @@ -201,6 +202,7 @@
>  	  || GET_CODE (XEXP (op, 1)) != CONST_INT)
>  	return false;
>        op = XEXP (op, 0);
> +      gcc_fallthrough ();
>  
>      case SYMBOL_REF:
>        return SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC;
> diff --git gcc/gcc/config/arm/arm-builtins.c gcc/gcc/config/arm/arm-builtins.c
> index 68b2839..3b03c29 100644
> --- gcc/gcc/config/arm/arm-builtins.c
> +++ gcc/gcc/config/arm/arm-builtins.c
> @@ -2113,6 +2113,7 @@ arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
>  		}
>  	      /* Fall through - if the lane index isn't a constant then
>  		 the next case will error.  */
> +	      gcc_fallthrough ();
>  
>  	    case NEON_ARG_CONSTANT:
>  constant_arg:
> diff --git gcc/gcc/config/arm/arm.c gcc/gcc/config/arm/arm.c
> index 580662d..e5f8208 100644
> --- gcc/gcc/config/arm/arm.c
> +++ gcc/gcc/config/arm/arm.c
> @@ -3956,6 +3956,7 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
>  	      || ((-i) & 0xfffff000) == 0))
>  	return 1;
>        /* else fall through.  */
> +      gcc_fallthrough ();
>  
>      case COMPARE:
>      case EQ:
> @@ -8469,6 +8470,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
>  	*total = rtx_cost (XEXP (x, 1), mode, code, 1, speed);
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>      case ROTATERT:
>        if (mode != SImode)
>  	{
> @@ -8477,6 +8479,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
>  	}
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>      case ASHIFT: case LSHIFTRT: case ASHIFTRT:
>        *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
>        if (mode == DImode)
> @@ -8590,6 +8593,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
>  	}
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>  
>      case PLUS:
>        if (code == PLUS && arm_arch6 && mode == SImode
> @@ -8646,6 +8650,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
>  	}
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>  
>      case AND: case XOR: case IOR:
>  
> @@ -8741,6 +8746,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
>  	}
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>      case NOT:
>        *total = COSTS_N_INSNS (ARM_NUM_REGS(mode));
>        if (mode == SImode && code == NOT)
> @@ -8837,6 +8843,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
>  	}
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>      case COMPARE:
>        if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) == CC_REGNUM)
>  	{
> @@ -9076,6 +9083,7 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
>  	      && power_of_two_operand (XEXP (XEXP (x, 1), 1), SImode)))
>  	return COSTS_N_INSNS (2);
>        /* On purpose fall through for normal RTX.  */
> +      gcc_fallthrough ();
>      case COMPARE:
>      case NEG:
>      case NOT:
> @@ -9243,6 +9251,7 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
>  	  return true;
>  	}
>        /* Fall through */
> +      gcc_fallthrough ();
>      case ROTATERT:
>      case ASHIFT:
>      case LSHIFTRT:
> @@ -9317,6 +9326,7 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
>  	}
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>      case AND: case XOR: case IOR:
>        if (mode == SImode)
>  	{
> @@ -9348,6 +9358,7 @@ arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
>  	}
>  
>        /* Fall through */
> +      gcc_fallthrough ();
>      case NOT:
>        *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
>  
> @@ -9721,6 +9732,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
>  	}
>  
>      /* Fall-through.  */
> +    gcc_fallthrough ();
>      case UMOD:
>        *cost = LIBCALL_COST (2);
>        return false;	/* All arguments must be in registers.  */
> @@ -9735,6 +9747,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
>  	  return true;
>  	}
>        /* Fall through */
> +      gcc_fallthrough ();
>      case ROTATERT:
>      case ASHIFT:
>      case LSHIFTRT:
> @@ -10244,6 +10257,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
>            return true;
>          }
>      /* Fall through.  */
> +    gcc_fallthrough ();
>      case AND: case XOR:
>        if (mode == SImode)
>  	{
> @@ -11035,6 +11049,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
>  	  return true;
>  	}
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      case SMAX:
>      case UMIN:
>      case UMAX:
> @@ -11076,6 +11091,7 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
>      case ZERO_EXTRACT:
>        /* TODO: Simple zero_extract of bottom bits using AND.  */
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      case SIGN_EXTRACT:
>        if (arm_arch6
>  	  && mode == SImode
> @@ -17506,6 +17522,7 @@ thumb2_reorg (void)
>  		      if (!optimize_size)
>  			break;
>  		      /* else fall through.  */
> +		      gcc_fallthrough ();
>  		    case AND:
>  		    case IOR:
>  		    case XOR:
> @@ -18544,6 +18561,7 @@ output_move_double (rtx *operands, bool emit, int *count)
>  	      return "";
>  	    }
>  	  /* Fall through */
> +	  gcc_fallthrough ();
>  
>          default:
>  	  otherops[0] = adjust_address (operands[0], SImode, 4);
> @@ -18811,6 +18829,7 @@ output_move_neon (rtx *operands)
>  	  break;
>  	}
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      case LABEL_REF:
>      case PLUS:
>        {
> @@ -21992,6 +22011,7 @@ arm_print_operand (FILE *stream, rtx x, int code)
>  	      break;
>  	    }
>  	  /* Fall through.  */
> +	  gcc_fallthrough ();
>  
>  	default:
>  	  output_operand_lossage ("Unsupported operand for code '%c'", code);
> @@ -28107,6 +28127,7 @@ arm_expand_compare_and_swap (rtx operands[])
>        rval = gen_reg_rtx (SImode);
>        oldval = convert_modes (SImode, mode, oldval, true);
>        /* FALLTHRU */
> +      gcc_fallthrough ();
>  
>      case SImode:
>        /* Force the value into a register if needed.  We waited until after
> @@ -28298,6 +28319,7 @@ arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
>  	  code = PLUS;
>  	}
>        /* FALLTHRU */
> +      gcc_fallthrough ();
>  
>      case PLUS:
>        if (mode == DImode)
> @@ -28317,6 +28339,7 @@ arm_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
>  	  break;
>  	}
>        /* FALLTHRU */
> +      gcc_fallthrough ();
>  
>      default:
>        x = gen_rtx_fmt_ee (code, wmode, old_out, value);
> @@ -28904,6 +28927,7 @@ arm_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel)
>  	 of the permutation by folding the permutation into the single
>  	 input vector.  */
>        /* FALLTHRU */
> +      gcc_fallthrough ();
>      case 2:
>        for (i = 0; i < nelt; ++i)
>          d.perm[i] &= nelt - 1;
> diff --git gcc/gcc/config/arm/neon.md gcc/gcc/config/arm/neon.md
> index e2fdfbb..6488cdc 100644
> --- gcc/gcc/config/arm/neon.md
> +++ gcc/gcc/config/arm/neon.md
> @@ -1731,6 +1731,7 @@
>  	  break;
>  	}
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      default:
>        if (!REG_P (operands[5]))
>  	operands[5] = force_reg (<MODE>mode, operands[5]);
> @@ -1742,6 +1743,7 @@
>      case UNLT:
>        inverse = 1;
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      case GE:
>      case UNGE:
>      case ORDERED:
> @@ -1753,6 +1755,7 @@
>      case UNLE:
>        inverse = 1;
>        /* Fall through.  */
> +      gcc_fallthrough ();
>      case GT:
>      case UNGT:
>        base_comparison = gen_neon_vcgt<mode>;
> @@ -1846,6 +1849,7 @@
>  	 Swapping the operands to BSL will give the UNORDERED case.  */
>       swap_bsl_operands = 1;
>       /* Fall through.  */
> +     gcc_fallthrough ();
>      case ORDERED:
>        emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5]));
>        emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4]));
> 

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 21:00 ` Martin Sebor
@ 2016-07-28 17:03   ` Marek Polacek
  0 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-28 17:03 UTC (permalink / raw)
  To: Martin Sebor; +Cc: GCC Patches

Coming back to this...

On Tue, Jul 12, 2016 at 03:00:43PM -0600, Martin Sebor wrote:
> > This patch is accompanied by more than 2000 lines of new tests to get the
> > warning covered though I'm sure folks will come up with other test cases
> > that I hadn't considered (hi Martin S. ;).
> > 
> > This warning is enabled by default for C/C++.  I was more inclined to put this
> > into -Wall, but our common.opt machinery doesn't seem to allow that (ugh!).
> > The clang version I have installed doesn't have this warning so I couldn't
> > compare my implementation with others.
> > 
> > I plan to plunge into the C++ [[fallthrough]] thingie after this core part is
> > dealt with.
> 
> I think this is a useful feature though like others I'm not
> entirely sure that a built-in is the right interface.  I think
> I would find a pragma or an attribute preferable.  At a minimum,
> it would obviate some questions raised by my testing (i.e.,
> whether the built-in be accepted when an attribute would
> otherwise not be syntactically allowed).
> 
> I applied the core patch and ran a few experiments with it on
> the assumption that __builtin_fallthrough() should behave roughly
> correspondingly to [[fallthrough]].  I.e., be rejected where
> [[fallthrough]] is rejected (but where attributes are otherwise
> valid) and be accepted where the latter is accepted.  This may
> not be intended but the text added to the manual is too vague
> to tell.  I also compared the results to Clang's [[fallthrough]]
> to make sure I wasn't missing something (or too much).
> 
> I ran into a few of what seems like subtle bugs or limitations
> some of which I'm not sure are going to be solvable in the middle
> end (at least not after the control flow graph has been built)
> because by the time the middle end sees the code (certainly by
> the time it gets to expansion) some of it has been eliminated.
> An illustrative example of this class of problems might be this
> function:
> 
>   void f (void)
>   {
>     if (0) __builtin_fallthrough ();   // never diagnosed
> 
>     int i = 0;
>     if (i) __builtin_fallthrough ();   // not diagnosed with -O
>   }
> 
> With the built-in replaced by [[fallthrough]] Clang diagnoses
> both of these.
> 
> This may be an okay limitation for __builtin_fallthrough since
> it's GCC-specific, but it won't do for the C++ attribute or for
> the C attribute if one is added with matching constraints.
> 
> The tests I tried are in the attached file.  Most of them are
> edge cases but some I think point out more serious problems
> (the checker getting confused/disabled by a prior switch
> statement).
> 
> Hopefully this will be useful.

Sure it is, thanks.  Since I've replaced __builtin_fallthrough ()
with an attribute, most of your observations should be fixed now.
But there was an ICE happening even with __attribute__((fallthrough)),
which I fixed now.  Your testcase is included (in a bit different
form) in the latest patch submission.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-12 16:10 ` Jeff Law
@ 2016-07-28 17:04   ` Marek Polacek
  0 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-07-28 17:04 UTC (permalink / raw)
  To: Jeff Law; +Cc: GCC Patches

On Tue, Jul 12, 2016 at 10:10:23AM -0600, Jeff Law wrote:
> On 07/11/2016 01:43 PM, Marek Polacek wrote:
> > The switch fallthrough has been widely considered a design defect in C, a
> > misfeature or, to use Marshall Cline's definition, evil.  The overwhelming
> > majority of the time you don't want to fall through to the next case, but it is
> > easy to forget to "break" at the end of the case, making this far too error
> > prone.  Yet GCC (and probably other compilers, too) doesn't have the ability to
> > warn in this case.  A feature request for such warning was opened back in 2002,
> > but it's mostly been untouched since.  But then the [[fallthrough]] attribute was
> > approved for C++17 [1], and that's what has got me to do all this.
> [ ... ]
> This is going to be rather contentious.  So as we're hashing through that,
> can you split off the patches which fix bugs rather than those which add
> fallthru annotations?

To (belatedly) answer this, I posted
<https://gcc.gnu.org/ml/gcc-patches/2016-07/msg01880.html> to address this.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

* Re: Implement -Wswitch-fallthrough
  2016-07-13 19:05         ` Marc Glisse
@ 2016-08-12 14:42           ` Marek Polacek
  0 siblings, 0 replies; 77+ messages in thread
From: Marek Polacek @ 2016-08-12 14:42 UTC (permalink / raw)
  To: GCC Patches

On Wed, Jul 13, 2016 at 09:05:26PM +0200, Marc Glisse wrote:
> > > Unrelated question: are there cases where __builtin_fallthrough() has any
> > > impact on code generation?
> > 
> > It should not -- my implementation gets rid of all __builtin_fallthrough()
> > during gimple-low, before most of the optimizations kick in, so it shouldn't
> > make any real difference.
> 
> "should", "most", "real"... This is a bit like compare-debug, as a user I
> expect it to only affect warnings, and if it can affect code generation,
> even in small ways, I would like the doc to tell me.

Dunno if this really proves anything, but I took dwarf2out.ii (it's huge),
and compiled it with
./cc1plus -quiet -g -O2
and then with
./cc1plus -quiet -g -O2 -Wimplicit-fallthrough
and compared the final .s files.  The result is just this:

$ diff -u dwarf2out-v.s dwarf2out.s
--- dwarf2out-v.s	2016-08-12 16:37:11.479918482 +0200
+++ dwarf2out.s	2016-08-12 16:38:06.825929792 +0200
@@ -116459,6 +116459,7 @@
 .LBB35755:
 .LBB35748:
 .LBB35742:
+	.loc 1 17164 0
 	jmp	.L11208
 .LVL13482:
 	.p2align 4,,10

so it seems this warning really doesn't have any effect whatsoever on code generation.

	Marek

^ permalink raw reply	[flat|nested] 77+ messages in thread

end of thread, other threads:[~2016-08-12 14:42 UTC | newest]

Thread overview: 77+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-11 19:43 Implement -Wswitch-fallthrough Marek Polacek
2016-07-11 19:46 ` Implement -Wswitch-fallthrough: core Marek Polacek
2016-07-11 19:50 ` Implement -Wswitch-fallthrough: c-family/ Marek Polacek
2016-07-11 19:50 ` Implement -Wswitch-fallthrough: c/ Marek Polacek
2016-07-11 19:51 ` Implement -Wswitch-fallthrough: cp/ Marek Polacek
2016-07-11 19:52 ` Implement -Wswitch-fallthrough: fortran/ Marek Polacek
2016-07-11 19:52 ` Implement -Wswitch-fallthrough: gcc/ Marek Polacek
2016-07-11 19:53 ` Implement -Wswitch-fallthrough: aarch64 + arm Marek Polacek
2016-07-14  9:05   ` Richard Earnshaw (lists)
2016-07-11 19:54 ` Implement -Wswitch-fallthrough: i386 Marek Polacek
2016-07-11 19:54 ` Implement -Wswitch-fallthrough: java Marek Polacek
2016-07-11 21:26   ` Tom Tromey
2016-07-11 19:54 ` Implement -Wswitch-fallthrough: go Marek Polacek
2016-07-11 19:55 ` Implement -Wswitch-fallthrough: libcpp Marek Polacek
2016-07-11 19:55 ` Implement -Wswitch-fallthrough: libatomic Marek Polacek
2016-07-11 19:56 ` Implement -Wswitch-fallthrough: libgcc Marek Polacek
2016-07-11 19:56 ` Implement -Wswitch-fallthrough: libgomp Marek Polacek
2016-07-11 19:57 ` Implement -Wswitch-fallthrough: libgo Marek Polacek
2016-07-11 19:57 ` Implement -Wswitch-fallthrough: libiberty Marek Polacek
2016-07-11 19:58 ` Implement -Wswitch-fallthrough: objc Marek Polacek
2016-07-11 19:58 ` Implement -Wswitch-fallthrough: libstdc++ Marek Polacek
2016-07-11 22:18   ` Jonathan Wakely
2016-07-11 19:58 ` Implement -Wswitch-fallthrough: lto Marek Polacek
2016-07-12 10:23   ` Richard Biener
2016-07-12 10:28     ` Marek Polacek
2016-07-11 19:59 ` Implement -Wswitch-fallthrough: rs6000 Marek Polacek
2016-07-11 20:36   ` Bruce Korb
2016-07-13 18:23     ` Marek Polacek
2016-07-13 18:31       ` Bruce Korb
2016-07-13 18:40         ` Marek Polacek
2016-07-13 18:48           ` Bruce Korb
2016-07-13 22:36       ` Bruce Korb
2016-07-13 22:53         ` Marek Polacek
2016-07-12 14:11   ` Segher Boessenkool
2016-07-12 14:20     ` Marek Polacek
2016-07-12 14:42       ` Bernd Schmidt
2016-07-12 14:45         ` Jakub Jelinek
2016-07-11 19:59 ` Implement -Wswitch-fallthrough: other archs Marek Polacek
2016-07-11 20:00 ` Implement -Wswitch-fallthrough: testsuite Marek Polacek
2016-07-11 20:00 ` Implement -Wswitch-fallthrough Andrew Pinski
2016-07-11 20:01   ` Marek Polacek
2016-07-11 20:03     ` Andrew Pinski
2016-07-11 20:01 ` Andi Kleen
2016-07-11 20:04   ` Marek Polacek
2016-07-11 20:18     ` Andi Kleen
2016-07-11 20:23       ` Marek Polacek
2016-07-11 20:35         ` Jakub Jelinek
2016-07-11 20:44           ` David Malcolm
2016-07-11 20:50             ` Jakub Jelinek
2016-07-12 13:57           ` NightStrike
2016-07-12 14:08             ` Marek Polacek
2016-07-12 14:14               ` Jakub Jelinek
2016-07-12 14:22                 ` Bernd Schmidt
2016-07-12 14:36                   ` Jakub Jelinek
2016-07-11 20:08 ` Eric Botcazou
2016-07-11 20:12   ` Jakub Jelinek
2016-07-11 20:20     ` Marek Polacek
2016-07-11 20:30       ` Eric Botcazou
2016-07-11 20:39       ` David Malcolm
2016-07-11 20:28 ` NightStrike
2016-07-13 18:16   ` Marek Polacek
2016-07-13 18:39     ` Marc Glisse
2016-07-13 18:47       ` Marek Polacek
2016-07-13 19:05         ` Marc Glisse
2016-08-12 14:42           ` Marek Polacek
2016-07-12 10:27 ` Richard Biener
2016-07-12 10:31   ` Marek Polacek
2016-07-12 15:59     ` Jeff Law
2016-07-12 16:04       ` Marek Polacek
2016-07-12 17:40         ` Martin Sebor
2016-07-12 17:52           ` Marek Polacek
2016-07-12 11:24 ` Bernd Schmidt
2016-07-12 11:36   ` Marek Polacek
2016-07-12 16:10 ` Jeff Law
2016-07-28 17:04   ` Marek Polacek
2016-07-12 21:00 ` Martin Sebor
2016-07-28 17:03   ` Marek Polacek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).