From: Jehan Date: Sun, 15 Mar 2020 22:29:37 +0000 (+0100) Subject: Fixes various Wreturn-type and Wimplicit-fallthrough errors on Mingw-w64 X-Git-Tag: json-c-0.14-20200419~48^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F556%2Fhead;p=thirdparty%2Fjson-c.git Fixes various Wreturn-type and Wimplicit-fallthrough errors on Mingw-w64 This is a recent regression since commit 6359b798479d379a3202e02c6a938d9b40c0d856 which added various assert(0) calls (often replacing return-s). With Ming-W64 compiler, json-c build was failing with various errors of the sort: > /home/jehan/dev/src/json-c/json_object.c: In function 'json_object_int_inc': > /home/jehan/dev/src/json-c/json_object.c:841:1: error: control reaches end of non-void function [-Werror=return-type] > 841 | } > | ^ > In file included from /home/jehan/dev/src/json-c/json_object.c:17: > /home/jehan/dev/src/json-c/json_object.c: In function 'json_object_get_double': > /home/jehan/.local/share/crossroad/roads/w64/json-c/include/assert.h:76:4: error: this statement may fall through [-Werror=implicit-fallthrough=] > 76 | (_assert(#_Expression,__FILE__,__LINE__),0)) > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /home/jehan/dev/src/json-c/json_object.c:1070:7: note: in expansion of macro 'assert' > 1070 | assert(0); > | ^~~~~~ > /home/jehan/dev/src/json-c/json_object.c:1072:3: note: here > 1072 | case json_type_boolean: > | ^~~~ The problem is that Mingw-w64 does not consider assert() as a noreturn (even assert(0)), because it has to be compatible by Microsoft libraries. See the discussion here: https://sourceforge.net/p/mingw-w64/bugs/306/ Instead let's create a new json_abort() function which is basically just an abort() function with an optional message, for such cases where abortion was non-conditional (using assert() and using the assertion condition as a message here was clearly a misuse of the function). And mark json_abort() as 'noreturn', as well as 'cold' for optimization purpose (this is code we expect to never run, unless there is a bug, that is). Finally let's use this json_abort() instead of previous misused assert() calls. --- diff --git a/json_object.c b/json_object.c index 399d8a40..13941506 100644 --- a/json_object.c +++ b/json_object.c @@ -597,7 +597,7 @@ json_bool json_object_get_boolean(const struct json_object *jso) case json_object_int_type_uint64: return (jso->o.c_int.cint.c_uint64 != 0); default: - assert(!"invalid cint_type"); + json_abort("invalid cint_type"); } case json_type_double: return (jso->o.c_double != 0); @@ -734,7 +734,7 @@ int64_t json_object_get_int64(const struct json_object *jso) return INT64_MAX; return (int64_t)jso->o.c_int.cint.c_uint64; default: - assert(!"invalid cint_type"); + json_abort("invalid cint_type"); } case json_type_double: // INT64_MAX can't be exactly represented as a double @@ -772,7 +772,7 @@ uint64_t json_object_get_uint64(const struct json_object *jso) case json_object_int_type_uint64: return jso->o.c_int.cint.c_uint64; default: - assert(!"invalid cint_type"); + json_abort("invalid cint_type"); } case json_type_double: // UINT64_MAX can't be exactly represented as a double @@ -836,7 +836,7 @@ int json_object_int_inc(struct json_object *jso, int64_t val) { } return 1; default: - assert(!"invalid cint_type"); + json_abort("invalid cint_type"); } } @@ -1067,7 +1067,7 @@ double json_object_get_double(const struct json_object *jso) case json_object_int_type_uint64: return jso->o.c_int.cint.c_uint64; default: - assert(!"invalid cint_type"); + json_abort("invalid cint_type"); } case json_type_boolean: return jso->o.c_boolean; diff --git a/json_util.c b/json_util.c index 1c1fa466..b7c25afd 100644 --- a/json_util.c +++ b/json_util.c @@ -282,3 +282,10 @@ const char *json_type_to_name(enum json_type o_type) return json_type_name[o_type]; } +void json_abort(const char *message) +{ + if (message != NULL) + fprintf (stderr, "json-c aborts with error: %s\n", message); + abort(); +} + diff --git a/json_util.h b/json_util.h index 43adca94..83ff62f2 100644 --- a/json_util.h +++ b/json_util.h @@ -112,6 +112,23 @@ JSON_EXPORT int json_parse_double(const char *buf, double *retval); */ JSON_EXPORT const char *json_type_to_name(enum json_type o_type); +#ifndef JSON_NORETURN +#if defined(_MSC_VER) +#define JSON_NORETURN __declspec(noreturn) +#else +/* 'cold' attribute is for optimization, telling the computer this code + * path is unlikely. + */ +#define JSON_NORETURN __attribute__ ((noreturn, cold)) +#endif +#endif +/** + * Abort and optionally print a message on standard error. + * This should be used rather than assert() for unconditional abortion + * (in particular for code paths which are never supposed to be run). + * */ +JSON_NORETURN JSON_EXPORT void json_abort(const char *message); + #ifdef __cplusplus } #endif