commit dcdc6b0900b0f6865eec98ac966d77faa783ee8e
parent a6d7a686b8137be144a22c205045fbb945e876d4
Author: serge-sans-paille <sguelton@mozilla.com>
Date: Tue, 28 Oct 2025 21:09:31 +0000
Bug 1985940 - Bind clang warnings support to a given version r=firefox-build-system-reviewers,glandium
Instead of checking which warnings are supported by clang, we can bind
that piece of information to a given version range, while not changing
the check for other compilers.
This provides faster configuration, which is especially valuable on
treeherder, where it saves 8s of configuration time \o/
Differential Revision: https://phabricator.services.mozilla.com/D263076
Diffstat:
3 files changed, 128 insertions(+), 48 deletions(-)
diff --git a/build/moz.configure/compile-checks.configure b/build/moz.configure/compile-checks.configure
@@ -377,7 +377,7 @@ def warnings_flags():
# adds it to the list of warning flags unconditionally. This is only meant
# for add_warning().
@template
-def check_and_add_warning(warning, compiler=None, when=None, check=True):
+def check_and_add_warning_impl(warning, compiler=None, when=None, check=True):
# GCC and clang will fail if given an unknown warning option like
# -Wfoobar. But later versions won't fail if given an unknown negated
# warning option like -Wno-foobar. So when we are checking for support
@@ -395,6 +395,20 @@ def check_and_add_warning(warning, compiler=None, when=None, check=True):
)
+# When changing this version, please check that no warning support have been
+# removed.
+clang_latest_release = dependable("21.1.0")
+
+
+@depends(c_compiler, clang_latest_release, when=moz_automation)
+def check_latest_release_version(compiler, clang_latest_release):
+ if (
+ compiler.type in ("clang", "clang-cl")
+ and compiler.version > clang_latest_release
+ ):
+ configure_error("latest clang release version must be updated")
+
+
# Add the given warning to the list of warning flags for the build.
# - `warning` is the warning flag (e.g. -Wfoo)
# - `compiler` (optional) is the compiler to add the flag for (c_compiler or
@@ -402,11 +416,46 @@ def check_and_add_warning(warning, compiler=None, when=None, check=True):
# is added for both compilers.
# - `when` (optional) is a @depends function or option name conditioning
# when the warning flag is wanted.
+@template
+def add_warning(warning, compiler=None, when=None):
+ check_and_add_warning_impl(warning, compiler, when, check=False)
+# Add the given warning to the list of warning flags for the build.
+# - `warning` is the warning flag (e.g. -Wfoo)
+# - `compiler` (optional) is the compiler to add the flag for (c_compiler or
+# cxx_compiler, from toolchain.configure). When omitted, the warning flag
+# is added for both compilers.
+# - `when` (optional) is a @depends function or option name conditioning
+# when the warning flag is wanted.
+# - if min_clang_version is set, do not run the check for clang compiler, use
+# know result instead. Possibly rely on max_clang_version in that case to
+# bound the version check.
@template
-def add_warning(warning, compiler=None, when=None):
- check_and_add_warning(warning, compiler, when, check=False)
+def check_and_add_warning(
+ warning, compiler=None, when=None, max_clang_version=None, min_clang_version=None
+):
+ if when is None:
+ when = always
+ if min_clang_version is None and max_clang_version is None:
+ return check_and_add_warning_impl(warning, compiler, when, check=True)
+
+ min_clang_version = min_clang_version or "0.0.0"
+ max_clang_version = (
+ dependable(max_clang_version) if max_clang_version else clang_latest_release
+ )
+ is_compatible_clang = depends(c_compiler, max_clang_version)(
+ lambda c, max_clang_version: c.type in ("clang", "clang-cl")
+ and min_clang_version <= c.version <= max_clang_version
+ )
+ is_clang = depends(c_compiler.type)(lambda t: t in ("clang", "clang-cl"))
+ res_clang = check_and_add_warning_impl(
+ warning, compiler, when & is_compatible_clang, check=False
+ )
+ res_other = check_and_add_warning_impl(
+ warning, compiler, when & (building_with_gcc | ~is_compatible_clang), check=True
+ )
+ return res_clang + res_other
# Like the warning checks above, but for general compilation flags.
diff --git a/build/moz.configure/warnings.configure b/build/moz.configure/warnings.configure
@@ -23,6 +23,8 @@ def warnings_as_errors(warnings_as_errors):
set_config("WARNINGS_AS_ERRORS", warnings_as_errors)
not_clang_cl = depends(c_compiler)(lambda c: c.type != "clang-cl")
+not_clang = depends(c_compiler)(lambda c: c.type != "clang")
+not_clang_based = depends(c_compiler)(lambda c: c.type not in ("clang", "clang-cl"))
# GCC/Clang warnings:
# https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
@@ -34,13 +36,13 @@ add_warning("-Wall", when=not_clang_cl)
add_warning("-W3", when=depends(c_compiler)(lambda c: c.type == "clang-cl"))
# catch implicit truncation of enum values assigned to smaller bit fields
-check_and_add_warning("-Wbitfield-enum-conversion")
+check_and_add_warning("-Wbitfield-enum-conversion", min_clang_version="5.0.0")
# catches bugs, e.g. "if (c); foo();", few false positives
add_warning("-Wempty-body")
# catches mismatched printf integer sizes.
-check_and_add_warning("-Wformat-type-confusion")
+check_and_add_warning("-Wformat-type-confusion", min_clang_version="10.0.0")
# catches return types with qualifiers like const
add_warning("-Wignored-qualifiers")
@@ -49,28 +51,35 @@ add_warning("-Wignored-qualifiers")
add_warning("-Wpointer-arith")
# catch modifying constructor parameter that shadows member variable
-check_and_add_warning("-Wshadow-field-in-constructor-modified")
+check_and_add_warning(
+ "-Wshadow-field-in-constructor-modified", min_clang_version="4.0.0"
+)
# catches comparing signed/unsigned ints
add_warning("-Wsign-compare")
# catches comparisons of values and sized types are always true or false
-check_and_add_warning("-Wtautological-constant-in-range-compare")
+check_and_add_warning(
+ "-Wtautological-constant-in-range-compare", min_clang_version="6.0.0"
+)
# catches overflow bugs, few false positives
add_warning("-Wtype-limits")
# This can be triggered by certain patterns used deliberately in portable code
-check_and_add_warning("-Wno-error=tautological-type-limit-compare")
+check_and_add_warning(
+ "-Wno-error=tautological-type-limit-compare", min_clang_version="6.0.0"
+)
# catches some dead code
add_warning("-Wunreachable-code")
-check_and_add_warning("-Wunreachable-code-return")
+check_and_add_warning("-Wunreachable-code-return", min_clang_version="4.0.0")
# catches parameters that are set but not read
# Only enable on clang because gcc reports false positives.
check_and_add_warning(
"-Wunused-but-set-parameter",
+ min_clang_version="13.0.0",
when=depends(c_compiler)(lambda c: c.type in ("clang", "clang-cl")),
)
@@ -78,36 +87,43 @@ check_and_add_warning(
add_warning("-Wno-invalid-offsetof", cxx_compiler)
# catches objects passed by value to variadic functions.
-check_and_add_warning("-Wclass-varargs")
+check_and_add_warning("-Wclass-varargs", min_clang_version="4.0.0")
# catches empty if/switch/for initialization statements that have no effect
-check_and_add_warning("-Wempty-init-stmt", cxx_compiler)
+check_and_add_warning("-Wempty-init-stmt", cxx_compiler, min_clang_version="8.0.0")
# catches some implicit conversion of floats to ints
-check_and_add_warning("-Wfloat-overflow-conversion")
-check_and_add_warning("-Wfloat-zero-conversion")
+check_and_add_warning("-Wfloat-overflow-conversion", min_clang_version="4.0.0")
+check_and_add_warning("-Wfloat-zero-conversion", min_clang_version="4.0.0")
# catches issues around loops
-check_and_add_warning("-Wloop-analysis")
+check_and_add_warning("-Wloop-analysis", min_clang_version="4.0.0")
# But, disable range-loop-analysis because it can raise unhelpful false
# positives.
-check_and_add_warning("-Wno-range-loop-analysis")
+check_and_add_warning("-Wno-range-loop-analysis", min_clang_version="4.0.0")
# Enable some C++20 compat warnings. We can remove these flags after we compile
# as C++20 (bug 1768116), because they will be enabled by default:
-check_and_add_warning("-Wcomma-subscript", cxx_compiler)
-check_and_add_warning("-Wenum-compare-conditional")
-check_and_add_warning("-Wenum-float-conversion")
-check_and_add_warning("-Wvolatile", cxx_compiler)
+check_and_add_warning("-Wcomma-subscript", cxx_compiler, when=not_clang_based)
+check_and_add_warning("-Wenum-compare-conditional", min_clang_version="10.0.0")
+check_and_add_warning("-Wenum-float-conversion", min_clang_version="10.0.0")
+check_and_add_warning("-Wvolatile", cxx_compiler, when=not_clang)
# Disable some C++20 errors to be fixed in bugs 1791958, 1791955, and 1775161.
-check_and_add_warning("-Wno-deprecated-anon-enum-enum-conversion", cxx_compiler)
-check_and_add_warning("-Wno-deprecated-enum-enum-conversion", cxx_compiler)
-
+check_and_add_warning(
+ "-Wno-deprecated-anon-enum-enum-conversion",
+ cxx_compiler,
+ min_clang_version="10.0.0",
+)
+check_and_add_warning(
+ "-Wno-deprecated-enum-enum-conversion", cxx_compiler, min_clang_version="10.0.0"
+)
# Suppress C++20 warnings about implicit capture of `this` until they are fixed
# in bug 1775161. gcc doesn't have a -Wdeprecated-this-capture flag like clang,
# so temporarily downgrade all gcc -Wdeprecated errors to warnings.
-check_and_add_warning("-Wno-deprecated-this-capture", cxx_compiler)
+check_and_add_warning(
+ "-Wno-deprecated-this-capture", cxx_compiler, min_clang_version="6.0.0"
+)
check_and_add_warning("-Wno-error=deprecated", when=building_with_gcc)
# Enable some C++23 compat warnings. We can remove these flags after we compile
@@ -116,16 +132,16 @@ check_and_add_warning("-Wdeprecated-literal-operator", cxx_compiler)
check_and_add_warning("-Winvalid-utf8")
# catches possible misuse of the comma operator
-check_and_add_warning("-Wcomma", cxx_compiler)
+check_and_add_warning("-Wcomma", cxx_compiler, min_clang_version="4.0.0")
# catches duplicated conditions in if-else-if chains
-check_and_add_warning("-Wduplicated-cond")
+check_and_add_warning("-Wduplicated-cond", when=not_clang_based)
# catches unintentional switch case fallthroughs
-check_and_add_warning("-Wimplicit-fallthrough", cxx_compiler)
+check_and_add_warning("-Wimplicit-fallthrough", cxx_compiler, min_clang_version="4.0.0")
# Warn about suspicious uses of logical operators in expressions.
-check_and_add_warning("-Wlogical-op")
+check_and_add_warning("-Wlogical-op", when=not_clang_based)
# Enable some ObjC diagnostics that are only relevant when targeting macOS:
with only_when(depends(target)(lambda t: t.kernel == "Darwin")):
@@ -148,39 +164,39 @@ with only_when(depends(target)(lambda t: t.kernel == "Darwin")):
check_and_add_warning("-Wsuper-class-method-mismatch")
# catches string literals used in boolean expressions
-check_and_add_warning("-Wstring-conversion")
+check_and_add_warning("-Wstring-conversion", min_clang_version="4.0.0")
# we inline 'new' and 'delete' in mozalloc
-check_and_add_warning("-Wno-inline-new-delete", cxx_compiler)
+check_and_add_warning("-Wno-inline-new-delete", cxx_compiler, min_clang_version="4.0.0")
# Prevent the following GCC warnings from being treated as errors:
# too many false positives
-check_and_add_warning("-Wno-error=maybe-uninitialized")
+check_and_add_warning("-Wno-error=maybe-uninitialized", when=not_clang_based)
# we don't want our builds held hostage when a platform-specific API
# becomes deprecated.
-check_and_add_warning("-Wno-error=deprecated-declarations")
+check_and_add_warning("-Wno-error=deprecated-declarations", min_clang_version="4.0.0")
# false positives depending on optimization
-check_and_add_warning("-Wno-error=array-bounds")
+check_and_add_warning("-Wno-error=array-bounds", min_clang_version="4.0.0")
# false positives depending on optimizations
-check_and_add_warning("-Wno-error=free-nonheap-object")
+check_and_add_warning("-Wno-error=free-nonheap-object", min_clang_version="12.0.0")
# Would be a pain to fix all occurrences, for very little gain
-check_and_add_warning("-Wno-multistatement-macros")
+check_and_add_warning("-Wno-multistatement-macros", when=not_clang_based)
# Disable the -Werror for -Wclass-memaccess as we have a long
# tail of issues to fix
-check_and_add_warning("-Wno-error=class-memaccess")
+check_and_add_warning("-Wno-error=class-memaccess", when=not_clang_based)
# -Watomic-alignment is a new warning in clang 7 that seems way too broad.
# https://bugs.llvm.org/show_bug.cgi?id=38593
-check_and_add_warning("-Wno-error=atomic-alignment")
+check_and_add_warning("-Wno-error=atomic-alignment", min_clang_version="7.0.0")
# New warning with clang 15. Catches uses of deprecated builtins in abseil-cpp.
# https://bugzilla.mozilla.org/show_bug.cgi?id=1779528
-check_and_add_warning("-Wno-error=deprecated-builtins")
+check_and_add_warning("-Wno-error=deprecated-builtins", min_clang_version="15.0.0")
# catches format/argument mismatches with printf
c_format_warning, cxx_format_warning = check_and_add_warning(
@@ -190,8 +206,14 @@ c_format_warning, cxx_format_warning = check_and_add_warning(
# Add compile-time warnings for unprotected functions and format functions
# that represent possible security problems. Enable this only when -Wformat
# is enabled, otherwise it is an error
-check_and_add_warning("-Wformat-security", when=c_format_warning & cxx_format_warning)
-check_and_add_warning("-Wformat-overflow=2", when=c_format_warning & cxx_format_warning)
+check_and_add_warning(
+ "-Wformat-security",
+ when=c_format_warning & cxx_format_warning,
+ min_clang_version="4.0.0",
+)
+check_and_add_warning(
+ "-Wformat-overflow=2", when=c_format_warning & cxx_format_warning & not_clang_based
+)
# Other Windows specific things
with only_when(target_is_windows):
@@ -284,15 +306,18 @@ with only_when(target_is_windows):
check_and_add_warning("-Wno-enum-compare")
# Make it an error to be missing function declarations for C code.
-check_and_add_warning("-Werror=implicit-function-declaration", c_compiler)
+check_and_add_warning(
+ "-Werror=implicit-function-declaration", c_compiler, min_clang_version="4.0.0"
+)
# New in clang 11. We can't really do anything about this warning.
-check_and_add_warning("-Wno-psabi")
+check_and_add_warning("-Wno-psabi", min_clang_version="11.0.0")
# Disable broken missing-braces warning on old clang versions
check_and_add_warning(
"-Wno-missing-braces",
when=depends(c_compiler)(lambda c: c.type == "clang" and c.version < "6.0"),
+ min_clang_version="4.0.0",
)
# Turn on clang thread-safety analysis
@@ -302,28 +327,33 @@ check_and_add_warning(
when=depends(c_compiler)(
lambda c: c.type in ("clang", "clang-cl") and c.version >= "8.0"
),
+ min_clang_version="4.0.0",
)
# Warn if APIs are used without available() checks on macOS.
-check_and_add_warning("-Werror=unguarded-availability-new", when=target_is_osx)
+check_and_add_warning(
+ "-Werror=unguarded-availability-new", when=target_is_osx, min_clang_version="5.0.0"
+)
# clang 17 warns about builtins being redefined and... well, we do that in
# multiple places, some of which are third-party. Until the situation is
# fixed, disable the new warning.
-check_and_add_warning("-Wno-error=builtin-macro-redefined")
+check_and_add_warning("-Wno-error=builtin-macro-redefined", min_clang_version="4.0.0")
# clang 18 has a new warning about VLAs being an extension in C++, but we
# have a number of them.
-check_and_add_warning("-Wno-vla-cxx-extension", cxx_compiler)
-
-# Please keep the following last in this file
+check_and_add_warning(
+ "-Wno-vla-cxx-extension", cxx_compiler, min_clang_version="18.0.0"
+)
# Avoid requiring complicated logic for extra warning flags in moz.build files.
-check_and_add_warning("-Wno-unknown-warning-option")
+check_and_add_warning("-Wno-unknown-warning-option", min_clang_version="4.0.0")
# clang 21 warns about charN_t conversions, and we have a lot that need a careful
# audit rather than plainly adding static_casts.
-check_and_add_warning("-Wno-character-conversion")
+check_and_add_warning("-Wno-character-conversion", min_clang_version="21.0.0")
+
+# Please keep the following last in this file
set_config("WARNINGS_CFLAGS", warnings_flags.cflags)
set_config("WARNINGS_CXXFLAGS", warnings_flags.cxxflags)
diff --git a/python/mozbuild/mozbuild/test/configure/test_compile_checks.py b/python/mozbuild/mozbuild/test/configure/test_compile_checks.py
@@ -50,6 +50,7 @@ class BaseCompileChecks(unittest.TestCase):
mock_compiler_defs = textwrap.dedent(
"""\
+ moz_automation = dependable(False)
@depends(when=True)
def extra_toolchain_flags():
return []