From 0fb4d92d83a054fcbf50c51675e3d9aa7f664bd5 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Wed, 7 Feb 2024 15:12:36 +0300 Subject: [PATCH] Moved checked deleters into internal namespace to block unintended ADL. This prevents adding namespace boost to ADL when the deleters are used in template parameters, e.g. in std::unique_ptr. --- doc/changes.qbk | 6 ++-- include/boost/core/checked_delete.hpp | 9 ++++++ test/Jamfile.v2 | 4 +++ ...checked_array_deleter_compile_fail_adl.cpp | 30 +++++++++++++++++++ test/checked_deleter_compile_fail_adl.cpp | 30 +++++++++++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 test/checked_array_deleter_compile_fail_adl.cpp create mode 100644 test/checked_deleter_compile_fail_adl.cpp diff --git a/doc/changes.qbk b/doc/changes.qbk index ecaeffa..0213c9c 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -11,9 +11,9 @@ * Added a new [link core.functor `boost/core/functor.hpp`] header with a `functor` class template for wrapping a raw function into a function object class. -* Changed [link core.null_deleter `null_deleter`] and [link core.fclose_deleter `fclose_deleter`] - definitions so that they don't bring namespace `boost` into argument-dependent lookup in cases - like this: +* Changed [link core.null_deleter `null_deleter`], [link core.fclose_deleter `fclose_deleter`] + and [link.checked_delete checked deleter] definitions so that they don't bring namespace `boost` + into argument-dependent lookup in cases like this: ``` std::unique_ptr< std::FILE, boost::fclose_deleter > p1, p2; swap(p1, p2); // no longer looks for boost::swap as part of ADL diff --git a/include/boost/core/checked_delete.hpp b/include/boost/core/checked_delete.hpp index b74a43a..67f3c74 100644 --- a/include/boost/core/checked_delete.hpp +++ b/include/boost/core/checked_delete.hpp @@ -60,6 +60,10 @@ template inline void checked_array_delete(T * x) BOOST_NOEXCEPT delete [] x; } +// Block unintended ADL +namespace checked_deleters +{ + template struct checked_deleter { typedef void result_type; @@ -83,6 +87,11 @@ template struct checked_array_deleter } }; +} // namespace checked_deleters + +using checked_deleters::checked_deleter; +using checked_deleters::checked_array_deleter; + } // namespace boost #endif // #ifndef BOOST_CORE_CHECKED_DELETE_HPP diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 31d740d..2bc6a4b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -39,6 +39,10 @@ compile-fail checked_delete_fail.cpp : $(warnings-as-errors-off) ; compile-fail checked_delete_fail2.cpp : $(warnings-as-errors-off) ; +compile-fail checked_deleter_compile_fail_adl.cpp + : $(warnings-as-errors-off) ; +compile-fail checked_array_deleter_compile_fail_adl.cpp + : $(warnings-as-errors-off) ; compile ref_ct_test.cpp ; run ref_test.cpp ; diff --git a/test/checked_array_deleter_compile_fail_adl.cpp b/test/checked_array_deleter_compile_fail_adl.cpp new file mode 100644 index 0000000..f1db4ba --- /dev/null +++ b/test/checked_array_deleter_compile_fail_adl.cpp @@ -0,0 +1,30 @@ +/* + * Copyright Andrey Semashev 2024. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +/*! + * \file checked_array_deleter_compile_fail_adl.cpp + * \author Andrey Semashev + * \date 07.02.2024 + * + * This file tests that \c boost::checked_array_deleter doesn't bring namespace + * \c boost into ADL. + */ + +#include + +namespace boost { + +void check_adl(checked_array_deleter< int > const&) +{ +} + +} // namespace boost + +int main() +{ + // Must not find boost::check_adl + check_adl(boost::checked_array_deleter< int >()); +} diff --git a/test/checked_deleter_compile_fail_adl.cpp b/test/checked_deleter_compile_fail_adl.cpp new file mode 100644 index 0000000..c736f25 --- /dev/null +++ b/test/checked_deleter_compile_fail_adl.cpp @@ -0,0 +1,30 @@ +/* + * Copyright Andrey Semashev 2024. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ +/*! + * \file checked_deleter_compile_fail_adl.cpp + * \author Andrey Semashev + * \date 07.02.2024 + * + * This file tests that \c boost::checked_deleter doesn't bring namespace + * \c boost into ADL. + */ + +#include + +namespace boost { + +void check_adl(checked_deleter< int > const&) +{ +} + +} // namespace boost + +int main() +{ + // Must not find boost::check_adl + check_adl(boost::checked_deleter< int >()); +}