Support __attribute__((fallthrough)) if possible.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2017-12-16 20:52:39 +03:00
parent 3ae7ad4449
commit 73979369d1
24 changed files with 287 additions and 37 deletions

View File

@ -2,6 +2,7 @@ m4_include([m4.include/ac_onceonly.m4])
m4_include([m4.include/ax_path_lib_pcre.m4])
m4_include([m4.include/dx_doxygen.m4])
m4_include([m4.include/mc-cflags.m4])
m4_include([m4.include/ax_gcc_func_attribute.m4])
m4_include([m4.include/mc-check-search-type.m4])
m4_include([m4.include/mode_t.m4])
m4_include([m4.include/stat-size.m4])

View File

@ -45,6 +45,8 @@ if test "x$enable_werror" = xyes; then
mc_CHECK_ONE_CFLAG([-Werror])
fi
AX_GCC_FUNC_ATTRIBUTE([fallthrough])
AC_PROG_LIBTOOL

View File

@ -27,6 +27,12 @@
/* for sig_atomic_t */
#include <signal.h>
#ifdef HAVE_FUNC_ATTRIBUTE_FALLTHROUGH
#define MC_FALLTHROUGH __attribute__((fallthrough))
#else
#define MC_FALLTHROUGH
#endif
/*** typedefs(not structures) and defined constants **********************************************/
/* The O_BINARY definition was taken from gettext */

View File

@ -71,7 +71,7 @@ mc_search__normal_translate_to_regex (const GString * astr)
case '-':
case '|':
g_string_append_c (buff, '\\');
/* fall through */
MC_FALLTHROUGH;
default:
g_string_append_c (buff, str[loop]);
break;

View File

@ -641,7 +641,7 @@ command_completion_function (const char *text, int state, input_complete_t flags
}
phase++;
words = bash_builtins;
/* fallthrough */
MC_FALLTHROUGH;
case 1: /* Builtin commands */
for (; *words != NULL; words++)
if (strncmp (*words, u_text, text_len) == 0)
@ -654,7 +654,7 @@ command_completion_function (const char *text, int state, input_complete_t flags
break;
cur_path = path;
cur_word = NULL;
/* fallthrough */
MC_FALLTHROUGH;
case 2: /* And looking through the $PATH */
while (found == NULL)
{
@ -675,7 +675,7 @@ command_completion_function (const char *text, int state, input_complete_t flags
if (found == NULL)
MC_PTR_FREE (cur_word);
}
/* fallthrough */
MC_FALLTHROUGH;
default:
break;
}
@ -1107,7 +1107,7 @@ query_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d
{
case -1:
bl = 0;
/* fallthrough */
MC_FALLTHROUGH;
case -2:
return MSG_HANDLED;
default:

View File

@ -441,7 +441,7 @@ quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip)
break;
}
}
/* fall through */
MC_FALLTHROUGH;
case quick_checkbox:
case quick_radio:
if (item->widget->x != x1)

View File

@ -105,7 +105,7 @@ query_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm,
return MSG_HANDLED;
}
/* fallthrough */
MC_FALLTHROUGH;
default:
return dlg_default_callback (w, sender, msg, parm, data);

View File

