Files
nethack/sys/unix/hints/include/compiler.370
nhmall 0792e5fe9e 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.
2024-11-30 14:16:27 -05:00

226 lines
6.6 KiB
Plaintext
Executable File

#------------------------------------------------------------------------------
# NetHack 3.7 compiler.370 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $
# compiler flags: CCFLAGS is used to construct a value for CFLAGS with
# various -I, -D, and -W settings appended below;
# these are the settings of most interest for an end-user build
# (clang doesn't support '-Og', gcc needs 4.x or later)
CCFLAGS = -g
#CCFLAGS = -g -Og
#CCFLAGS = -O2
# Note: this is not the usual 'CFLAGS' which is used in default
# rules for compiling C code; specifying a value for that on the
# 'make' command line should be avoided.
#If you want to force use of one particular set of compilers, do it
#here, ahead of the detection, so that the detection will match your
#choice and set variables CCISCLANG, GCCGTEQ, CLANGPPGTEQ9 etc.
#accordingly.
#
#CC= gcc
#CXX= g++ -std-gnu++11
#
#CC= clang
#CXX=clang++ -std=gnu++11
#
# If these are set on entry, preparation for C++ compiles is affected.
# CPLUSPLUS_NEEDED = 1 C++ compile bits included
# CPLUSPLUS_NEED17 = 1 C++ -std=c++17 (at least)
# CPLUSPLUS_NEED_DEPSUPPRESS = 1 C++ -Wno-deprecated-copy,
# -Wno-deprecated-declarations
ifeq "$(WANT_ASAN)" "1"
USE_ASAN=1
endif
ifeq "$(WANT_UBSAN)" "1"
USE_UBSAN=1
endif
# If you want to override the compiler detection just carried out
# uncomment one of the following pairs. Note, however, that
# doing this after the detection above will likely result in
# mismatched variable values for CCISCLANG, GCCGTEQ, CLANGPPGTEQ9 etc.
#
#CC= gcc
#CXX= g++ -std-gnu++11
#
#CC= clang
#CXX=clang++ -std=gnu++11
CFLAGS=$(CCFLAGS) -I../include -DNOTPARMDECL
CFLAGS+=-Wall -Wextra \
-Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings
CFLAGS+=-pedantic
CFLAGS+=-Wmissing-declarations
#CFLAGS+=-Wformat=2
# these are left out of the C++ flags
CFLAGS+=-Wformat-nonliteral
CFLAGS+=-Wunreachable-code
#
# the following are not allowed in C++
CFLAGS+=-Wimplicit
CFLAGS+=-Wimplicit-function-declaration
CFLAGS+=-Wimplicit-int
CFLAGS+=-Wmissing-prototypes
CFLAGS+=-Wold-style-definition
CFLAGS+=-Wstrict-prototypes
CFLAGS+=-Wnonnull
#detection of clang vs gcc
CCISCLANG := $(shell echo `$(CC) --version` | grep clang)
ifeq "$(CCISCLANG)" ""
# gcc-specific follows
CXX=g++ -std=gnu++11
# get the version of gcc
GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9)
GCCGTEQ11 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 11)
GCCGTEQ12 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 12)
GCCGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14)
ifeq "$(GCCGTEQ9)" "1"
# flags present in gcc version greater than or equal to 9 can go here
CFLAGS+=-Wformat-overflow
CFLAGS+=-Wmissing-parameter-type
endif # GCC greater than or equal to 9
#ifeq "$(GCCGTEQ11)" "1"
CFLAGS+=-Wimplicit-fallthrough
#endif
#ifeq "$(GCCGTEQ12)" "1"
#endif
#ifeq "$(GCCGTEQ14)" "1"
CFLAGS+=-std=gnu23
#endif
# end of gcc-specific
else # gcc or clang?
CXX=clang++ -std=gnu++11
# clang-specific follows
CLANGGTEQ12 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 12)
CLANGGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14)
ifeq "$(CLANGGTEQ12)" "1"
CFLAGS+=-Wimplicit-fallthrough
endif
ifeq "$(CLANGGTEQ14)" "1"
ifneq "$(VIEWDEPRECATIONS)" "1"
CFLAGS+=-Wno-deprecated-declarations
endif # not VIEWDEPRECATIONS
else
# older versions complain about things newer ones don't without this
CFLAGS+=-Wno-missing-field-initializers
endif
# none
endif # clang-specific ends here
ifdef MAKEFILE_SRC
ifdef CPLUSPLUS_NEEDED
CCXXFLAGS = -g -I../include -DNOTPARMDECL
CCXXFLAGS+=-Wall -Wextra -Wno-missing-field-initializers \
-Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings
CCXXFLAGS+=-pedantic
CCXXFLAGS+=-Wmissing-declarations
#detection of clang++ vs g++
CXXISCLANG := $(shell echo `$(CXX) --version` | grep clang)
ifeq "$(CXXISCLANG)" ""
# g++-specific
CCXX=g++ -std=gnu++11
# get the version of g++
GPPGTEQ9 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 9)
GPPGTEQ11 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 11)
GPPGTEQ12 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 12)
GPPGTEQ14 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 14)
ifeq "$(GPPGTEQ9)" "1"
CCXXFLAGS+=-Wformat-overflow
ifdef CPLUSPLUS_NEED_DEPSUPPRESS
ifneq "$(VIEWDEPRECATIONS)" "1"
CCXXFLAGS+=-Wno-deprecated-copy
CCXXFLAGS+=-Wno-deprecated-declarations
endif # not VIEWDEPRECATIONS
endif # CPLUSPLUS_NEED_DEPSUPPRESS
endif # g++ version greater than or equal to 9
ifeq "$(GPPGTEQ11)" "1"
# the g++ linker will have trouble linking if the following isn't included
# when compiling the C files.
CFLAGS+=-fPIC
endif # g++ version greater than or equal to 11
ifdef CPLUSPLUS_NEED17
ifeq "$(GPPGTEQ12)" "1"
CCXX=g++ -std=c++17
else # g++ version greater than or equal to 12? (no follows)
CCXX=g++ -std=c++17
endif # g++ version greater than or equal to 12
endif # CPLUSPLUS_NEED17
else # g++ or clang++ ?
# clang++-specific
CCXX=clang++ -std=c++11
# get the version of clang++
CLANGPPGTEQ9 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 9)
CLANGPPGTEQ11 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 11)
CLANGPPGTEQ14 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 14)
CLANGPPGTEQ16 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 16)
CLANGPPGTEQ17 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 17)
ifeq "$(CLANGPPGTEQ9)" "1"
#CCXXFLAGS+=-Wformat-overflow
endif
ifeq "$(CLANGPPGTEQ14)" "1"
CPLUSPLUS_NEED_DEPSUPPRESS=1
endif
ifdef CPLUSPLUS_NEED_DEPSUPPRESS
ifneq "$(VIEWDEPRECATIONS)" "1"
CCXXFLAGS+=-Wno-deprecated
CCXXFLAGS+=-Wno-deprecated-declarations
endif # not VIEWDEPRECATIONS
endif # CPLUSPLUS_NEED_DEPSUPPRESS
# The clang++ linker seems to have trouble linking if the following isn't
# included when compiling the C files by clang..
CFLAGS+=-fPIC
ifdef CPLUSPLUS_NEED17
ifeq "$(CLANGPPGTEQ14)" "1"
CCXX=clang++ -std=c++17
endif # clang++ greater than or equal to 14
ifeq "$(CLANGPPGTEQ17)" "1"
CCXX=clang++ -std=c++17
endif # clang++ greater than or equal to 17
endif # CPLUSPLUS_NEED17
endif # end of clang++-specific section
CXX=$(CCXX)
endif # CPLUSPLUS_NEEDED
endif # MAKEFILE_SRC
ifeq "$(c89)" "1"
HAVECSTD=c89
endif
ifeq "$(C89)" "1"
HAVECSTD=c89
endif
ifeq "$(c99)" "1"
HAVECSTD=c99
endif
ifeq "$(C99)" "1"
HAVECSTD=c99
endif
ifeq "$(c11)" "1"
HAVECSTD=c11
endif
ifeq "$(C11)" "1"
HAVECSTD=c11
endif
ifeq "$(c23)" "1"
HAVECSTD=c2x
endif
ifeq "$(C23)" "1"
HAVECSTD=c2x
endif
ifneq "$(HAVECSTD)" ""
CSTD = -std=$(HAVECSTD)
endif
#end of compiler.370
#------------------------------------------------------------------------------