-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Enable -Wstrict-aliasing warning #2816
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
9576122 to
6154bf5
Compare
bstaletic
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.
Previous run, which errored: https://github.com/pybind/pybind11/pull/2816/checks?check_run_id=1755015877
include/pybind11/detail/common.h
Outdated
| #if defined(__has_include) && __has_include(<version>) | ||
| # include <version> | ||
| #endif |
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.
Since C++20, __cpp_lib_foo feature test macros are in <version> header and at least clang respects that.
include/pybind11/pybind11.h
Outdated
| #if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914)) | ||
| # define PYBIND11_STD_LAUNDER std::launder | ||
| # define PYBIND11_HAS_STD_LAUNDER 1 | ||
| #else | ||
| # define PYBIND11_STD_LAUNDER | ||
| # define PYBIND11_HAS_STD_LAUNDER 0 | ||
| #endif | ||
|
|
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 is the best check that @YannickJadoul and I could come up with.
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.
Like I mentioned in the other comment, __cpp_lib_launder will be defined in <version> in C++20. If I define these macros here, I won't get that header from detail/common.h.
Should I include <version> here? Move these macro definitions to common.h?
Also defined(__cpp_lib_launder) should be defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606.
include/pybind11/pybind11.h
Outdated
| # if !PYBIND11_HAS_STD_LAUNDER | ||
| # pragma GCC diagnostic ignored "-Wstrict-aliasing" | ||
| # endif |
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.
In case we don't have std::launder, we can't tackle -Wstrict-aliasin. At least not easily, without breaking or a major refactoring.
include/pybind11/pybind11.h
Outdated
| #endif | ||
| if (!std::is_trivially_destructible<Func>::value) | ||
| rec->free_data = [](function_record *r) { ((capture *) &r->data)->~capture(); }; | ||
| rec->free_data = [](function_record *r) { PYBIND11_STD_LAUNDER((capture *) &r->data)->~capture(); }; |
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.
As far as I know, this is the only place where we need to launder.
6154bf5 to
d68f534
Compare
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.
I wish there was a way to avoid std::launder (and UB on C++<17), but ... myeah, it's better than before, at least.
include/pybind11/pybind11.h
Outdated
| #if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914)) | ||
| # define PYBIND11_STD_LAUNDER std::launder | ||
| # define PYBIND11_HAS_STD_LAUNDER 1 | ||
| #else | ||
| # define PYBIND11_STD_LAUNDER | ||
| # define PYBIND11_HAS_STD_LAUNDER 0 |
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.
Oh, I'd still move this up (underneath detail/common.h) having been included?
fe06e0a to
0e4e1c6
Compare
include/pybind11/pybind11.h
Outdated
| #if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 | ||
| # pragma GCC diagnostic pop | ||
| #endif | ||
| #if !PYBIND11_HAS_STD_LAUNDER |
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.
| #if !PYBIND11_HAS_STD_LAUNDER | |
| #if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER |
or
| #if !PYBIND11_HAS_STD_LAUNDER | |
| #if defined(__GNUG__) && !defined(__clang__) && !PYBIND11_HAS_STD_LAUNDER |
e7225e6 to
257af0e
Compare
e6ddb66 to
98bae49
Compare
|
I was not expecting that to work, but that message seems to have been received... |
98bae49 to
ca1e08d
Compare
#2819) * When determining if a shared_ptr already exists, use a test on the weak_ptr instead of a try/catch block. * When determining if a shared_ptr already exists, use a test on the weak_ptr instead of a try/catch block. * weak_from_this is only available in C++17 and later * Switch to use feature flag instead of C++ version flag. * Add Microsoft-specific check. * Avoid undefined preprocessor macro warning treated as error. * Simplify shared_from_this in init_holder * Include <version> in detail/common.h (~stolen~ borrowed from @bstaletic's #2816) * Move class_::get_shared_from_this to detail::try_get_shared_from_this * Simplify try_get_shared_from_this by using weak_ptr::lock() Co-authored-by: Yannick Jadoul <[email protected]>
ca1e08d to
1578e69
Compare
|
I think I got this to work on icc as well. |
henryiii
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.
Always happy to see these ignores go away (even if only conditionally)! And become more specific to the code they are there for.
I'm wondering if things like missing-field-initializers can go away after the last few PRs fixing clang-tidy?
Not quite, I can enable that clang-tidy check too. |
I tried and gcc 11 did not complain. However, this is surprising: |
rwgk
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.
The pragma block at the top of pybind11.h is evil (I lost a few hours already because of this), nice to see at least one item go.
Side remark: The repetition of a complex #if for the pragma ... pop seems unfortunate (DRY) but is common practice. Might be nice to go through at some point to do something like this:
#if something complicated
# pragma ...
# define PYBIND11_PRAGMA_ACTIVE 1
#endif
...
#if defined(PYBIND11_PRAGMA_ACTIVE)
# pragma ...
# undef PYBIND11_PRAGMA_ACTIVE
#endif
None of our sanitizers picks up on this. I think they would if it was real. |
…andard_layout`) https://chatgpt.com/share/67ea07fa-9afc-8008-95af-4d7e0829a9c2 Apply std::launder consistently to functional capture storage This commit improves the robustness and clarity of pybind11's internal capture mechanism for bound C++ callables stored in function_record. - Introduces `capture::from_data(void**)` to encapsulate reinterpretation of the in-place `capture` object stored in `rec->data`, ensuring consistent use of `std::launder`. - Adds a `static_assert` that verifies `capture` is standard layout, making explicit the precondition necessary for these low-level performance optimizations. - Centralizes the `PYBIND11_STD_LAUNDER` and `PYBIND11_HAS_STD_LAUNDER` macros into `common.h` to enable reuse across headers. - Replaces ad hoc laundering and strict aliasing warnings with a more principled and maintainable approach. This refines and generalizes the use of `std::launder` introduced in PR pybind#2816 (2021-07-15), addressing undefined behavior more thoroughly while preserving ABI and performance characteristics.
Description
Even though our cmake uses
-fno-strict-aliasing, not all extensions do. Since C++17, we can actually fix-Wstrict-aliasingerrors. For now, let's just see how things fail in CI.Suggested changelog entry: