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.
226 lines
6.6 KiB
Plaintext
Executable File
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
|
|
#------------------------------------------------------------------------------
|