Add fallthrough annotations on new C++ switches

A recent commit converted some source from C to C++. Chrome has
checks against unannotated switch case fallthroughs in C++ code, so the
converted source needs annotations.

Bug: 990190
Change-Id: Ib92435b4877be936f837928a70b552ec4975d42a
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1898429
Reviewed-by: Mark Mentovai <mark@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/src/common/convert_UTF.cc b/src/common/convert_UTF.cc
index fed04e7..fe0e155 100644
--- a/src/common/convert_UTF.cc
+++ b/src/common/convert_UTF.cc
@@ -60,6 +60,8 @@
 #include <stdio.h>
 #endif
 
+#include "common/macros.h"
+
 namespace google_breakpad {
 
 namespace {
@@ -295,10 +297,20 @@
 	    target -= bytesToWrite; result = targetExhausted; break;
     }
     switch (bytesToWrite) { /* note: everything falls through. */
-	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-	    case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
+      case 4:
+        *--target = (UTF8)((ch | byteMark) & byteMask);
+        ch >>= 6;
+        BP_FALLTHROUGH;
+      case 3:
+        *--target = (UTF8)((ch | byteMark) & byteMask);
+        ch >>= 6;
+        BP_FALLTHROUGH;
+      case 2:
+        *--target = (UTF8)((ch | byteMark) & byteMask);
+        ch >>= 6;
+        BP_FALLTHROUGH;
+      case 1:
+        *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);
     }
     target += bytesToWrite;
   }
@@ -327,9 +339,14 @@
   switch (length) {
     default: return false;
       /* Everything else falls through when "true"... */
-    case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
-    case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
-    case 2: if ((a = (*--srcptr)) > 0xBF) return false;
+    case 4:
+      if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+      BP_FALLTHROUGH;
+    case 3:
+      if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;
+      BP_FALLTHROUGH;
+    case 2:
+      if ((a = (*--srcptr)) > 0xBF) return false;
 
       switch (*source) {
         /* no fall-through in this inner switch */
@@ -339,8 +356,8 @@
         case 0xF4: if (a > 0x8F) return false; break;
         default:   if (a < 0x80) return false;
       }
-
-      case 1: if (*source >= 0x80 && *source < 0xC2) return false;
+      BP_FALLTHROUGH;
+    case 1: if (*source >= 0x80 && *source < 0xC2) return false;
   }
   if (*source > 0xF4) return false;
   return true;
@@ -384,12 +401,14 @@
      * The cases all fall through. See "Note A" below.
      */
     switch (extraBytesToRead) {
-	    case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
-	    case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
-	    case 3: ch += *source++; ch <<= 6;
-	    case 2: ch += *source++; ch <<= 6;
-	    case 1: ch += *source++; ch <<= 6;
-	    case 0: ch += *source++;
+      /* remember, illegal UTF-8 */
+      case 5: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      /* remember, illegal UTF-8 */
+      case 4: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 3: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 2: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 1: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 0: ch += *source++;
     }
     ch -= offsetsFromUTF8[extraBytesToRead];
 
@@ -474,10 +493,20 @@
 	    target -= bytesToWrite; result = targetExhausted; break;
     }
     switch (bytesToWrite) { /* note: everything falls through. */
-	    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-	    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-	    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-	    case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
+      case 4:
+        *--target = (UTF8)((ch | byteMark) & byteMask);
+        ch >>= 6;
+        BP_FALLTHROUGH;
+      case 3:
+        *--target = (UTF8)((ch | byteMark) & byteMask);
+        ch >>= 6;
+        BP_FALLTHROUGH;
+      case 2:
+        *--target = (UTF8)((ch | byteMark) & byteMask);
+        ch >>= 6;
+        BP_FALLTHROUGH;
+      case 1:
+        *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
     }
     target += bytesToWrite;
   }
@@ -508,12 +537,12 @@
      * The cases all fall through. See "Note A" below.
      */
     switch (extraBytesToRead) {
-	    case 5: ch += *source++; ch <<= 6;
-	    case 4: ch += *source++; ch <<= 6;
-	    case 3: ch += *source++; ch <<= 6;
-	    case 2: ch += *source++; ch <<= 6;
-	    case 1: ch += *source++; ch <<= 6;
-	    case 0: ch += *source++;
+      case 5: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 4: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 3: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 2: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 1: ch += *source++; ch <<= 6; BP_FALLTHROUGH;
+      case 0: ch += *source++;
     }
     ch -= offsetsFromUTF8[extraBytesToRead];
 
diff --git a/src/common/macros.h b/src/common/macros.h
new file mode 100644
index 0000000..14bb3f7
--- /dev/null
+++ b/src/common/macros.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2019, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef BREAKPAD_COMMON_MACROS_H_
+#define BREAKPAD_COMMON_MACROS_H_
+
+// Ensure that this macro definition stays in a private header file: clang
+// suggests the first macro expanding to [[clang::fallthrough]] in its
+// diagnostics, so if BP_FALLTHROUGH is visible in code depending on breakpad,
+// clang would suggest BP_FALLTHROUGH for code depending on breakpad, instead of
+// the client code's own fallthrough macro.
+// TODO(thakis): Once everyone uses C++17, use its [[fallthrough]] instead.
+#if defined(__clang__)
+#define BP_FALLTHROUGH [[clang::fallthrough]]
+#else
+#define BP_FALLTHROUGH
+#endif
+
+#endif // BREAKPAD_COMMON_MACROS_H_
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index 78faf77..75b6b45 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -54,6 +54,7 @@
 
 #include "processor/range_map-inl.h"
 
+#include "common/macros.h"
 #include "common/scoped_ptr.h"
 #include "common/stdio_wrapper.h"
 #include "google_breakpad/processor/dump_context.h"
@@ -62,22 +63,6 @@
 #include "processor/convert_old_arm64_context.h"
 #include "processor/logging.h"
 
-// All intentional fallthroughs in breakpad are in this file, so define
-// this macro locally.
-// If you ever move this to a .h file, make sure it's defined in a
-// private header file: clang suggests the first macro expanding to
-// [[clang::fallthrough]] in its diagnostics, so if BP_FALLTHROUGH
-// is visible in code depending on breakpad, clang would suggest
-// BP_FALLTHROUGH for code depending on breakpad, instead of the
-// client code's own fallthrough macro.
-// TODO(thakis): Once everyone uses C++17, use its [[fallthrough]] instead.
-#if defined(__clang__)
-#define BP_FALLTHROUGH [[clang::fallthrough]]
-#else
-#define BP_FALLTHROUGH
-#endif
-
-
 namespace google_breakpad {
 
 using std::istream;