@ -0,0 +1,238 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
#
# DESCRIPTION
#
# This macro checks if the compiler supports one of GCC's function
# attributes; many other compilers also provide function attributes with
# the same syntax. Compiler warnings are used to detect supported
# attributes as unsupported ones are ignored by default so quieting
# warnings when using this macro will yield false positives.
#
# The ATTRIBUTE parameter holds the name of the attribute to be checked.
#
# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
#
# The macro caches its result in the ax_cv_have_func_attribute_<attribute>
# variable.
#
# The macro currently supports the following function attributes:
#
# alias
# aligned
# alloc_size
# always_inline
# artificial
# cold
# const
# constructor
# constructor_priority for constructor attribute with priority
# deprecated
# destructor
# dllexport
# dllimport
# error
# externally_visible
# fallthrough
# flatten
# format
# format_arg
# gnu_inline
# hot
# ifunc
# leaf
# malloc
# noclone
# noinline
# nonnull
# noreturn
# nothrow
# optimize
# pure
# sentinel
# sentinel_position
# unused
# used
# visibility
# warning
# warn_unused_result
# weak
# weakref
#
# Unsupported function attributes will be tested with a prototype
# returning an int and not accepting any arguments and the result of the
# check might be wrong or meaningless so use with care.
#
# LICENSE
#
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 9
AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([
m4_case([$1],
[alias], [
int foo( void ) { return 0; }
int bar( void ) __attribute__(($1("foo")));
],
[aligned], [
int foo( void ) __attribute__(($1(32)));
],
[alloc_size], [
void *foo(int a) __attribute__(($1(1)));
],
[always_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[artificial], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[cold], [
int foo( void ) __attribute__(($1));
],
[const], [
int foo( void ) __attribute__(($1));
],
[constructor_priority], [
int foo( void ) __attribute__((__constructor__(65535/2)));
],
[constructor], [
int foo( void ) __attribute__(($1));
],
[deprecated], [
int foo( void ) __attribute__(($1("")));
],
[destructor], [
int foo( void ) __attribute__(($1));
],
[dllexport], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[dllimport], [
int foo( void ) __attribute__(($1));
],
[error], [
int foo( void ) __attribute__(($1("")));
],
[externally_visible], [
int foo( void ) __attribute__(($1));
],
[fallthrough], [
int foo( void ) {switch (0) { case 1: __attribute__(($1)); case 2: break ; }};
],
[flatten], [
int foo( void ) __attribute__(($1));
],
[format], [
int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
],
[format_arg], [
char *foo(const char *p) __attribute__(($1(1)));
],
[gnu_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[hot], [
int foo( void ) __attribute__(($1));
],
[ifunc], [
int my_foo( void ) { return 0; }
static int (*resolve_foo(void))(void) { return my_foo; }
int foo( void ) __attribute__(($1("resolve_foo")));
],
[leaf], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[malloc], [
void *foo( void ) __attribute__(($1));
],
[noclone], [
int foo( void ) __attribute__(($1));
],
[noinline], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[nonnull], [
int foo(char *p) __attribute__(($1(1)));
],
[noreturn], [
void foo( void ) __attribute__(($1));
],
[nothrow], [
int foo( void ) __attribute__(($1));
],
[optimize], [
__attribute__(($1(3))) int foo( void ) { return 0; }
],
[pure], [
int foo( void ) __attribute__(($1));
],
[sentinel], [
int foo(void *p, ...) __attribute__(($1));
],
[sentinel_position], [
int foo(void *p, ...) __attribute__(($1(1)));
],
[returns_nonnull], [
void *foo( void ) __attribute__(($1));
],
[unused], [
int foo( void ) __attribute__(($1));
],
[used], [
int foo( void ) __attribute__(($1));
],
[visibility], [
int foo_def( void ) __attribute__(($1("default")));
int foo_hid( void ) __attribute__(($1("hidden")));
int foo_int( void ) __attribute__(($1("internal")));
int foo_pro( void ) __attribute__(($1("protected")));
],
[warning], [
int foo( void ) __attribute__(($1("")));
],
[warn_unused_result], [
int foo( void ) __attribute__(($1));
],
[weak], [
int foo( void ) __attribute__(($1));
],
[weakref], [
static int foo( void ) { return 0; }
static int bar( void ) __attribute__(($1("foo")));
],
[
m4_warn([syntax], [Unsupported attribute $1, the test may fail])
int foo( void ) __attribute__(($1));
]
)], [])
],
dnl GCC doesn't exit with an error if an unknown attribute is
dnl provided but only outputs a warning, so accept the attribute
dnl only if no warning were issued.
[AS_IF([test -s conftest.err],
[AS_VAR_SET([ac_var], [no])],
[AS_VAR_SET([ac_var], [yes])])],
[AS_VAR_SET([ac_var], [no])])
])
AS_IF([test yes = AS_VAR_GET([ac_var])],
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
[Define to 1 if the system has the `$1' function attribute])], [])
AS_VAR_POPDEF([ac_var])
])

View File

@ -63,6 +63,7 @@ dnl Sorted -W options:
mc_CHECK_ONE_CFLAG([-Wformat-security])
mc_CHECK_ONE_CFLAG([-Wformat-signedness])
mc_CHECK_ONE_CFLAG([-Wimplicit])
mc_CHECK_ONE_CFLAG([-Wimplicit-fallthrough])
mc_CHECK_ONE_CFLAG([-Wignored-qualifiers])
mc_CHECK_ONE_CFLAG([-Wlogical-not-parentheses])
mc_CHECK_ONE_CFLAG([-Wmaybe-uninitialized])

View File

@ -831,7 +831,7 @@ mc_setup_by_args (int argc, char **argv, GError ** mcerror)
_("Two files are required to envoke the diffviewer."));
return FALSE;
}
/* fallthrough */
MC_FALLTHROUGH;
#endif /* USE_DIFF_VIEW */
case MC_RUN_FULL:

View File

@ -3106,7 +3106,7 @@ dview_ok_to_exit (WDiff * dview)
res = mc_util_unlink_backup_if_possible (dview->file[DIFF_LEFT], "~~~");
if (mc_util_restore_from_backup_if_possible (dview->file[DIFF_RIGHT], "~~~"))
res = mc_util_unlink_backup_if_possible (dview->file[DIFF_RIGHT], "~~~");
/* fall through */
MC_FALLTHROUGH;
default:
res = TRUE;
break;

View File

@ -233,7 +233,7 @@ edit_save_file (WEdit * edit, const vfs_path_t * filename_vpath)
{
case 0:
this_save_mode = EDIT_SAFE_SAVE;
/* fallthrough */
MC_FALLTHROUGH;
case 1:
edit->skip_detach_prompt = 1;
break;
@ -1777,7 +1777,7 @@ edit_save_as_cmd (WEdit * edit)
return TRUE;
default:
edit_error_dialog (_("Save as"), get_sys_error (_("Cannot save file")));
/* fallthrough */
MC_FALLTHROUGH;
case -1:
/* Failed, so maintain modify (not save) lock */
if (save_lock)

View File

@ -731,7 +731,7 @@ edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_c
col++;
break;
}
/* fallthrough */
MC_FALLTHROUGH;
default:
#ifdef HAVE_CHARSET
if (mc_global.utf8_display)

View File

@ -1115,7 +1115,7 @@ edit_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
}
}
/* fall through to start/stop text selection */
MC_FALLTHROUGH; /* to start/stop text selection */
case MSG_MOUSE_UP:
edit_update_cursor (edit, event);

View File

@ -358,7 +358,7 @@ perm_button_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, v
{
case '*':
parm = '=';
/* fallthrough */
MC_FALLTHROUGH;
case '-':
case '=':
@ -393,15 +393,15 @@ perm_button_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, v
case 'x':
i++;
/* fallthrough */
MC_FALLTHROUGH;
case 'w':
i++;
/* fallthrough */
MC_FALLTHROUGH;
case 'r':
b->hotpos = i;
/* fallthrough */
MC_FALLTHROUGH;
case ' ':
i = b->hotpos;
@ -416,11 +416,11 @@ perm_button_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, v
case '4':
i++;
/* fallthrough */
MC_FALLTHROUGH;
case '2':
i++;
/* fallthrough */
MC_FALLTHROUGH;
case '1':
b->hotpos = i;
@ -450,7 +450,7 @@ perm_button_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
case MSG_MOUSE_DOWN:
/* place cursor on flag that is being modified */
BUTTON (w)->hotpos = CLAMP (event->x - 1, 0, 2);
/* fallthrough */
MC_FALLTHROUGH;
default:
button_mouse_default_callback (w, msg, event);
@ -672,11 +672,11 @@ advanced_chown_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm
{
case ALT ('x'):
i++;
/* fallthrough */
MC_FALLTHROUGH;
case ALT ('w'):
i++;
/* fallthrough */
MC_FALLTHROUGH;
case ALT ('r'):
parm = i + 3;
@ -689,11 +689,11 @@ advanced_chown_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm
case XCTRL ('x'):
i++;
/* fallthrough */
MC_FALLTHROUGH;
case XCTRL ('w'):
i++;
/* fallthrough */
MC_FALLTHROUGH;
case XCTRL ('r'):
parm = i;

View File

@ -351,7 +351,7 @@ command_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
/* Special case: we handle the enter key */
if (parm == '\n')
return enter (INPUT (w));
/* fall through */
MC_FALLTHROUGH;
default:
return input_callback (w, sender, msg, parm, data);

View File

@ -702,7 +702,7 @@ check_progress_buttons (file_op_context_t * ctx)
ctx->suspended = !ctx->suspended;
place_progress_buttons (ui->op_dlg, ctx->suspended);
dlg_redraw (ui->op_dlg);
/* fallthrough */
MC_FALLTHROUGH;
default:
if (ctx->suspended)
goto get_event;
@ -1143,9 +1143,11 @@ file_progress_real_query_replace (file_op_context_t * ctx,
case REPLACE_REGET:
/* Careful: we fall through and set do_append */
ctx->do_reget = _d_stat->st_size;
MC_FALLTHROUGH;
case REPLACE_APPEND:
ctx->do_append = TRUE;
MC_FALLTHROUGH;
case REPLACE_YES:
case REPLACE_ALWAYS:

View File

@ -540,7 +540,7 @@ find_parm_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, voi
}
first_draw = FALSE;
/* fall through to call MSG_DRAW default handler */
MC_FALLTHROUGH; /* to call MSG_DRAW default handler */
default:
return dlg_default_callback (w, sender, msg, parm, data);

View File

@ -449,9 +449,9 @@ hotlist_run_cmd (int action)
fill_listbox (list);
return 0;
}
/* Fall through - go up */
MC_FALLTHROUGH; /* go up */
}
/* Fall through if list empty - just go up */
MC_FALLTHROUGH; /* if list empty - just go up */
case B_UP_GROUP:
{
@ -466,7 +466,7 @@ hotlist_run_cmd (int action)
#ifdef ENABLE_VFS
case B_FREE_ALL_VFS:
vfs_expire (TRUE);
/* fall through */
MC_FALLTHROUGH;
case B_REFRESH_VFS:
listbox_remove_list (l_hotlist);
@ -1289,7 +1289,7 @@ hot_next_token (void)
if (c == '\n')
goto again;
/* fall through; it is taken as normal character */
MC_FALLTHROUGH; /* it is taken as normal character */
default:
do

View File

@ -3873,7 +3873,7 @@ panel_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
if (!is_active)
change_panel ();
/* fall through */
MC_FALLTHROUGH;
case MSG_MOUSE_DRAG:
{

View File

@ -883,7 +883,7 @@ expand_format (const WEdit * edit_widget, char c, gboolean do_quote)
goto ret;
}
/* Fall through */
MC_FALLTHROUGH;
case 't':
case 'u':

View File

@ -687,7 +687,7 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
}
if (code != COMPLETE)
break;
/* fall through */
MC_FALLTHROUGH;
case COMPLETE:
vfs_print_message ("%s", _("ftpfs: logged in"));

View File

@ -817,7 +817,7 @@ tar_open_archive (struct vfs_s_super *archive, const vfs_path_t * vpath,
{
message (D_ERROR, MSG_ERROR, _("%s\ndoesn't look like a tar archive."),
vfs_path_as_str (vpath));
/* FALL THRU */
MC_FALLTHROUGH;
/* Error after header rec */
}
@ -836,7 +836,7 @@ tar_open_archive (struct vfs_s_super *archive, const vfs_path_t * vpath,
/* Record of zeroes */
case STATUS_EOFMARK: /* If error after 0's */
/* FALL THRU */
MC_FALLTHROUGH;
/* exit from loop */
case STATUS_EOF: /* End of archive */
break;

View File

@ -106,7 +106,7 @@ mcview_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
change_panel ();
}
}
/* fall through */
MC_FALLTHROUGH;
case MSG_MOUSE_CLICK:
if (!view->text_wrap_mode)