Fix -Wimplicit-fallthrough for Clang.

WUFFS_BASE__FALLTHROUGH was not defined because the generated output is
C (so __cplusplus is never defined) and Clang was explicitly excluded
from the __attribute__ case (though it would have worked).

Instead test for the availability of the fallthrough attribute directly,
which should be more portable.

Bug: chromium:995993
diff --git a/internal/cgen/base/fundamental-private.h b/internal/cgen/base/fundamental-private.h
index 1232b4b..8fce6f2 100644
--- a/internal/cgen/base/fundamental-private.h
+++ b/internal/cgen/base/fundamental-private.h
@@ -31,14 +31,18 @@
 
 // Denote intentional fallthroughs for -Wimplicit-fallthrough.
 //
-// The order matters here. Clang also defines "__GNUC__".
-#if defined(__clang__) && defined(__cplusplus) && (__cplusplus >= 201103L)
-#define WUFFS_BASE__FALLTHROUGH [[clang::fallthrough]]
-#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 7)
+// As noted on
+// https:// gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html ,
+// combining the two tests in one conditional would not be portable.
+#if defined __has_attribute
+#if __has_attribute(fallthrough)
 #define WUFFS_BASE__FALLTHROUGH __attribute__((fallthrough))
 #else
 #define WUFFS_BASE__FALLTHROUGH
 #endif
+#else
+#define WUFFS_BASE__FALLTHROUGH
+#endif
 
 // Use switch cases for coroutine suspension points, similar to the technique
 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index 8a83223..2dc1bf7 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -29,9 +29,9 @@
 	""
 
 const BaseFundamentalPrivateH = "" +
-	"// ---------------- Fundamentals\n\n// WUFFS_BASE__MAGIC is a magic number to check that initializers are called.\n// It's not foolproof, given C doesn't automatically zero memory before use,\n// but it should catch 99.99% of cases.\n//\n// Its (non-zero) value is arbitrary, based on md5sum(\"wuffs\").\n#define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)\n\n// WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable\n// error was previously encountered.\n//\n// Its (non-zero) value is arbitrary, based on md5sum(\"disabled\").\n#define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)\n\n// Denote intentional fallthroughs for -Wimplicit-fallthrough.\n//\n// The order matters here. Clang also defines \"__GNUC__\".\n#if defined(__clang__) && defined(__cplusplus) && (__cplusplus >= 201103L)\n#define WUFFS_BASE__FALLTHROUGH [[clang::fallthrough]]\n#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 7)\n#define WUFFS_BASE__FALLTHROUGH __attribute__((fallthrough))\n#else\n#define WUFFS_BASE__FALLTHROUGH\n#endif\n\n// Use switch " +
-	"cases for coroutine suspension points, similar to the technique\n// in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html\n//\n// We use trivial macros instead of an explicit assignment and case statement\n// so that clang-format doesn't get confused by the unusual \"case\"s.\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \\\n  coro_susp_point = n;                            \\\n  WUFFS_BASE__FALLTHROUGH;                        \\\n  case n:;\n\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \\\n  if (!status.repr) {                                           \\\n    goto ok;                                                    \\\n  } else if (*status.repr != '$') {                             \\\n    goto exit;                                                  \\\n  }                                                             \\\n  coro_susp_point = n;                                          \\\n  goto suspend;                                        " +
-	"         \\\n  case n:;\n\n// Clang also defines \"__GNUC__\".\n#if defined(__GNUC__)\n#define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))\n#define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))\n#else\n#define WUFFS_BASE__LIKELY(expr) (expr)\n#define WUFFS_BASE__UNLIKELY(expr) (expr)\n#endif\n\n" +
+	"// ---------------- Fundamentals\n\n// WUFFS_BASE__MAGIC is a magic number to check that initializers are called.\n// It's not foolproof, given C doesn't automatically zero memory before use,\n// but it should catch 99.99% of cases.\n//\n// Its (non-zero) value is arbitrary, based on md5sum(\"wuffs\").\n#define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)\n\n// WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable\n// error was previously encountered.\n//\n// Its (non-zero) value is arbitrary, based on md5sum(\"disabled\").\n#define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)\n\n// Denote intentional fallthroughs for -Wimplicit-fallthrough.\n//\n// As noted on\n// https:// gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html ,\n// combining the two tests in one conditional would not be portable.\n#if defined __has_attribute\n#if __has_attribute(fallthrough)\n#define WUFFS_BASE__FALLTHROUGH __attribute__((fallthrough))\n#else\n#define WUFFS_BASE__FALLTHROUGH\n#endif\n#else\n#define WUFFS_BASE__FALLTHROUGH\n#endif\n\n// U" +
+	"se switch cases for coroutine suspension points, similar to the technique\n// in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html\n//\n// We use trivial macros instead of an explicit assignment and case statement\n// so that clang-format doesn't get confused by the unusual \"case\"s.\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \\\n  coro_susp_point = n;                            \\\n  WUFFS_BASE__FALLTHROUGH;                        \\\n  case n:;\n\n#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \\\n  if (!status.repr) {                                           \\\n    goto ok;                                                    \\\n  } else if (*status.repr != '$') {                             \\\n    goto exit;                                                  \\\n  }                                                             \\\n  coro_susp_point = n;                                          \\\n  goto suspend;                              " +
+	"                   \\\n  case n:;\n\n// Clang also defines \"__GNUC__\".\n#if defined(__GNUC__)\n#define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))\n#define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))\n#else\n#define WUFFS_BASE__LIKELY(expr) (expr)\n#define WUFFS_BASE__UNLIKELY(expr) (expr)\n#endif\n\n" +
 	"" +
 	"// --------\n\nstatic inline wuffs_base__empty_struct  //\nwuffs_base__ignore_status(wuffs_base__status z) {\n  return wuffs_base__make_empty_struct();\n}\n\nstatic inline wuffs_base__status  //\nwuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {\n  if (z.repr && (*z.repr == '$')) {\n    z.repr = wuffs_base__error__cannot_return_a_suspension;\n  }\n  return z;\n}\n\n" +
 	"" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index c99ce5c..2989dcd 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -10061,14 +10061,18 @@
 
 // Denote intentional fallthroughs for -Wimplicit-fallthrough.
 //
-// The order matters here. Clang also defines "__GNUC__".
-#if defined(__clang__) && defined(__cplusplus) && (__cplusplus >= 201103L)
-#define WUFFS_BASE__FALLTHROUGH [[clang::fallthrough]]
-#elif !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 7)
+// As noted on
+// https:// gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html ,
+// combining the two tests in one conditional would not be portable.
+#if defined __has_attribute
+#if __has_attribute(fallthrough)
 #define WUFFS_BASE__FALLTHROUGH __attribute__((fallthrough))
 #else
 #define WUFFS_BASE__FALLTHROUGH
 #endif
+#else
+#define WUFFS_BASE__FALLTHROUGH
+#endif
 
 // Use switch cases for coroutine suspension points, similar to the technique
 // in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html