-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Introduce a new style of warning suppression based on push/pop #4285
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
@rwgk Went through a lot of trouble in a previous PR to remove all these warning pop push pragma warnings as they were bugprone for accidentally silencing warnings in downstream projects. So we try to avoid pushing / pop warning pragmas unless we don't have a choice. |
I changed it so that the push and pop are done at PYBIND11_NAMESPACE_BEGIN and PYBIND11_NAMESPACE_END We will never need to push and pop manually and so can't make mistakes. |
@rwgk Thoughts on this? |
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.
That is so cool! I didn't have the idea to tag the _Pragma onto PYBIND11_NAMESPACE when I was going through my round of cleanup.
I'm 100% for globally disabling the C4127 warning with your trick. It's just useless, almost harmful because of all the clutter it creates suppressing it locally. We already had discussions about that in the past.
I'll look more later. Today I'm very busy.
JIC you're interested in historical background, how we got to what you see: Column R in that sheet has a list of PRs. |
Yep, if this PR gets merged I would want to do a general cleanup of all warnings under this new system in a new PR. We would globally disable some, and swap others to other APIs as needed. |
Sounds awesome. I will look carefully here asap. It's not easy with git: if you branch from this branch to do a little bit of the follow-on steps, that might be useful for us to see exactly where it's going. |
Doing a quick pass, it looks like we would only want to globally disable Intel 2196 and MSVC C4127. The rest are good warnings, but should still be cleaned up quite a bit. The following regex gives all the lines that should be cleaned up:
|
The force push was just for rebase on current master. I didn't change anything. |
I wanted to see what it's like to work with the new system, practicing with e94b70f. It's great! Did you have someone special in mind for globally disabling that particular warning? — After my commit, there are only 6 header files and 2 test files that need Feel free to |
Works like a charm! There isn't that much more work in it (below). Looks like ~20-30 minutes of leg work, then mostly waiting for the CI and maybe fixing oversights. What do you think about doing that in this PR? I'd be happy to help if you want to split the work. It almost looks like too much fun getting rid of all those noisy pragma blocks.
|
Thanks for taking a look and finishing the cleanup for that file!
We should be able to just add our global disables to PYBIND11_NAMESPACE_BEGIN
Yep, updating them all in this PR is probably a good idea. I'll do that this weekend. The real question is whether to introduce PYBIND11_WARNING_BLOCK macros or to manually push/pop. |
I have a split mind about that: what we have right now is very low noise, lets us know in which files the C4127 suppression is actually needed, and doubles as a small reminder, to be less surprised when we need to add it to some new test in the future. Tagging it unconditionally to PYBIND11_NAMESPACE_BEGIN is only very slightly more convenient. That convenience may (mis)lead (IMO) people to dubious PYBIND11_NAMESPACE_BEGIN/END uses. I'm fine either way though.
Trying to understand: With this PR as is I'd use (actually, your code)
That's already far better than what we have right now. Is PYBIND11_WARNING_BLOCK for this situation, to make that even better? (How? it doesn't click for me TBH) |
PYBIND11_WARNING_BLOCK would take advantage of C++ scopes to force users to unpop as otherwise the compiler would throw an error. The way it would be implemented is:
Example code
If users forget to include END_WARNING_BLOCK, the compiler will throw an error. Compare that to our current setup, where the following will still compile
|
I'm a bit worried about using scopes: that could easily lead to accidents, too, variables getting shadowed. I think clang-tidy or some compilers warn or error out, but not all. I've lost some time over such mistakes on and off. Detecting missing pops could be an easy pre-commit hook. We could fold in detecting PYBIND11_NAMESPACE_BEGIN/END mismatches, which I was wishing for already, but never got to it. (I think I had a PR fixing a couple such oversights, but not worth digging up that number right now.) |
Yeah, I think you are right. PYBIND11_WARNING_BLOCK is probably not worth it since we can replace it with a very simple pre-commit hook. We can always add it later if the manual push/pops become a problem. I'll stick with the current design:
|
@rwgk Sorry for the delay, but I just cleared out the remaining #pragmas and fixed all the other issues. I think this PR is good to go! |
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.
Awesome! Just one naming suggestion.
(I dread the thought of resolving the merge conflicts with the smart_holder branch, but it's totally worth it!)
f12191a
to
f64bc2c
Compare
I just rebased this off the current master, so it should be ready for merging! |
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.
Wonderful!
@ax3l
@EricCousineau-TRI
@Skylion007
This PR has a lot of sprawling changes and will therefore bit-rot pretty quickly (if we merge other things).
Could you please help out getting this reviewed and merged soon? I believe this is a quick review:
- The only file that needs careful review is pybind11/detail/common.h, and even that is pretty repetitive (sections for each type of compiler).
- All the rest is boilerplate. It seems very unlikely that a serious issue with those changes could pass our extensive testing. I think if a couple more people spend 5 minutes each glancing through there isn't much that could still slip in accidentally.
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 awesome! Just a small nit-pick request about guidance for future devs.
The only one CI failure is an unrelated known flake ( Thanks @lalaland for this great work, thanks @EricCousineau-TRI for the review! |
…ased on push/pop)
…ased on push/pop)
…ased on push/pop)
Hi @lalaland, coincidentally, my attention got drawn to this change: For easy reference, that diff is: -#elif defined(__MINGW32__)
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#endif
+PYBIND11_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") IIUC, before this PR that warning suppression was specific to MINGW, but now it applies to all GCCs. Is that a correct understanding? Do you have ideas for making it specific again in a nice way? I guess I could simply put back |
Feel free to add the #if statement for MINGW32. Alternatively, if we have a lot of these, might be worth considering PYBIND11_WARNING_DISABLE_MINGW32 |
Description
As I was working through #4250, I realized that pybind11's warning suppression system is a bit too fragile. We can't globally disable any of the useless warnings like C4127 and it requires repeated compiler version checks in a lot of cases scattered throughout the code.
This PR introduces 2 things:
As pushes and pops are error-prone, the general plan should be to rely on PYBIND11_NAMESPACE_BEGIN and PYBIND11_NAMESPACE_END to do the required pushing and popping of warnings.
As an aside, I would also like to argue that we should globally disable C4127 (constant expression in if statement), but I think this PR is still useful even if we don't globally disable it.