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:
@@ -327,13 +327,20 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */
|
||||
/*
|
||||
* Give first priority to standard
|
||||
*/
|
||||
#ifndef ATTRNORETURN
|
||||
#if defined(__STDC_VERSION__) || defined(__cplusplus)
|
||||
#if (__STDC_VERSION__ > 202300L) || defined(__cplusplus)
|
||||
#ifndef ATTRNORETURN
|
||||
#define ATTRNORETURN [[noreturn]]
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifndef __has_c_attribute
|
||||
#define __has_c_attribute(x) 0
|
||||
#endif /* __has_c_attribute */
|
||||
#if __has_c_attribute(fallthrough)
|
||||
/* Standard attribute is available, use it. */
|
||||
#define FALLTHROUGH [[fallthrough]]
|
||||
#endif /* __has_c_attribute(fallthrough) */
|
||||
#endif /* __STDC_VERSION__ gt 202300L || __cplusplus */
|
||||
#endif /* __STDC_VERSION || __cplusplus */
|
||||
|
||||
/*
|
||||
* Allow gcc2 to check parameters of printf-like calls with -Wformat;
|
||||
@@ -366,12 +373,21 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */
|
||||
#endif /* !NONNULLS_DEFINED */
|
||||
/* #pragma message is available */
|
||||
#define NH_PRAGMA_MESSAGE 1
|
||||
#endif
|
||||
#endif
|
||||
#endif /* __GNUC__ greater than or equal to 5 */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#if defined(__clang__) && !defined(DO_DEFINE_NONNULLS)
|
||||
#if defined(__clang__)
|
||||
#ifndef FALLTHROUGH
|
||||
#if defined(__clang_major__)
|
||||
#if __clang_major__ >= 9
|
||||
#define FALLTHROUGH __attribute__((fallthrough))
|
||||
#endif /* __clang_major__ greater than or equal to 9 */
|
||||
#endif /* __clang_major__ is defined */
|
||||
#endif /* FALLTHROUGH */
|
||||
#if !defined(DO_DEFINE_NONNULLS)
|
||||
#define DO_DEFINE_NONNULLS
|
||||
#endif
|
||||
#endif /* __clang__ */
|
||||
|
||||
#if defined(DO_DEFINE_NONNULLS) && !defined(NONNULLS_DEFINED)
|
||||
#define NONNULL __attribute__((returns_nonnull))
|
||||
@@ -405,6 +421,7 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */
|
||||
#define NH_PRAGMA_MESSAGE 1
|
||||
#endif
|
||||
|
||||
/* Fallback implementations */
|
||||
#ifndef PRINTF_F
|
||||
#define PRINTF_F(f, v)
|
||||
#endif
|
||||
@@ -414,6 +431,9 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */
|
||||
#ifndef UNUSED
|
||||
#define UNUSED
|
||||
#endif
|
||||
#ifndef FALLTHROUGH
|
||||
#define FALLTHROUGH
|
||||
#endif
|
||||
#ifndef ATTRNORETURN
|
||||
#define ATTRNORETURN
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user