Files
nethack/include/warnings.h
nhmall a6631e3bb0 suppress a particular warning for an individual function; useful for non-gcc
Microsoft and other non-GNU compilers don't recognize gcc tricks
like  /*NOTREACHED*/ to suppress individual warnings. clang recognizes most
of them because it tries to be gcc-compatible. Because of that, a lot of
potentially useful warnings have had to be completely suppressed in the
past in all source files when using the non-gcc compatible compilers.

Now that the code is C99, take advantage of a way to suppress warnings for
individual functions, a big step up from suppressing the warnings
altogether.

Unfortunately, it does require a bit of ugliness caused by the
insertion of some macros in a few spots, but I'm not aware of
a cleaner alternative that still allows warnings to be enabled
in general, while suppressing a warning for known white-listed
instances.

Prior to the warning-tiggering function, place whichever one of
the following is needed to suppress the warning being encountered:

DISABLE_WARNING_UNREACHABLE_CODE
DISABLE_WARNING_CONDEXPR_IS_CONSTANT

After the warning-triggering function, place this:

RESTORE_WARNINGS

Under the hood, the compiler-appropriate warning-disabling
mechanics involve the use of C99 _Pragma, which can be used
in macros.

For unrecognized or inappropriate compilers, or if
DISABLE_WARNING_PRAGMAS is defined, the macros expand
to nothing.
2021-02-01 12:54:19 -05:00

75 lines
2.5 KiB
C

/* NetHack 3.7 warnings.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */
/* Copyright (c) Michael Allison, 2021. */
#ifndef WARNINGS_H
#define WARNINGS_H
/*
* If ENABLE_WARNING_PRAGMAS is defined, the checks for various
* compilers is activated.
*
* If a suitable compiler is found, STDC_Pragma_AVAILABLE will be defined.
* When STDC_Pragma_AVAILABLE is not defined, these are defined as no-ops:
* DISABLE_WARNING_UNREACHABLE_CODE
* DISABLE_WARNING_CONDEXPR_IS_CONSTANT
* ...
* RESTORE_WARNINGS
*
*/
#if !defined(DISABLE_WARNING_PRAGMAS)
#if defined(__STDC_VERSION__)
#if __STDC_VERSION__ >= 199901L
#define ACTIVATE_WARNING_PRAGMAS
#endif /* __STDC_VERSION >= 199901L */
#endif /* __STDC_VERSION */
#if defined(_MSC_VER)
#ifndef ACTIVATE_WARNING_PRAGMAS
#define ACTIVATE_WARNING_PRAGMAS
#endif
#endif
#ifdef ACTIVATE_WARNING_PRAGMAS
#if defined(__clang__)
#define DISABLE_WARNING_UNREACHABLE_CODE \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wunreachable-code\"")
#define DISABLE_WARNING_CONDEXPR_IS_CONSTANT
#define RESTORE_WARNINGS _Pragma("clang diagnostic pop")
#define STDC_Pragma_AVAILABLE
#elif defined(__GNUC__)
/* unlike in clang, -Wunreachable-code does not function in later versions of gcc */
#define DISABLE_WARNING_UNREACHABLE_CODE \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wunreachable-code\"")
#define DISABLE_WARNING_CONDEXPR_IS_CONSTANT
#define RESTORE_WARNINGS _Pragma("GCC diagnostic pop")
#define STDC_Pragma_AVAILABLE
#elif defined(_MSC_VER)
#define DISABLE_WARNING_UNREACHABLE_CODE \
_Pragma("warning( push )") \
_Pragma("warning( disable : 4702 )")
#define DISABLE_WARNING_CONDEXPR_IS_CONSTANT \
_Pragma("warning( push )") \
_Pragma("warning( disable : 4127 )")
#define RESTORE_WARNINGS _Pragma("warning( pop )")
#define STDC_Pragma_AVAILABLE
#endif /* various compiler detections */
#endif /* ACTIVATE_WARNING_PRAGMAS */
#else /* DISABLE_WARNING_PRAGMAS */
#if defined(STDC_Pragma_AVAILABLE)
#undef STDC_Pragma_AVAILABLE
#endif
#endif /* DISABLE_WARNING_PRAGMAS */
#if !defined(STDC_Pragma_AVAILABLE)
#define DISABLE_WARNING_UNREACHABLE_CODE
#define DISABLE_WARNING_CONDEXPR_IS_CONSTANT
#deifne RESTORE_WARNINGS
#endif
#endif /* WARNINGS_H */