-
Notifications
You must be signed in to change notification settings - Fork 37.7k
ci: Treat IWYU violations as errors #26763
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
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
@@ -25,10 +25,10 @@ | |||
#include <fcntl.h> | |||
#include <sys/mman.h> | |||
#include <sys/select.h> | |||
#include <sys/socket.h> | |||
#include <sys/socket.h> // IWYU pragma: export |
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.
What symbols are these needed for (here and below), and what are the trade-offs between adding the pragma, and actually adding the include where it is used? We should probably have some rationale as to wether we are going to further include/"export" everything out of compat, or actually add includes to source files.
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.
What symbols are these needed for (here and below)...
#include <sys/socket.h> // for socklen_t, size_t, ssize_t
#include <netinet/in.h> // for in6_addr, in_addr, s6_addr
Both headers are non-Windows.
... and what are the trade-offs between adding the pragma, and actually adding the include where it is used?
Platform-specific headers require to be guarded with #ifdef ... #endif
macros. So adding them in every place, where they are required, is not very DRY.
We should probably have some rationale as to wether we are going to further include/"export" everything out of compat, or actually add includes to source files.
My suggestion is to "export" platform-specific headers out of compat.h
when IWYU points at them.
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.
#include <sys/socket.h> .... size_t, ssize_t
Is this a bug? size_t
/ssize_t
do not come from socket.h
.
So adding them in every place, where they are required, is not very DRY.
Isn't adding every header, everywhere it is used, the entire point of IWYU though?
This could also lead to having a single bloated compat.h, which when included everywhere, mitigates one of the other supposed benefit of IWYU, which is removing unneeded headers to reducing preprocessing time.
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.
It just seems more convenient to include compat.h or socks.h when using the Sock
wrapper, instead of having to deal with low-level system includes everywhere Sock
is used. I guess an alternative to the iwyu pragma would be to also wrap the low-level types, but not sure if this is actually better.
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.
#include <sys/socket.h> .... size_t, ssize_t
Is this a bug?
size_t
/ssize_t
do not come fromsocket.h
.
Perhaps, it is. But it is unrelated, as the socket.h
header is required to provide the socklen_t
symbol.
So adding them in every place, where they are required, is not very DRY.
Isn't adding every header, everywhere it is used, the entire point of IWYU though?
This could also lead to having a single bloated compat.h, which when included everywhere, mitigates one of the other supposed benefit of IWYU, which is removing unneeded headers to reducing preprocessing time.
That is not what I meant. The compat.h
header, which includes platform-specific headers, allows to avoid repetition of code like that:
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#endif
…sk back to "ASan..." one afc6052 ci: Move `--enable-c++20` from "tidy" task back to "ASan..." one (Hennadii Stepanov) Pull request description: This PR reverts cc7335e from bitcoin/bitcoin#25528 partially. C++20 has introduced some new headers, and it is premature to consider them when using the IWYU tool. Required for bitcoin/bitcoin#26763 and bitcoin/bitcoin#26766. Related discussions: - bitcoin/bitcoin#25528 (comment) - bitcoin/bitcoin#26763 (comment) ACKs for top commit: MarcoFalke: review only ACK afc6052 Tree-SHA512: 9c1d3317d0f7a94d46d1e442da1a91669cd9ed1e62a41579edc96e1f5447551b536d32eeb222caf277e85228482753be545e0a874208cb24f9a8491fce3b6d9f
Rebased 682a87e -> 9b7443d (pr26763.02 -> pr26763.03) on top of the #26770. |
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.
Concept ACK
src/chain.h
Outdated
#include <vector> | ||
|
||
namespace Consensus { | ||
struct Params; |
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.
Why drop the #include <consensus/params.h>
just to manually forward declare the struct? This seems like a backwards step. Seems better to either leave it as is, or move GetBlockProofEquivalentTime
back to pow.cpp
so that chain.h
doesn't need Consensus::Params
at all (partially reverting #7311 ; GBPET() is used in ConnectBlock() so it isn't really separate from consensus functionality for us).
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.
Why drop the
#include <consensus/params.h>
just to manually forward declare the struct?
Although forward declarations have their own pros and cons, this code base seems to lean in their favour:
$ git grep -e "struct Params;"
src/node/blockstorage.h:struct Params;
src/node/miner.h:namespace Consensus { struct Params; };
src/node/transaction.h:struct Params;
src/txdb.h:struct Params;
src/validation.h:struct Params;
src/zmq/zmqpublishnotifier.cpp:struct Params;
This seems like a backwards step.
Mind elaborating?
As a question like that has been raised, should we document our preferences in https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md?
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.
Mind elaborating?
If we've got a dependency from one module to another ("validation" depends on "consensus/params") then we should just include the header file; if we're avoiding a dependency (eg making "chain" just store chain data independent of whatever the consensus parameters might be), then we shouldn't be entangling them by referencing the "unrelated" module's definitions.
Some of those cases don't even avoid the dependency at all; eg validation.h includes chainparams.h which includes consensus/params.h anyway.
It makes the dependencies slightly harder to track: forward declarations are harder to search for than a plain #include; it also violates the DRY-principle, though not in a very big way.
The benefit is that not including the full header can reduce compilation time in the cases where you can avoid including a complicated header (eg, one that pulls in boost multiindex or that pulls in lots of other headers). That probably makes sense if you're avoiding pulling in txmempool.h (which validation.h does), but even then any effort's probably better spent in improving our modularisation...
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.
The changes in src/chain.h
appeared non-required for this PR, and they have been dropped.
The discussion about forward declaration vs header including could be continued elsewhere, maybe in a dedicated issue, couldn't it?
Updated 9b7443d -> a697950 (pr26763.03 -> pr26763.04):
|
src/test/fuzz/util/net.cpp
Outdated
@@ -21,6 +21,7 @@ | |||
#include <cstdlib> | |||
#include <cstring> | |||
#include <thread> | |||
#include <unordered_map> |
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.
Looks wrong as well?
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.
Well, in FuzzedSock::WaitMany()
function
bitcoin/src/test/fuzz/util/net.cpp
Lines 332 to 339 in 4717a5a
bool FuzzedSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const | |
{ | |
for (auto& [sock, events] : events_per_sock) { | |
(void)sock; | |
events.occurred = m_fuzzed_data_provider.ConsumeBool() ? events.requested : 0; | |
} | |
return true; | |
} |
EventsPerSock
is actually an std::unordered_map
: Line 218 in 2ec9782
using EventsPerSock = std::unordered_map<std::shared_ptr<const Sock>, Events, HashSharedPtrSock, EqualSharedPtrSock>; |
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.
Right, so it would need to include util/sock.h
instead to get EventsPerSock
?
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.
Thanks! Updated.
Some relevant IWYU's docs: https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/WhatIsAUse.md#re-exporting.
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.
This will force iwyu to remove #include <unordered_map>
if util/sock.h
is included, but an unrelated code piece needs the unordered map include?
Not sure which is preferable. I am just explaining the tradeoffs.
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.
What about // IWYU pragma: no_include <unordered_map>
in src/test/fuzz/util/net.cpp
?
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.
Seems worse (combining all downsides), compared to just including the file
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.
FWIW, I lean to just following IWYU's suggestion and including a header. It won't make a translation unit bigger anyway.
Updated a697950 -> ba0780b (pr26763.04 -> pr26763.05, diff):
|
Rebased ba0780b -> 077376c (pr26763.05 -> pr26763.06). |
Concept ACK. Seems like a good attempt to reduce review on the include list or avoid shipping a release with missing includes (on Linux fwiw). However, the CI output might be too cumbersome to act on. It would be nice if it also printed a nice diff to copy (or if there was a documented way to create one locally). |
Yea. I think in it's current state, this change will mostly just annoy contributors, for not much gain. Even more so if the CI is giving them nonsensical output (IWYU bugs), and it's not clear what should be done (add the wrong include, add a IWYU pragma inline, add a workaround to our |
It is possible to leverage the
The current state, in the master branch, is worse because using IWYU is a no-op effectively, but consumes resources. In case IWYU produces "nonsensical output" for any particular source file or header, the latter could just be skipped from analysis temporarily. |
Looks like that would need |
I disagree, it's not worse, because if you don't care about it, you don't have to engage / fix anything, and the resource usage/overhead is basically 0. It's also useful enough that if someone does want to use the tool / run it locally, they can. |
It doesn't help, unfortunately. |
Rebased and drafted. |
Could probably make sense to add this to the CI, to allow easy copy-pasting from Cirrus or from a local run. |
@@ -72,7 +72,7 @@ if [ "${RUN_TIDY}" = "true" ]; then | |||
" src/util/syserror.cpp"\ | |||
" src/util/threadinterrupt.cpp"\ | |||
" src/zmq"\ | |||
" -p . ${MAKEJOBS} -- -Xiwyu --cxx17ns -Xiwyu --mapping_file=${BASE_BUILD_DIR}/bitcoin-$HOST/contrib/devtools/iwyu/bitcoin.core.imp" | |||
" -p . ${MAKEJOBS} -- -Xiwyu --error -Xiwyu --cxx17ns -Xiwyu --mapping_file=${BASE_BUILD_DIR}/bitcoin-$HOST/contrib/devtools/iwyu/bitcoin.core.imp" |
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.
Light concept ACK if this change reduces review work and unburdens the review process, which seems more important than the potential annoyance it may add to opening a PR. Edit: I would likely find that this change makes working on a PR easier.
CI fails with
|
Thanks! Fixed. |
🐙 This pull request conflicts with the target branch and needs rebase. |
Fixes the #24831 (comment):