expand implicit fallthrough detection to non-gcc compilers
gcc has recognized various "magic comments" for white-listing
occurrences of implicit fallthrough in switch statements for
a long time:
The range and shape of "falls through" comments accepted are
contingent upon the level of the warning. (The default level is =3.)
-Wimplicit-fallthrough=0 disables the warning altogether.
-Wimplicit-fallthrough=1 treats any kind of comment as a "falls through" comment.
-Wimplicit-fallthrough=2 essentially accepts any comment that contains something
that matches (case insensitively) "falls?[ \t-]*thr(ough|u)" regular expression.
-Wimplicit-fallthrough=3 case sensitively matches a wide range of regular
expressions, listed in the GCC manual. E.g., all of these are accepted:
/* Falls through. */
/* fall-thru */
/* Else falls through. */
/* FALLTHRU */
/* ... falls through ... */
etc.
-Wimplicit-fallthrough=4 also, case sensitively matches a range of regular
expressions but is much more strict than level =3.
-Wimplicit-fallthrough=5 doesn't recognize any comments.
Plenty of other compilers did not recognize the gcc comment convention,
and up until now the compiler warning for detecting unintended
fallthrough had to be suppressed on other compilers. That's because the code
in NetHack has been relying on the gcc approach, and only the gcc approach.
The C23 standard introduces an attribute [[fallthrough]] for the
functionality, when implicit fallthrough warnings have been enabled.
Several popular compilers already support that, or a very similar attribute
style approach, today, even ahead of their C23 support:
C compiler whitelist approach
--------------------------- -------------------------------------
C23 conforming compilers [[fallthrough]]
clang versions supporting
standards prior to
C23 __attribute__((__fallthrough__))
Microsoft Visual Studio
since VS 2022 17.4.
The warning C5262 controls
whether the implict
fallthrough is detected and
warned about with
/std:clatest. [[fallthrough]]
This adds support to NetHack for the attribute approach by inserting a
macro FALLTHROUGH to the existing cases that require white-listing, so
other compilers can analyze things too.
The definition of the FALLTHROUGH macro is controlled in include/tradstdc.h.
The gcc comment approach has also been left in place at this time.
This commit is contained in:
@@ -271,6 +271,7 @@ void NetHackQtBind::qt_askname()
|
||||
// success; handle plname[] verification below prior to returning
|
||||
break;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case -2:
|
||||
// Quit
|
||||
@@ -726,6 +727,7 @@ char NetHackQtBind::qt_more()
|
||||
switch (ch) {
|
||||
case '\0': // hypothetical
|
||||
ch = '\033';
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case ' ':
|
||||
case '\n':
|
||||
|
||||
@@ -1556,6 +1556,7 @@ menu_get_selections(WINDOW *win, nhmenu *menu, int how)
|
||||
break;
|
||||
}
|
||||
}
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
default:
|
||||
if (curletter > 0 && curletter < 256
|
||||
|
||||
@@ -114,6 +114,7 @@ curses_create_main_windows(void)
|
||||
|
||||
case 3:
|
||||
noperminv_borders = TRUE;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case 1: /* On */
|
||||
borders = TRUE;
|
||||
@@ -121,6 +122,7 @@ curses_create_main_windows(void)
|
||||
|
||||
case 4:
|
||||
noperminv_borders = TRUE;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case 2: /* Auto */
|
||||
borders = (term_cols >= 80 + 2 && term_rows >= 24 + 2);
|
||||
|
||||
@@ -291,7 +291,7 @@ curses_break_str(const char *str, int width, int line_num)
|
||||
char *retstr;
|
||||
int curline = 0;
|
||||
int strsize = (int) strlen(str) + 1;
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) && !defined(_MSC_VER)
|
||||
char substr[strsize];
|
||||
char curstr[strsize];
|
||||
char tmpstr[strsize];
|
||||
@@ -363,7 +363,7 @@ curses_str_remainder(const char *str, int width, int line_num)
|
||||
char *retstr;
|
||||
int curline = 0;
|
||||
int strsize = strlen(str) + 1;
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#if (__STDC_VERSION__ >= 199901L) && !defined(_MSC_VER)
|
||||
char substr[strsize];
|
||||
char tmpstr[strsize];
|
||||
|
||||
@@ -801,6 +801,7 @@ curses_convert_keys(int key)
|
||||
a value for ^H greater than 255 is passed back to core's
|
||||
readchar() and stripping the value down to 0..255 yields ^G! */
|
||||
ret = C('H');
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
default:
|
||||
if (modifiers_available)
|
||||
|
||||
@@ -415,6 +415,7 @@ draw_horizontal(boolean border)
|
||||
w -= (t - 30); /* '+= strlen()' below will add 't';
|
||||
* functional result being 'w += 30' */
|
||||
}
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case BL_ALIGN:
|
||||
case BL_LEVELDESC:
|
||||
@@ -1231,6 +1232,7 @@ curs_vert_status_vals(int win_width)
|
||||
if (fld_width < hp_width + 3) /* +3: " " gap and "("...")" */
|
||||
Sprintf(leadingspace, "%*s",
|
||||
(hp_width + 3) - fld_width, " ");
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case BL_VERS:
|
||||
case BL_EXP:
|
||||
|
||||
@@ -98,6 +98,7 @@ curses_create_window(int wid, int width, int height, orient orientation)
|
||||
switch (orientation) {
|
||||
default:
|
||||
impossible("curses_create_window: Bad orientation");
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case CENTER:
|
||||
startx = (term_cols / 2) - (width / 2);
|
||||
|
||||
@@ -1341,6 +1341,7 @@ s_atr2str(int n)
|
||||
/* if italic isn't available, fall through to underline */
|
||||
if (ZH && *ZH)
|
||||
return ZH;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case ATR_BLINK:
|
||||
case ATR_ULINE:
|
||||
@@ -1351,6 +1352,7 @@ s_atr2str(int n)
|
||||
if (nh_US && *nh_US)
|
||||
return nh_US;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case ATR_BOLD:
|
||||
if (MD && *MD)
|
||||
@@ -1378,15 +1380,18 @@ e_atr2str(int n)
|
||||
/* send ZR unless we didn't have ZH and substituted US */
|
||||
if (ZR && *ZR && ZH && *ZH)
|
||||
return ZR;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case ATR_ULINE:
|
||||
if (nh_UE && *nh_UE)
|
||||
return nh_UE;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case ATR_BOLD:
|
||||
case ATR_BLINK:
|
||||
if (nh_HE && *nh_HE)
|
||||
return nh_HE;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case ATR_DIM:
|
||||
case ATR_INVERSE:
|
||||
|
||||
@@ -665,6 +665,7 @@ tty_askname(void)
|
||||
case -1:
|
||||
bail("Until next time then..."); /* quit */
|
||||
/*NOTREACHED*/
|
||||
break;
|
||||
case 0:
|
||||
break; /* no game chosen; start new game */
|
||||
case 1:
|
||||
@@ -1084,6 +1085,7 @@ tty_clear_nhwindow(winid window)
|
||||
case NHW_MAP:
|
||||
/* cheap -- clear the whole thing and tell nethack to redraw botl */
|
||||
disp.botlx = TRUE;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case NHW_BASE:
|
||||
/* if erasing_tty_screen is True, calling sequence is
|
||||
@@ -1721,6 +1723,7 @@ process_menu_window(winid window, struct WinDesc *cw)
|
||||
break;
|
||||
case MENU_EXPLICIT_CHOICE:
|
||||
morc = really_morc;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
default:
|
||||
if (cw->how == PICK_NONE || !strchr(resp, morc)) {
|
||||
@@ -1878,12 +1881,14 @@ tty_display_nhwindow(
|
||||
tty_display_nhwindow(WIN_MESSAGE, TRUE);
|
||||
return;
|
||||
}
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case NHW_BASE:
|
||||
(void) fflush(stdout);
|
||||
break;
|
||||
case NHW_TEXT:
|
||||
cw->maxcol = ttyDisplay->cols; /* force full-screen mode */
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case NHW_MENU:
|
||||
cw->active = 1;
|
||||
@@ -1951,6 +1956,7 @@ tty_dismiss_nhwindow(winid window)
|
||||
if (ttyDisplay->toplin != TOPLINE_EMPTY)
|
||||
tty_display_nhwindow(WIN_MESSAGE, TRUE);
|
||||
nhassert(ttyDisplay->toplin == TOPLINE_EMPTY);
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case NHW_STATUS:
|
||||
case NHW_BASE:
|
||||
@@ -4438,6 +4444,7 @@ tty_status_update(
|
||||
switch (fldidx) {
|
||||
case BL_RESET:
|
||||
reset_state = FORCE_RESET;
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case BL_FLUSH:
|
||||
if (make_things_fit(reset_state) || truncation_expected) {
|
||||
@@ -4458,6 +4465,7 @@ tty_status_update(
|
||||
break;
|
||||
case BL_GOLD:
|
||||
text = decode_mixed(goldbuf, text);
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
default:
|
||||
attrmask = (color >> 8) & 0x00FF;
|
||||
@@ -4506,6 +4514,7 @@ tty_status_update(
|
||||
break;
|
||||
case BL_LEVELDESC:
|
||||
dlvl_shrinklvl = 0; /* caller is passing full length string */
|
||||
FALLTHROUGH;
|
||||
/*FALLTHRU*/
|
||||
case BL_HUNGER:
|
||||
/* The core sends trailing blanks for some fields.
|
||||
|
||||
@@ -146,7 +146,8 @@ GetlinDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
(WPARAM) sizeof(wbuf2), (LPARAM) wbuf2);
|
||||
NH_W2A(wbuf2, data->result, data->result_size);
|
||||
|
||||
/* Fall through. */
|
||||
FALLTHROUGH;
|
||||
/* FALLTHRU */
|
||||
|
||||
/* cancel button was pressed */
|
||||
case IDCANCEL:
|
||||
@@ -246,7 +247,8 @@ ExtCmdDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
hWnd, IDC_EXTCMD_LIST, LB_GETCURSEL, (WPARAM) 0, (LPARAM) 0);
|
||||
if (*data->selection == LB_ERR)
|
||||
*data->selection = -1;
|
||||
/* Fall through. */
|
||||
FALLTHROUGH;
|
||||
/* FALLTHRU */
|
||||
|
||||
/* CANCEL button ws clicked */
|
||||
case IDCANCEL:
|
||||
|
||||
Reference in New Issue
Block a user