mirror of
https://github.com/Z3Prover/z3
synced 2026-08-02 12:13:25 +00:00
This is another PR towards the goal of getting Z3 to compile cleanly
when included via FetchContents into clang-tidy, which uses a pretty
strict set of warnings. (1 more flag after this!)
This one adds the flag -Wgnu-anonymous-struct. Z3 uses this anonymous
struct idiom, usually when using a struct as one of the members of a
union, as in:
```
union {
justification * m_js;
unsigned m_lidx;
struct {
enode * m_lhs;
enode * m_rhs;
};
};
```
This is not, strictly speaking, legal C++ (at least according to
Google's AI summary -- and the existence of this flag in Clang implies
that it is a GNU extension). You need to give the struct a member name
in the outer union to prevent the warning.
I'm of two minds on this. On the one hand it's not hurting anything, and
all the major compilers seem to support the idiom. On the other hand,
well, why do we have standards if we're going to ignore them in favor of
de-facto standards?
I submit this PR to show the size of the changes necessary to eliminate
the use of the extension. Personally, I'd do it, but I would gladly
withdraw the PR in favor of one that just silences the warning, if that
was the reviewer's preference.
186 lines
6.9 KiB
CMake
186 lines
6.9 KiB
CMake
################################################################################
|
|
# Compiler warning flags
|
|
################################################################################
|
|
# These are passed to relevant compiler provided they are supported
|
|
set(GCC_AND_CLANG_WARNINGS
|
|
"-Wall"
|
|
)
|
|
set(GCC_ONLY_WARNINGS "")
|
|
# Disable C++98 compatibility warnings to prevent excessive warning output
|
|
# when building with clang-cl or when -Weverything is enabled.
|
|
# These warnings are not useful for Z3 since it requires C++20.
|
|
#
|
|
# The "-Wno-zero-length-array" is for cases where Z3 is fetched by a CMake build
|
|
# to serve as a component in another system. Z3 has many classes whose last member
|
|
# is a zero-length array of some type T, indicating a variable-length array of T.
|
|
# If the including system compiles with "-Wzero-length-array", there will be
|
|
# many warnings. Overriding this prevents such warnings in the Z3 portion of the
|
|
# build of the including system.
|
|
set(CLANG_ONLY_WARNINGS
|
|
"-Wno-c++98-compat"
|
|
"-Wno-c++98-compat-pedantic"
|
|
"-Wno-zero-length-array"
|
|
"-Wc99-extensions"
|
|
"-Wsuggest-override"
|
|
"-Winconsistent-missing-override"
|
|
"-Wno-missing-field-initializers"
|
|
"-Wcast-qual"
|
|
"-Wimplicit-fallthrough"
|
|
"-Wextra-semi"
|
|
"-Wignored-qualifiers"
|
|
"-Wnoctad-maybe-unsupported"
|
|
"-Wdeprecated-copy-with-user-provided-copy"
|
|
"-Wgnu-anonymous-struct"
|
|
)
|
|
|
|
set(MSVC_WARNINGS "/W3")
|
|
|
|
################################################################################
|
|
# Serious warnings
|
|
################################################################################
|
|
# This declares the flags that are passed to the compiler when
|
|
# `WARNINGS_AS_ERRORS` is set to `SERIOUS_ONLY`. Only flags that are supported
|
|
# by the compiler are used.
|
|
#
|
|
# In effect this a "whitelist" approach where we explicitly tell the compiler
|
|
# which warnings we want to be treated as errors. The alternative would be a
|
|
# "blacklist" approach where we ask the compiler to treat all warnings are
|
|
# treated as errors but then we explicitly list which warnings which should be
|
|
# allowed.
|
|
#
|
|
# The "whitelist" approach seems simpiler because we can incrementally add
|
|
# warnings we "think are serious".
|
|
|
|
# TODO: Add more warnings that are considered serious enough that we should
|
|
# treat them as errors.
|
|
set(GCC_AND_CLANG_WARNINGS_AS_ERRORS
|
|
# https://clang.llvm.org/docs/DiagnosticsReference.html#wodr
|
|
"-Werror=odr"
|
|
# https://clang.llvm.org/docs/DiagnosticsReference.html#wreturn-type
|
|
"-Werror=return-type"
|
|
)
|
|
set(GCC_WARNINGS_AS_ERRORS
|
|
""
|
|
)
|
|
set(CLANG_WARNINGS_AS_ERRORS
|
|
# https://clang.llvm.org/docs/DiagnosticsReference.html#wdelete-non-virtual-dtor
|
|
"-Werror=delete-non-virtual-dtor"
|
|
# https://clang.llvm.org/docs/DiagnosticsReference.html#woverloaded-virtual
|
|
"-Werror=overloaded-virtual"
|
|
# warn the user if a class with virtual functions has a
|
|
# non-virtual destructor. This helps catch hard to
|
|
# track down memory errors
|
|
"-Werror=non-virtual-dtor"
|
|
# warn if a null dereference is detected
|
|
"-Werror=null-dereference"
|
|
# warn for potential performance problem casts
|
|
# "-Werror=cast-align"
|
|
# warn if float is implicit promoted to double
|
|
# "-Werror=double-promotion"
|
|
"-Werror=no-unreachable-code-return"
|
|
# warn the user if a variable declaration shadows one from a parent context
|
|
# "-Werror=shadow"
|
|
# warn for c-style casts
|
|
# "-Werror=old-style-cast"
|
|
# warn on sign conversions
|
|
# "-Werror=sign-conversion"
|
|
# warn on type conversions that may lose data
|
|
# "-Werror=conversion"
|
|
# warn on anything being unused
|
|
# "-Werror=unused"
|
|
)
|
|
|
|
################################################################################
|
|
# Test warning/error flags
|
|
################################################################################
|
|
set(WARNING_FLAGS_TO_CHECK "")
|
|
set(WARNING_AS_ERROR_FLAGS_TO_CHECK "")
|
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
|
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
|
|
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_ONLY_WARNINGS})
|
|
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS_AS_ERRORS})
|
|
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_WARNINGS_AS_ERRORS})
|
|
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
|
|
list(APPEND WARNING_FLAGS_TO_CHECK ${CLANG_ONLY_WARNINGS})
|
|
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS_AS_ERRORS})
|
|
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${CLANG_WARNINGS_AS_ERRORS})
|
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|
list(APPEND WARNING_FLAGS_TO_CHECK ${MSVC_WARNINGS})
|
|
|
|
# CMake's default flags include /W3 already so remove them if
|
|
# they already exist.
|
|
if (CMAKE_CXX_FLAGS MATCHES "/W3")
|
|
string(REPLACE "/W3" "" _cmake_cxx_flags_remove_w3 "${CMAKE_CXX_FLAGS}")
|
|
set(CMAKE_CXX_FLAGS "${_cmake_cxx_flags_remove_w3}" CACHE STRING "" FORCE)
|
|
endif()
|
|
else()
|
|
message(AUTHOR_WARNING "Unknown compiler")
|
|
endif()
|
|
|
|
# Loop through flags and use the ones which the compiler supports
|
|
foreach (flag ${WARNING_FLAGS_TO_CHECK})
|
|
z3_add_cxx_flag("${flag}")
|
|
endforeach()
|
|
|
|
# TODO: Remove this eventually.
|
|
# Detect legacy `WARNINGS_AS_ERRORS` boolean option and covert to new
|
|
# to new option type.
|
|
get_property(
|
|
WARNINGS_AS_ERRORS_CACHE_VAR_TYPE
|
|
CACHE
|
|
WARNINGS_AS_ERRORS
|
|
PROPERTY
|
|
TYPE
|
|
)
|
|
if (WARNINGS_AS_ERRORS_CACHE_VAR_TYPE STREQUAL "BOOL")
|
|
message(WARNING "Detected legacy WARNINGS_AS_ERRORS option. Upgrading")
|
|
set(WARNINGS_AS_ERRORS_DEFAULT "${WARNINGS_AS_ERRORS}")
|
|
# Delete old entry
|
|
unset(WARNINGS_AS_ERRORS CACHE)
|
|
else()
|
|
set(WARNINGS_AS_ERRORS_DEFAULT "SERIOUS_ONLY")
|
|
endif()
|
|
|
|
set(WARNINGS_AS_ERRORS
|
|
${WARNINGS_AS_ERRORS_DEFAULT}
|
|
CACHE STRING
|
|
"Treat warnings as errors. ON, OFF, or SERIOUS_ONLY"
|
|
)
|
|
# Set GUI options
|
|
set_property(
|
|
CACHE
|
|
WARNINGS_AS_ERRORS
|
|
PROPERTY STRINGS
|
|
"ON;OFF;SERIOUS_ONLY"
|
|
)
|
|
|
|
if (WARNINGS_AS_ERRORS STREQUAL "ON")
|
|
message(STATUS "Treating compiler warnings as errors")
|
|
if ((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR (CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
|
|
list(APPEND Z3_COMPONENT_CXX_FLAGS "-Werror")
|
|
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX")
|
|
else()
|
|
message(AUTHOR_WARNING "Unknown compiler")
|
|
endif()
|
|
elseif (WARNINGS_AS_ERRORS STREQUAL "SERIOUS_ONLY")
|
|
message(STATUS "Treating only serious compiler warnings as errors")
|
|
# Loop through the flags
|
|
foreach (flag ${WARNING_AS_ERROR_FLAGS_TO_CHECK})
|
|
# Add globally because some flags need to be passed at link time.
|
|
z3_add_cxx_flag("${flag}" GLOBAL)
|
|
endforeach()
|
|
elseif (WARNINGS_AS_ERRORS STREQUAL "OFF")
|
|
message(STATUS "Not treating compiler warnings as errors")
|
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|
# Warnings as errors is off by default for MSVC so setting this
|
|
# is not necessary but this duplicates the behaviour of the old
|
|
# build system.
|
|
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX-")
|
|
endif()
|
|
else()
|
|
message(FATAL_ERROR
|
|
"WARNINGS_AS_ERRORS set to unsupported value \"${WARNINGS_AS_ERRORS}\""
|
|
)
|
|
endif()
|