|
35 | 35 | # pragma GCC diagnostic ignored "-Wunused-but-set-parameter" |
36 | 36 | # pragma GCC diagnostic ignored "-Wunused-but-set-variable" |
37 | 37 | # pragma GCC diagnostic ignored "-Wmissing-field-initializers" |
38 | | -# pragma GCC diagnostic ignored "-Wstrict-aliasing" |
39 | 38 | # pragma GCC diagnostic ignored "-Wattributes" |
40 | 39 | # if __GNUC__ >= 7 |
41 | 40 | # pragma GCC diagnostic ignored "-Wnoexcept-type" |
|
49 | 48 | #include "detail/init.h" |
50 | 49 |
|
51 | 50 | #include <memory> |
| 51 | +#include <new> |
52 | 52 | #include <vector> |
53 | 53 | #include <string> |
54 | 54 | #include <utility> |
55 | 55 |
|
| 56 | +#if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914)) |
| 57 | +# define PYBIND11_STD_LAUNDER std::launder |
| 58 | +# define PYBIND11_HAS_STD_LAUNDER 1 |
| 59 | +#else |
| 60 | +# define PYBIND11_STD_LAUNDER |
| 61 | +# define PYBIND11_HAS_STD_LAUNDER 0 |
| 62 | +#endif |
56 | 63 | #if defined(__GNUG__) && !defined(__clang__) |
57 | 64 | # include <cxxabi.h> |
58 | 65 | #endif |
@@ -151,8 +158,21 @@ class cpp_function : public function { |
151 | 158 | #if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER) |
152 | 159 | # pragma GCC diagnostic pop |
153 | 160 | #endif |
| 161 | +#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER) |
| 162 | +# pragma GCC diagnostic push |
| 163 | +# pragma GCC diagnostic ignored "-Wstrict-aliasing" |
| 164 | +#endif |
| 165 | + // UB without std::launder, but without breaking ABI and/or |
| 166 | + // a significant refactoring it's "impossible" to solve. |
154 | 167 | if (!std::is_trivially_destructible<Func>::value) |
155 | | - rec->free_data = [](function_record *r) { ((capture *) &r->data)->~capture(); }; |
| 168 | + rec->free_data = [](function_record *r) { |
| 169 | + auto data = PYBIND11_STD_LAUNDER((capture *) &r->data); |
| 170 | + (void) data; |
| 171 | + data->~capture(); |
| 172 | + }; |
| 173 | +#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER) |
| 174 | +# pragma GCC diagnostic pop |
| 175 | +#endif |
156 | 176 | } else { |
157 | 177 | rec->data[0] = new capture { std::forward<Func>(f) }; |
158 | 178 | rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); }; |
|
0 commit comments