-
Notifications
You must be signed in to change notification settings - Fork 548
CXX-2139 update clang-tidy configuration with WarningsAsErrors #1496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
kevinAlbs
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opinion: enable WarningsAsErrors for default checks that do not already warn. Enable checks straightforward to address. Defer others to future work:
Some default checks appear to be aliases:
cert-con54-cppOmit? Alias ofcert-con36-ccert-dcl51-cppOmit? Alias ofcert-dcl37-ccert-err61-cppOmit? Alias ofcert-err09-cppcert-msc50-cppOmit? Alias ofcert-msc30-ccert-msc51-cppOmit? Alias ofcert-msc32-c
Some appear straightforward to address:
cert-oop54-cppEnable? 11 warnings. On brief look, self-assignments appear to be correct but doing a needless copy. I expect these can be fixed with an added self-check, from:to:read_concern& read_concern::operator=(read_concern const& other) { _impl = bsoncxx::make_unique<impl>(libmongoc::read_concern_copy(other._impl->read_concern_t)); return *this; }
read_concern& read_concern::operator=(read_concern const& other) { if (this == &other) { return *this; } _impl = bsoncxx::make_unique<impl>(libmongoc::read_concern_copy(other._impl->read_concern_t)); return *this; }
cppcoreguidelines-init-variables(Enable? 20 warnings. Appears easy to address).cppcoreguidelines-prefer-member-initializer(Enable? 3 warnings. Appears easy to address.)cppcoreguidelines-pro-type-static-cast-downcast(Enable? 1 warning. May be a legitimate bug?)cppcoreguidelines-use-default-member-init(Enable? 4 warnings. Appears easy to fix)
|
Important The
Duplicate checks (e.g.
Done: The warnings suggested to be enabled are fixed (as described below) and removed from the list of exclusions.
Fixed. Deliberately ignored existing inconsistencies between the exception strategy for v_noabi assignment operators given an "invalid" assign-or-destroy-only argument.
Fixed. Used
Fixed.
This is not a bug due to the cast being guarded by
Fixed. Used the same
This is a new clang-tidy warning (already enabled by the This diagnostic seems to warn only when there are both public and private data members in the same class. Because this
This is a new clang-tidy warning (already enabled by the If we want to restrict this warning to identifying non-reference catch statements (which may slice the exception object; this seems to be the main purpose of this diagnostic), we could disable the "throw anonymous temporaries" aspect of this diagnostic by setting the
Following these changes, the warnings which are currently enabled (by default) but not treated as errors (excluded) are:
All other currently-enabled warnings are now treated as errors. Note that with the current arrangement, any new warnings added to the list of diagnostics supported by |
|
In my previous role, I took on a similar initiative to gradually introduce more strict clang-tidy checks. From memory, I believed we enforced the majority of the checks from the following groups:
I chose most of these groups as they seemed appropriate for general application rather than being tied to a specific set of company conventions, project conventions, or coding standards. There were two exceptions however:
While all these groups were enforced, some checks were selectively disabled from each group due to their enforcement being impractical, overly opinionated, or unreliable (too many false positives). That said, I made a point to document each disabled check to discourage others from disabling checks out of convenience or expediency, e.g.: Checks:
- bugprone-*
- -bugprone-exception-escape # Difficult to enforce since many STL functions lack proper conditional noexcept.
- readability-*
- -readability-identifier-length # Too opinionated.Some of the enforced checks still needed to be suppressed. I similarly tried to encourage devs to document suppressions with some sort of justification, e.g.: // ABI backward compatibility. Const is restored in `view::_init`.
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
_init(const_cast<void*>(static_cast<void const*>(value)));While I think this was largely a sound approach, it was also curated for that specific project and domain. Some of these goals may not be as applicable to our use case:
Overall, I am still partial to a somewhat aggressive use of clang-tidy, but I recognize that I am new to this project and have a background in a different domain. With the amount of checks there are, I cannot practically give my opinion on each one. For now, I will just give my thoughts on some of the warnings with a high occurrence:
For the rest, there are so few warnings that it seems practical to enforce then suppress as needed. I mentioned some other groups of checks that I would support enabling (see the beginning of this comment). To be clear, I think it makes sense to stick with |
|
Important The following checks have been disabled:
See below for rationale.
Agreed. The focus of this PR is specifically to determine the checks which will trigger EVG
These warnings are emitted by both C and C++ Driver code:
In my opinion, and as you've stated, it is not feasible to address these warnings without raising our minimum C++ standard to C++17 or newer to obtain access to
I agree we do not want to depend on GSL. The C API is not actually such a concern (since deallocation is managed by
I think this diagnostic is useful to keep enabled as a helpful reminder to use smart pointers when able. Therefore, opted to suppress all current instances of this warning with either "custom deleter" or "owning
I find the value of this diagnostic dubious. Even if we go out of our way to explicitly cast C arrays into pointers via static casts... for what benefit? Even if we convert these instances into Therefore, opted to disable this check together with related checks
I agree that this warning "can be annoying in tests", but for the moment, these clang-tidy diagnostics only apply to library code. It does not apply to tests, examples, and etc. Therefore, I think this is a useful diagnostic to keep enabled, if only to encourage descriptive names (fix) or documentation (suppression). Therefore, opted to suppress this diagnostic on a case-by-case basis. I think the corresponding changes are indeed a readability improvement. However, I'm not sure if we want to promote this into an error yet, so left it as a warning-only for now.
I agree we should enforce this diagnostic. Fixed and suppressed accordingly.
I agree we should enforce this diagnostic. Fix and suppressed accordingly. The use of Scott Meyers' DRY getters pattern is used by several Fixing these warnings also highlights an inconsistency in the
I agree we should enforce this diagnostic. Fixed and suppressed accordingly. We could consider setting
I personally think this diagnostic somewhat dubious in value, despite my remarks above concerning
I agree we should enforce this diagnostic, although I really wish we could use C++20's Also opted to set
I believe this is worth enforcing, so drive-by fixed these warnings as well. Following these changes, the warnings which are currently emitted but not treated as errors are only six in total: I am in favor of enforcing |
Resolves CXX-2139. Followup to #1495 upon realising the clang-tidy EVG task has been providing minimal value due to the absence of
WarningsAsErrorschecks (most/all diagnostics except for hard compilation errors are emitted but otherwise ignored). #1049 implemented a "temporary" workaround clang-tidy configuration options document this absence of static analysis errors. This PR proposes taking this opportunity to codify the clang-tidy configuration options for Clang 21.1.1 (onrhel9-latest) and the initial set ofWarningsAsErrorschecks to be enabled going forward.The set of clang-tidy warnings emitted by the
clang-tidytask with currently proposed changes are visible in this patch build.The
.clang-tidyconfiguration file has been updated with the dump of the default configuration for clang-tidy 21.1.1 (the version onrhel9-latestwhere this task will now be executed). The default list of checks is preserved for now, including the disabling of all default checks with-*(with redundancy removed). The initial changes in this PR leave the set ofWarningsAsErrorsdiagnostics (which unfortunately does not seem to support list syntax) empty: this PR is an opportunity to decide on an initially minimal-and-constrainted set of checks which will fail theclang-tidytask on error.Important
Adding checks to
WarningsAsErrorsis necessary to determine when theclang-tidyEVG task fails due to static analysis diagnostics.The initial set of files to be analyzed are library components only. Notably, the
benchmark(requires C++17),config,_deps,docs,enums,test, directories and macro guard headers are excluded from analysis. We can consider extending analysis to one or more of these extra directories once we have decided the set ofWarningsAsErrorsdiagnostics to enable. The current filter list includes 219 source files:The
--header-filterflag further limits analysis to library headers only so that diagnostics are not emitted for external headers.Note
These filters and exclusions are deliberately not specified via
.clang-tidyconfiguration options to avoid pessimizing the local development experience. The.clang-tidyconfiguration only excludesconfig,_depsandenumsheaders.According to llvm/llvm-project#47042 (which is finally resolved by llvm/llvm-project#154012), the "N warnings generated" spam (which is what motivated the
2>/dev/nullthat masked the "command not found" error) should hopefully be in the next clang-tidy release. 👏 Until then, we'll need to continue using this workaround.Given this configuration and filters, the current state of clang-tidy warnings is as follows:
cppcoreguidelines-pro-type-union-access: 87 warningscppcoreguidelines-pro-bounds-array-to-pointer-decay: 34 warningscppcoreguidelines-init-variables: 20 warningscppcoreguidelines-pro-type-reinterpret-cast: 19 warningscppcoreguidelines-avoid-magic-numbers: 17 warningscppcoreguidelines-pro-bounds-pointer-arithmetic: 17 warningscppcoreguidelines-pro-type-const-cast: 12 warningscppcoreguidelines-pro-type-member-init: 12 warningscert-oop54-cpp: 11 warningscppcoreguidelines-avoid-c-arrays: 9 warningscppcoreguidelines-rvalue-reference-param-not-moved: 5 warningscppcoreguidelines-use-enum-class: 5 warningscppcoreguidelines-use-default-member-init: 4 warningscppcoreguidelines-owning-memory: 3 warningscppcoreguidelines-prefer-member-initializer: 3 warningscppcoreguidelines-avoid-non-const-global-variables: 2 warningscppcoreguidelines-pro-bounds-constant-array-index: 2 warningscert-err58-cpp: 1 warningcppcoreguidelines-avoid-do-while: 1 warningcppcoreguidelines-pro-type-static-cast-downcast: 1 warningcppcoreguidelines-pro-type-vararg: 1 warningTip
See here for the list of all available checks with clang-tidy 21.1 and their descriptions.
All checks currently enabled by the default configuration are listed below (82 in total; 21 of these currently emit at least one a diagnostic):