Fixed a bunch of Clang warnings.

Unfortunately a few of the Clang warnings did not have easy fixes:

../../../../ext/google/protobuf_c/ruby-upb.c: In function ‘fastdecode_err’:
../../../../ext/google/protobuf_c/ruby-upb.c:353:13: warning: function might be candidate for attribute ‘noreturn’ [-Wsuggest-attribute=noreturn]
  353 | const char *fastdecode_err(upb_decstate *d) {
      |             ^~~~~~~~~~~~~~
../../../../ext/google/protobuf_c/ruby-upb.c: In function ‘_upb_decode’:
../../../../ext/google/protobuf_c/ruby-upb.c:867:30: warning: argument ‘buf’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
  867 | bool _upb_decode(const char *buf, size_t size, void *msg,

I even tried to suppress the first error, but it still shows up.
diff --git a/upb/decode.c b/upb/decode.c
index cc18d7d..0ca6268 100644
--- a/upb/decode.c
+++ b/upb/decode.c
@@ -150,11 +150,23 @@
 
 UPB_NORETURN static void decode_err(upb_decstate *d) { UPB_LONGJMP(d->err, 1); }
 
+// We don't want to mark this NORETURN, see comment in .h.
+// Unfortunately this code to suppress the warning doesn't appear to be working.
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-warning-option"
+#pragma clang diagnostic ignored "-Wsuggest-attribute"
+#endif
+
 const char *fastdecode_err(upb_decstate *d) {
   longjmp(d->err, 1);
   return NULL;
 }
 
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
 const uint8_t upb_utf8_offsets[] = {
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -652,6 +664,14 @@
   return decode_msg(d, ptr, msg, decode_totablep(table));
 }
 
+static bool decode_top(struct upb_decstate *d, const char *buf, void *msg,
+                       const upb_msglayout *l) {
+  if (!decode_tryfastdispatch(d, &buf, msg, l)) {
+    decode_msg(d, buf, msg, l);
+  }
+  return d->end_group == DECODE_NOGROUP;
+}
+
 bool _upb_decode(const char *buf, size_t size, void *msg,
                  const upb_msglayout *l, upb_arena *arena, int options) {
   bool ok;
@@ -685,10 +705,7 @@
   if (UPB_UNLIKELY(UPB_SETJMP(state.err))) {
     ok = false;
   } else {
-    if (!decode_tryfastdispatch(&state, &buf, msg, l)) {
-      decode_msg(&state, buf, msg, l);
-    }
-    ok = state.end_group == DECODE_NOGROUP;
+    ok = decode_top(&state, buf, msg, l);
   }
 
   arena->head.ptr = state.arena.head.ptr;
diff --git a/upb/decode.int.h b/upb/decode.int.h
index e286b9c..7376e21 100644
--- a/upb/decode.int.h
+++ b/upb/decode.int.h
@@ -14,7 +14,7 @@
 /* Must be last. */
 #include "upb/port_def.inc"
 
-#define DECODE_NOGROUP -1
+#define DECODE_NOGROUP (uint32_t)-1
 
 typedef struct upb_decstate {
   const char *end;         /* Can read up to 16 bytes slop beyond this. */
diff --git a/upb/def.c b/upb/def.c
index cdb5a5e..8d5e502 100644
--- a/upb/def.c
+++ b/upb/def.c
@@ -929,7 +929,7 @@
   jmp_buf err;                    /* longjmp() on error. */
 } symtab_addctx;
 
-UPB_NORETURN UPB_NOINLINE
+UPB_NORETURN UPB_NOINLINE UPB_PRINTF(2, 3)
 static void symtab_errf(symtab_addctx *ctx, const char *fmt, ...) {
   va_list argp;
   va_start(argp, fmt);
@@ -1543,7 +1543,7 @@
   return;
 
 invalid:
-  symtab_errf(ctx, "Invalid default '%.*s' for field %f", (int)len, str,
+  symtab_errf(ctx, "Invalid default '%.*s' for field %s", (int)len, str,
               upb_fielddef_fullname(f));
 }
 
diff --git a/upb/json/parser.rl b/upb/json/parser.rl
index a7d75ff..e6a701a 100644
--- a/upb/json/parser.rl
+++ b/upb/json/parser.rl
@@ -1380,7 +1380,8 @@
           ok = true;
           /* TODO(teboring): Should also clean this field. */
         } else {
-          upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", len, buf);
+          upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", (int)len,
+                             buf);
         }
       }
 
@@ -2808,7 +2809,8 @@
   %% write exec;
 
   if (p != pe) {
-    upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p);
+    upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", (int)(pe - p),
+                       p);
   } else {
     capture_suspend(parser, &p);
   }
diff --git a/upb/json_decode.c b/upb/json_decode.c
index bb33744..760f96b 100644
--- a/upb/json_decode.c
+++ b/upb/json_decode.c
@@ -62,6 +62,7 @@
   UPB_LONGJMP(d->err, 1);
 }
 
+UPB_PRINTF(2, 3)
 UPB_NORETURN static void jsondec_errf(jsondec *d, const char *fmt, ...) {
   va_list argp;
   upb_status_seterrf(d->status, "Error parsing JSON @%d:%d: ", d->line,
@@ -678,7 +679,7 @@
       }
       val.int64_val = dbl;  /* must be guarded, overflow here is UB */
       if (val.int64_val != dbl) {
-        jsondec_errf(d, "JSON number was not integral (%d != %" PRId64 ")", dbl,
+        jsondec_errf(d, "JSON number was not integral (%f != %" PRId64 ")", dbl,
                      val.int64_val);
       }
       break;
@@ -704,7 +705,7 @@
 
 /* Parse UINT32 or UINT64 value. */
 static upb_msgval jsondec_uint(jsondec *d, const upb_fielddef *f) {
-  upb_msgval val;
+  upb_msgval val = {0};
 
   switch (jsondec_peek(d)) {
     case JD_NUMBER: {
@@ -714,7 +715,7 @@
       }
       val.uint64_val = dbl;  /* must be guarded, overflow here is UB */
       if (val.uint64_val != dbl) {
-        jsondec_errf(d, "JSON number was not integral (%d != %" PRIu64 ")", dbl,
+        jsondec_errf(d, "JSON number was not integral (%f != %" PRIu64 ")", dbl,
                      val.uint64_val);
       }
       break;
@@ -741,7 +742,7 @@
 /* Parse DOUBLE or FLOAT value. */
 static upb_msgval jsondec_double(jsondec *d, const upb_fielddef *f) {
   upb_strview str;
-  upb_msgval val;
+  upb_msgval val = {0};
 
   switch (jsondec_peek(d)) {
     case JD_NUMBER:
diff --git a/upb/json_encode.c b/upb/json_encode.c
index 9217c65..7bdda51 100644
--- a/upb/json_encode.c
+++ b/upb/json_encode.c
@@ -40,6 +40,7 @@
   longjmp(e->err, 1);
 }
 
+UPB_PRINTF(2, 3)
 UPB_NORETURN static void jsonenc_errf(jsonenc *e, const char *fmt, ...) {
   va_list argp;
   va_start(argp, fmt);
@@ -72,6 +73,7 @@
   jsonenc_putbytes(e, str, strlen(str));
 }
 
+UPB_PRINTF(2, 3)
 static void jsonenc_printf(jsonenc *e, const char *fmt, ...) {
   size_t n;
   size_t have = e->end - e->ptr;
@@ -102,7 +104,7 @@
     digits -= 3;
   }
 
-  jsonenc_printf(e, ".%0.*" PRId32, digits, nanos);
+  jsonenc_printf(e, ".%.*" PRId32, digits, nanos);
 }
 
 static void jsonenc_timestamp(jsonenc *e, const upb_msg *msg,
diff --git a/upb/port_def.inc b/upb/port_def.inc
index 2cd1bb6..8e243a9 100644
--- a/upb/port_def.inc
+++ b/upb/port_def.inc
@@ -80,14 +80,17 @@
 #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
 #define UPB_NOINLINE __attribute__((noinline))
 #define UPB_NORETURN __attribute__((__noreturn__))
+#define UPB_PRINTF(str, first_vararg) __attribute__((format (printf, str, first_vararg)))
 #elif defined(_MSC_VER)
 #define UPB_NOINLINE
 #define UPB_FORCEINLINE
 #define UPB_NORETURN __declspec(noreturn)
+#define UPB_PRINTF(str, first_vararg)
 #else  /* !defined(__GNUC__) */
 #define UPB_FORCEINLINE
 #define UPB_NOINLINE
 #define UPB_NORETURN
+#define UPB_PRINTF(str, first_vararg)
 #endif
 
 #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
diff --git a/upb/upb.h b/upb/upb.h
index 11c0e4d..6c54e87 100644
--- a/upb/upb.h
+++ b/upb/upb.h
@@ -33,9 +33,12 @@
 /* These are no-op if |status| is NULL. */
 void upb_status_clear(upb_status *status);
 void upb_status_seterrmsg(upb_status *status, const char *msg);
-void upb_status_seterrf(upb_status *status, const char *fmt, ...);
-void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args);
-void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args);
+void upb_status_seterrf(upb_status *status, const char *fmt, ...)
+    UPB_PRINTF(2, 3);
+void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args)
+    UPB_PRINTF(2, 0);
+void upb_status_vappenderrf(upb_status *status, const char *fmt, va_list args)
+    UPB_PRINTF(2, 0);
 
 /** upb_strview ************************************************************/