chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.81k stars 1.2k forks source link

Clang-Tidy: Null pointer dereference in any_executor::require #1291

Open res0nance opened 1 year ago

res0nance commented 1 year ago

When running clang tidy on our codebase we see the error

/myrepo/extern/repo/boost/libs/asio/include/boost/asio/execution/any_executor.hpp:1914:44: error: Access to field 'target' results in a dereference of a null pointer (loaded from field 'object_fns_') [clang-analyzer-core.NullDereference,-warnings-as-errors]
    return prop_fns_[found::index].require(object_fns_->target(*this),
                                           ^
/myrepo/myrepo/socketlib/socket/delegating_tcp.cpp:23:3: note: Calling 'post<boost::asio::any_io_executor, (lambda at /myrepo/myrepo/socketlib/socket/delegating_tcp.cpp:24:21)>'
  boost::asio::post(mSocket.get_executor(),
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/post.hpp:177:7: note: Calling constructor for 'initiate_post_with_executor<boost::asio::any_io_executor>'
      detail::initiate_post_with_executor<Executor>(ex), token);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/detail/initiate_post.hpp:104:7: note: Calling copy constructor for 'any_io_executor'
    : ex_(ex)
      ^~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/impl/any_io_executor.ipp:40:5: note: Calling copy constructor for 'any_executor<boost::asio::execution::context_as_t<boost::asio::execution_context &>, boost::asio::execution::detail::blocking::never_t<0>, boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0>>>'
  : base_type(static_cast<const base_type&>(e))
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/execution/any_executor.hpp:1666:7: note: Calling copy constructor for 'any_executor_base'
    : detail::any_executor_base(
      ^~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/execution/any_executor.hpp:664:5: note: Taking false branch
    if (!!other)
    ^
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/execution/any_executor.hpp:672:7: note: Null pointer value stored to field 'object_fns_'
      object_fns_ = 0;
      ^~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/execution/any_executor.hpp:1666:7: note: Returning from copy constructor for 'any_executor_base'
    : detail::any_executor_base(
      ^~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/impl/any_io_executor.ipp:40:5: note: Returning from copy constructor for 'any_executor<boost::asio::execution::context_as_t<boost::asio::execution_context &>, boost::asio::execution::detail::blocking::never_t<0>, boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0>>, boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0>>>'
  : base_type(static_cast<const base_type&>(e))
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/detail/initiate_post.hpp:104:7: note: Returning from copy constructor for 'any_io_executor'
    : ex_(ex)
      ^~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/post.hpp:177:7: note: Returning from constructor for 'initiate_post_with_executor<boost::asio::any_io_executor>'
      detail::initiate_post_with_executor<Executor>(ex), token);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/post.hpp:176:10: note: Calling 'async_initiate<(lambda at /myrepo/myrepo/socketlib/socket/delegating_tcp.cpp:24:21), void (), boost::asio::detail::initiate_post_with_executor<boost::asio::any_io_executor>, >'
  return async_initiate<NullaryToken, void()>(
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/async_result.hpp:895:10: note: Calling 'completion_handler_async_result::initiate'
  return async_result<typename decay<CompletionToken>::type,
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/async_result.hpp:482:5: note: Calling 'initiate_post_with_executor::operator()'
    BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
    ^
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/detail/config.hpp:135:37: note: expanded from macro 'BOOST_ASIO_MOVE_CAST'
# define BOOST_ASIO_MOVE_CAST(type) static_cast<type&&>
                                    ^
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/detail/initiate_post.hpp:143:11: note: Calling 'impl::operator()'
          boost::asio::require(ex_, execution::blocking.never),
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/require.hpp:336:12: note: Calling 'any_io_executor::require'
    return BOOST_ASIO_MOVE_CAST(T)(t).require(
           ^
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/detail/config.hpp:135:37: note: expanded from macro 'BOOST_ASIO_MOVE_CAST'
# define BOOST_ASIO_MOVE_CAST(type) static_cast<type&&>
                                    ^
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/impl/any_io_executor.ipp:98:10: note: Calling 'any_executor::require'
  return static_cast<const base_type&>(*this).require(p);
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/myrepo/extern/repo/boost/libs/asio/include/boost/asio/execution/any_executor.hpp:1914:44: note: Access to field 'target' results in a dereference of a null pointer (loaded from field 'object_fns_')
    return prop_fns_[found::index].require(object_fns_->target(*this),

My understanding of this bug is mostly that if anyexecutor has no `targetcalling require() will cause a nullptr dereference as it will dereference the nullobjectfns`