commit ad9233a867709195fe1450329b52d2bf1732e935
parent 40bf71ac3e8eeb6e596a738d175c44478a7b3ce6
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Thu, 24 Apr 2025 19:16:23 +0200
Fixed "fallthrough" warnings with modern C versions
Diffstat:
5 files changed, 101 insertions(+), 21 deletions(-)
diff --git a/configure.ac b/configure.ac
@@ -1371,6 +1371,62 @@ AS_IF([test "x${mhd_cv_cc_kwd_unreachable}" != "xnone"],
]
)
+# Check for 'fallthrough' keywords
+save_CFLAGS_ac="${CFLAGS_ac}"
+CFLAGS="${user_CFLAGS}"
+# Use strictest warning flags
+MHD_FIND_ADD_CC_CFLAG([CFLAGS_ac], [-Wimplicit-fallthrough=5],[-Wimplicit-fallthrough=4],[-Wimplicit-fallthrough=3],
+[-Wimplicit-fallthrough])
+AC_CACHE_CHECK([for 'fallthrough' keyword supported by $CC],[mhd_cv_cc_kwd_fallthrough],
+ [
+ mhd_cv_cc_kwd_fallthrough="no"
+ CFLAGS="${CFLAGS_ac} ${user_CFLAGS} ${errattr_CFLAGS}"
+ SAVE_ac_c_werror_flag="$ac_c_werror_flag"
+ ac_c_werror_flag="yes"
+ [for keyword_chk in '[[fallthrough]]' '[[__fallthrough__]]' '[[gnu::fallthrough]]' '[[clang::fallthrough]]' '__attribute__((fallthrough))' '']
+ do
+ AC_LINK_IFELSE([
+ AC_LANG_SOURCE([[
+int main(int argc, char *argv[])
+{
+ int ret = 0;
+ (void) argv;
+ switch (argc)
+ {
+ case 0:
+ ++ret;
+ ${keyword_chk};
+ case 3:
+ ++ret;
+ ${keyword_chk};
+ case 10:
+ ++ret;
+ ${keyword_chk};
+ default:
+ break;
+ }
+ return ret;
+}
+ ]]
+ )
+ ],
+ [mhd_cv_cc_kwd_fallthrough="$keyword_chk"]
+ )
+ test "x${mhd_cv_cc_kwd_fallthrough}" != "xno" && break
+ done
+ AS_IF([test -z "${mhd_cv_cc_kwd_fallthrough}"], [mhd_cv_cc_kwd_fallthrough="none needed"])
+ ac_c_werror_flag="$SAVE_ac_c_werror_flag"
+ ]
+)
+AH_TEMPLATE([mhd_FALLTHROUGH],[Define to keyword marking intentional missing 'break' at the end of 'case:'])
+AS_CASE([${mhd_cv_cc_kwd_fallthrough}],
+ [no],[AC_DEFINE([mhd_FALLTHROUGH],[((void) 0) /* no keyword supported */])],
+ ["none needed"],[AC_DEFINE([mhd_FALLTHROUGH],[((void) 0) /* not needed */])],
+ [AC_DEFINE_UNQUOTED([mhd_FALLTHROUGH],[$mhd_cv_cc_kwd_fallthrough])]
+)
+CFLAGS_ac="${save_CFLAGS_ac}"
+CFLAGS="${CFLAGS_ac} ${user_CFLAGS}"
+
AC_CHECK_HEADERS([stdalign.h], [], [], [AC_INCLUDES_DEFAULT])
AC_CACHE_CHECK([[for C11 'alignof()' support]], [[mhd_cv_c_alignof]],
[AC_COMPILE_IFELSE(
diff --git a/src/incl_priv/mhd_sys_options.h b/src/incl_priv/mhd_sys_options.h
@@ -542,6 +542,8 @@
#ifdef __CDT_PARSER__
# undef MHD_NORETURN_
# define MHD_NORETURN_ __attribute__((__noreturn__))
+# undef mhd_FALLTHROUGH
+# define mhd_FALLTHROUGH ((void) 0)
#endif
/* Avoid interference with third-party headers */
diff --git a/src/mhd2/conn_tls_check.c b/src/mhd2/conn_tls_check.c
@@ -96,7 +96,8 @@ mhd_conn_tls_check (struct MHD_Connection *restrict c)
(((unsigned int) c->sk.ready)
& (~(enum mhd_SocketNetState)
mhd_SOCKET_NET_STATE_RECV_READY));
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_TLS_PROCED_RECV_INTERRUPTED:
c->conn_state = mhd_CONN_STATE_TLS_HANDSHAKE_RECV;
c->event_loop_info = MHD_EVENT_LOOP_INFO_RECV;
@@ -106,7 +107,8 @@ mhd_conn_tls_check (struct MHD_Connection *restrict c)
(((unsigned int) c->sk.ready)
& (~(enum mhd_SocketNetState)
mhd_SOCKET_NET_STATE_SEND_READY));
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_TLS_PROCED_SEND_INTERRUPTED:
c->conn_state = mhd_CONN_STATE_TLS_HANDSHAKE_SEND;
c->event_loop_info = MHD_EVENT_LOOP_INFO_SEND;
diff --git a/src/mhd2/daemon_start.c b/src/mhd2/daemon_start.c
@@ -206,6 +206,7 @@ daemon_set_work_mode (struct MHD_Daemon *restrict d,
"is not compatible with 'epoll' sockets polling.");
return MHD_SC_SYSCALL_WORK_MODE_COMBINATION_INVALID;
}
+ mhd_FALLTHROUGH;
/* Intentional fallthrough */
case MHD_WM_WORKER_THREADS:
#ifndef MHD_SUPPORT_THREADS
diff --git a/src/mhd2/post_parser_funcs.c b/src/mhd2/post_parser_funcs.c
@@ -1199,7 +1199,8 @@ parse_post_urlenc (struct MHD_Connection *restrict c,
uf->name_idx = i;
uf->last_pct_idx = mhd_POST_INVALID_POS;
uf->st = mhd_POST_UENC_ST_NAME;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_UENC_ST_NAME:
do /* Fast local loop */
{
@@ -1251,7 +1252,8 @@ parse_post_urlenc (struct MHD_Connection *restrict c,
uf->last_pct_idx = mhd_POST_INVALID_POS;
uf->value_idx = i;
uf->st = mhd_POST_UENC_ST_VALUE;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_UENC_ST_VALUE:
do /* Fast local loop */
{
@@ -1301,7 +1303,8 @@ parse_post_urlenc (struct MHD_Connection *restrict c,
buf[uf->name_idx + uf->name_len] = 0; /* Zero-terminate the name */
}
uf->st = mhd_POST_UENC_ST_FULL_FIELD_FOUND;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_UENC_ST_FULL_FIELD_FOUND:
++i; /* Consume current character,
advance to the next char to be checked */
@@ -1442,7 +1445,8 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mhd_assert (mhd_POST_INVALID_POS != mf->delim_check_start);
mf->line_start = mhd_POST_INVALID_POS;
mf->st = mhd_POST_MPART_ST_PREAMBL;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_PREAMBL:
mhd_assert (0 == p_data->value_off);
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start);
@@ -1482,13 +1486,15 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mhd_assert (0 == p_data->value_off);
mf->delim_check_start = mhd_POST_INVALID_POS; /* Ignored for first delimiter */
p_data->field_start = i;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_PREAMBL_LINE_START:
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start);
mhd_assert (mhd_POST_INVALID_POS == mf->line_start);
mf->line_start = i;
mf->st = mhd_POST_MPART_ST_PREAMBL_CHECKING_FOR_DELIM;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_PREAMBL_CHECKING_FOR_DELIM:
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start); /* Ignored for first delimiter */
mhd_assert (i >= mf->line_start);
@@ -1575,18 +1581,21 @@ parse_post_mpart (struct MHD_Connection *restrict c,
i = p_data->field_start;
}
mf->delim_check_start = p_data->field_start;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_PART_START:
mhd_assert (0 == mf->f.name_len);
mhd_assert (0 == p_data->value_off);
mhd_assert (mhd_POST_INVALID_POS != mf->delim_check_start);
p_data->field_start = mf->delim_check_start;
mf->delim_check_start = mhd_POST_INVALID_POS;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_HEADER_LINE_START:
mf->line_start = i;
mf->st = mhd_POST_MPART_ST_HEADER_LINE;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_HEADER_LINE:
mhd_assert (i >= mf->line_start);
mhd_assert (mhd_POST_INVALID_POS != mf->line_start);
@@ -1640,7 +1649,8 @@ parse_post_mpart (struct MHD_Connection *restrict c,
continue;
}
mf->st = mhd_POST_MPART_ST_HEADER_LINE_END;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_HEADER_LINE_END:
mhd_assert (mhd_POST_INVALID_POS != p_data->field_start);
mhd_assert (i >= mf->line_start);
@@ -1848,13 +1858,15 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mhd_assert (0 != mf->f.name_len);
mhd_assert (i > mf->f.name_idx);
mf->f.value_idx = i;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_BACK_TO_VALUE:
mhd_assert (mhd_POST_INVALID_POS != p_data->field_start);
mf->line_start = mhd_POST_INVALID_POS;
mf->delim_check_start = mhd_POST_INVALID_POS;
mf->st = mhd_POST_MPART_ST_VALUE;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_VALUE:
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start);
mhd_assert (mhd_POST_INVALID_POS == mf->line_start);
@@ -1894,7 +1906,8 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mhd_assert (mhd_POST_INVALID_POS != p_data->field_start);
mf->line_start = i;
mf->st = mhd_POST_MPART_ST_VALUE_CHECKING_FOR_DELIM;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_VALUE_CHECKING_FOR_DELIM:
mhd_assert (mhd_POST_INVALID_POS != p_data->field_start);
mhd_assert (i >= mf->line_start);
@@ -1982,7 +1995,8 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mf->st = mhd_POST_MPART_ST_FULL_FIELD_FOUND;
else
mf->st = mhd_POST_MPART_ST_FULL_FIELD_FOUND_FINAL;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_FULL_FIELD_FOUND:
case mhd_POST_MPART_ST_FULL_FIELD_FOUND_FINAL:
mhd_assert (mhd_POST_INVALID_POS != mf->delim_check_start);
@@ -2172,7 +2186,8 @@ parse_post_text (struct MHD_Connection *restrict c,
p_data->field_start = i;
tf->name_idx = i;
tf->st = mhd_POST_TEXT_ST_NAME;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_TEXT_ST_NAME:
do /* Fast local loop */
{
@@ -2211,7 +2226,8 @@ parse_post_text (struct MHD_Connection *restrict c,
mhd_assert (0 != i && "the 'value' should follow the 'name'");
tf->value_idx = i;
tf->st = mhd_POST_TEXT_ST_VALUE;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_TEXT_ST_VALUE:
do /* Fast local loop */
{
@@ -2236,7 +2252,8 @@ parse_post_text (struct MHD_Connection *restrict c,
enc_broken = true;
break;
}
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_TEXT_ST_AT_CR:
mhd_assert (0 == tf->value_len);
buf[i] = 0; /* Zero-terminate the value (or the name) */
@@ -2265,7 +2282,8 @@ parse_post_text (struct MHD_Connection *restrict c,
break;
}
tf->st = mhd_POST_TEXT_ST_FULL_LINE_FOUND;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_TEXT_ST_FULL_LINE_FOUND:
++i; /* Advance to the next char to be checked */
if (process_complete_field (c,
@@ -2674,7 +2692,8 @@ check_post_leftovers_mpart (struct MHD_Connection *restrict c,
break;
case mhd_POST_MPART_ST_FULL_FIELD_FOUND:
not_terminated = true;
- /* Intentional fall-through */
+ mhd_FALLTHROUGH;
+ /* Intentional fallthrough */
case mhd_POST_MPART_ST_FULL_FIELD_FOUND_FINAL:
mhd_assert (0 != mf->f.name_idx);
add_field = true;