Added a check for NULL pointer in fclose_deleter.

The deleter can be called on a null pointer by shared_ptr.

Also added tests with unique_ptr from Boost.Move and shared_ptr
from Boost.SmartPtr.
This commit is contained in:
Andrey Semashev 2022-09-21 18:09:42 +03:00
parent 3510f6244b
commit 00f4f11f14
3 changed files with 30 additions and 8 deletions

View File

@ -36,7 +36,8 @@ struct fclose_deleter
*/ */
void operator() (std::FILE* p) const BOOST_NOEXCEPT void operator() (std::FILE* p) const BOOST_NOEXCEPT
{ {
std::fclose(p); if (BOOST_LIKELY(!!p))
std::fclose(p);
} }
}; };

View File

@ -176,7 +176,7 @@ run demangle_test.cpp
run demangled_name_test.cpp run demangled_name_test.cpp
: : : <test-info>always_show_run_output ; : : : <test-info>always_show_run_output ;
run demangled_name_test.cpp : : : <rtti>off <test-info>always_show_run_output : demangled_name_test_no_rtti ; run demangled_name_test.cpp : : : <rtti>off <test-info>always_show_run_output : demangled_name_test_no_rtti ;
run scoped_enum.cpp ; run scoped_enum.cpp ;
compile-fail scoped_enum_compile_fail_conv_from_int.cpp compile-fail scoped_enum_compile_fail_conv_from_int.cpp
@ -186,8 +186,8 @@ compile-fail scoped_enum_compile_fail_conv_to_int.cpp
run underlying_type.cpp ; run underlying_type.cpp ;
compile fclose_deleter_test.cpp run fclose_deleter_test.cpp
: <target-os>windows:<define>_CRT_SECURE_NO_WARNINGS <target-os>windows:<define>_CRT_SECURE_NO_DEPRECATE ; : : : <target-os>windows:<define>_CRT_SECURE_NO_WARNINGS <target-os>windows:<define>_CRT_SECURE_NO_DEPRECATE ;
run pointer_traits_pointer_test.cpp ; run pointer_traits_pointer_test.cpp ;
run pointer_traits_element_type_test.cpp ; run pointer_traits_element_type_test.cpp ;

View File

@ -16,17 +16,29 @@
#include <cstdio> #include <cstdio>
#include <cstddef> #include <cstddef>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/move/unique_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#if !defined(BOOST_NO_CXX11_SMART_PTR) #if !defined(BOOST_NO_CXX11_SMART_PTR)
#include <memory> #include <memory>
#endif #endif
boost::movelib::unique_ptr< std::FILE, boost::fclose_deleter > make_boost_unique_file(const char* filename)
{
return boost::movelib::unique_ptr< std::FILE, boost::fclose_deleter >(std::fopen(filename, "w"));
}
boost::shared_ptr< std::FILE > make_boost_shared_file(const char* filename)
{
return boost::shared_ptr< std::FILE >(std::fopen(filename, "w"), boost::fclose_deleter());
}
#if !defined(BOOST_NO_CXX11_SMART_PTR) #if !defined(BOOST_NO_CXX11_SMART_PTR)
std::unique_ptr< std::FILE, boost::fclose_deleter > make_unique_file(const char* filename) std::unique_ptr< std::FILE, boost::fclose_deleter > make_std_unique_file(const char* filename)
{ {
return std::unique_ptr< std::FILE, boost::fclose_deleter >(std::fopen(filename, "w")); return std::unique_ptr< std::FILE, boost::fclose_deleter >(std::fopen(filename, "w"));
} }
std::shared_ptr< std::FILE > make_shared_file(const char* filename) std::shared_ptr< std::FILE > make_std_shared_file(const char* filename)
{ {
return std::shared_ptr< std::FILE >(std::fopen(filename, "w"), boost::fclose_deleter()); return std::shared_ptr< std::FILE >(std::fopen(filename, "w"), boost::fclose_deleter());
} }
@ -43,9 +55,18 @@ int main()
file = NULL; file = NULL;
} }
make_boost_unique_file(filename);
make_boost_shared_file(filename);
#if !defined(BOOST_NO_CXX11_SMART_PTR) #if !defined(BOOST_NO_CXX11_SMART_PTR)
make_unique_file(filename); make_std_unique_file(filename);
make_shared_file(filename); make_std_shared_file(filename);
#endif
// Test if the deleter can be called on a NULL pointer
boost::shared_ptr< std::FILE >(static_cast< std::FILE* >(NULL), boost::fclose_deleter());
#if !defined(BOOST_NO_CXX11_SMART_PTR)
std::shared_ptr< std::FILE >(static_cast< std::FILE* >(NULL), boost::fclose_deleter());
#endif #endif
std::remove(filename); std::remove(filename);