From 4596e8938ea6ab43e806a3dc88bc6e0d2a3bd9ed Mon Sep 17 00:00:00 2001 From: Christian Mazakas Date: Wed, 21 Jan 2026 19:36:38 -0800 Subject: [PATCH] initialize object storage using tag dispatch Currently, the code branches on whether to use SBO or not using a runtime check, i.e. a raw `if(x)`. This can trick the msvc optimizer into believing the SBO path can be taken, which in the case of sufficiently large Callables triggers a buffer overrun warning as emplacing into the small buffer would exceed its size. By updating the code to instead dispatch at compile-time via tags, the msvc optimizer is no longer confused and the warning disappears as the code path is now truly unreachable. --- include/boost/compat/move_only_function.hpp | 29 ++++++++++++--------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/include/boost/compat/move_only_function.hpp b/include/boost/compat/move_only_function.hpp index 5511b52..d307a00 100644 --- a/include/boost/compat/move_only_function.hpp +++ b/include/boost/compat/move_only_function.hpp @@ -435,6 +435,22 @@ struct move_only_function_base { } + template + void init_object( std::false_type /* use_sbo */, CArgs&& ...args ) + { + s_.pobj_ = new VT( std::forward( args )... ); + invoke_ = &mo_invoke_object_holder::invoke_object; + manager_ = &manage_object; + } + + template + void init_object( std::true_type /* use_sbo */, CArgs&& ...args ) + { + new( s_.addr() ) VT( std::forward( args )... ); + invoke_ = &mo_invoke_local_holder::invoke_local; + manager_ = &manage_local; + } + template void init( std::false_type /* is_function */, CArgs&& ...args ) { @@ -444,18 +460,7 @@ struct move_only_function_base return; } - if( !storage::use_sbo() ) - { - s_.pobj_ = new VT( std::forward( args )... ); - invoke_ = &mo_invoke_object_holder::invoke_object; - manager_ = &manage_object; - } - else - { - new( s_.addr() ) VT( std::forward( args )... ); - invoke_ = &mo_invoke_local_holder::invoke_local; - manager_ = &manage_local; - } + init_object( std::integral_constant()>{}, std::forward( args )... ); } template