diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 08c51c6f92..59ee31c527 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -35,7 +35,6 @@ # pragma GCC diagnostic ignored "-Wunused-but-set-parameter" # pragma GCC diagnostic ignored "-Wunused-but-set-variable" # pragma GCC diagnostic ignored "-Wmissing-field-initializers" -# pragma GCC diagnostic ignored "-Wstrict-aliasing" # pragma GCC diagnostic ignored "-Wattributes" # if __GNUC__ >= 7 # pragma GCC diagnostic ignored "-Wnoexcept-type" @@ -48,10 +47,18 @@ #include "detail/init.h" #include +#include #include #include #include +#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 #if defined(__GNUG__) && !defined(__clang__) # include #endif @@ -150,8 +157,21 @@ class cpp_function : public function { #if defined(__GNUG__) && !defined(__clang__) && __GNUC__ >= 6 # pragma GCC diagnostic pop #endif +#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + // UB without std::launder, but without breaking ABI and/or + // a significant refactoring it's "impossible" to solve. if (!std::is_trivially_destructible::value) - rec->free_data = [](function_record *r) { ((capture *) &r->data)->~capture(); }; + rec->free_data = [](function_record *r) { + auto data = PYBIND11_STD_LAUNDER((capture *) &r->data); + (void) data; + data->~capture(); + }; +#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER) +# pragma GCC diagnostic pop +#endif } else { rec->data[0] = new capture { std::forward(f) }; rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };