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 ************************************************************/