3838PYBIND11_WARNING_DISABLE_CLANG (" -Wgnu-zero-variadic-macro-arguments" )
3939#endif
4040
41- #if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914))
42- # define PYBIND11_STD_LAUNDER std::launder
43- # define PYBIND11_HAS_STD_LAUNDER 1
44- #else
45- # define PYBIND11_STD_LAUNDER
46- # define PYBIND11_HAS_STD_LAUNDER 0
47- #endif
4841#if defined(__GNUG__) && !defined(__clang__)
4942# include < cxxabi.h>
5043#endif
@@ -345,6 +338,10 @@ class cpp_function : public function {
345338 using namespace detail ;
346339 struct capture {
347340 remove_reference_t <Func> f;
341+
342+ static capture *from_data (void **data) {
343+ return PYBIND11_STD_LAUNDER (reinterpret_cast <capture *>(data));
344+ }
348345 };
349346
350347 /* Store the function including any extra state it might have (e.g. a lambda capture
@@ -364,7 +361,7 @@ class cpp_function : public function {
364361 PYBIND11_WARNING_DISABLE_GCC (" -Wplacement-new" )
365362#endif
366363
367- new (( capture *) & rec->data ) capture{std::forward<Func>(f)};
364+ new (capture::from_data ( rec->data ) ) capture{std::forward<Func>(f)};
368365
369366#if !PYBIND11_HAS_STD_LAUNDER
370367 PYBIND11_WARNING_DISABLE_GCC (" -Wstrict-aliasing" )
@@ -374,8 +371,8 @@ class cpp_function : public function {
374371 // a significant refactoring it's "impossible" to solve.
375372 if (!std::is_trivially_destructible<capture>::value) {
376373 rec->free_data = [](function_record *r) {
377- auto data = PYBIND11_STD_LAUNDER (( capture *) & r->data );
378- (void ) data;
374+ auto data = capture::from_data ( r->data );
375+ (void ) data; // suppress "unused variable" warnings
379376 data->~capture ();
380377 };
381378 }
@@ -492,6 +489,8 @@ class cpp_function : public function {
492489 using FunctionType = Return (*)(Args...);
493490 constexpr bool is_function_ptr
494491 = std::is_convertible<Func, FunctionType>::value && sizeof (capture) == sizeof (void *);
492+ PYBIND11_ENSURE_PRECONDITION_FOR_FUNCTIONAL_H_PERFORMANCE_OPTIMIZATIONS (
493+ !is_function_ptr || std::is_standard_layout<capture>::value);
495494 if (is_function_ptr) {
496495 rec->is_stateless = true ;
497496 rec->data [1 ]
0 commit comments