From 844d8c224558966a745b20f4fbda28b64d243b5e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 3 Feb 2022 21:19:43 +0200 Subject: [PATCH] Enable BOOST_CURRENT_LOCATION at top level and in default arguments --- include/boost/assert/source_location.hpp | 58 ++++++++++++++----- test/Jamfile.v2 | 1 + test/source_location_test.cpp | 23 ++++++-- test/source_location_test3.cpp | 74 +++++++++++++++--------- test/source_location_test4.cpp | 42 ++++++++++++++ 5 files changed, 151 insertions(+), 47 deletions(-) create mode 100644 test/source_location_test4.cpp diff --git a/include/boost/assert/source_location.hpp b/include/boost/assert/source_location.hpp index c556f93..6bb1ad0 100644 --- a/include/boost/assert/source_location.hpp +++ b/include/boost/assert/source_location.hpp @@ -9,10 +9,12 @@ #include #include +#include #include #include #include #include +#include #if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L # include @@ -75,7 +77,9 @@ public: std::string to_string() const { - if( line() == 0 ) + unsigned long ln = line(); + + if( ln == 0 ) { return "(unknown source location)"; } @@ -84,18 +88,25 @@ public: char buffer[ 16 ]; - std::sprintf( buffer, ":%lu", static_cast( line() ) ); + std::sprintf( buffer, ":%lu", ln ); r += buffer; - if( column() ) + unsigned long co = column(); + + if( co ) { - std::sprintf( buffer, ":%lu", static_cast( column() ) ); + std::sprintf( buffer, ":%lu", co ); r += buffer; } - r += " in function '"; - r += function_name(); - r += '\''; + char const* fn = function_name(); + + if( *fn != 0 ) + { + r += " in function '"; + r += fn; + r += '\''; + } return r; } @@ -112,25 +123,42 @@ template std::basic_ostream & operator<<( std::basic_ost return os; } +namespace detail +{ + +inline char const* srcloc_strip_top_level( char const* fn ) +{ + return std::strcmp( fn, "top level" ) == 0? "": fn; +} + +} // namespace detail + } // namespace boost #if defined( BOOST_DISABLE_CURRENT_LOCATION ) -# define BOOST_CURRENT_LOCATION ::boost::source_location() +# define BOOST_CURRENT_LOCATION ::boost::source_location() -#elif defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L +#elif defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L && !BOOST_WORKAROUND(BOOST_MSVC, < 1931) -# define BOOST_CURRENT_LOCATION ::boost::source_location(std::source_location::current()) +# define BOOST_CURRENT_LOCATION ::boost::source_location(::std::source_location::current()) -#elif defined(__clang_analyzer__) +#elif defined(BOOST_DISABLE_CURRENT_FUNCTION) || defined(__clang_analyzer__) // https://bugs.llvm.org/show_bug.cgi?id=28480 -// Cast to char const* to placate clang-tidy -// https://bugs.llvm.org/show_bug.cgi?id=28480 -# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, static_cast(BOOST_CURRENT_FUNCTION)) +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, "") + +#elif defined(__GNUC__) + +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, ::boost::detail::srcloc_strip_top_level(__PRETTY_FUNCTION__)) + +# if defined(__clang__) +//# pragma clang diagnostic ignored "-W" +# endif #else -# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION) +// __func__ macros aren't allowed outside functions, but BOOST_CURRENT_LOCATION is +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, "") #endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index b7a9bfc..89d75bd 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -40,3 +40,4 @@ run current_function_test2.cpp ; run source_location_test.cpp ; run source_location_test2.cpp ; run source_location_test3.cpp ; +run source_location_test4.cpp ; diff --git a/test/source_location_test.cpp b/test/source_location_test.cpp index 1eaabf8..265984b 100644 --- a/test/source_location_test.cpp +++ b/test/source_location_test.cpp @@ -17,17 +17,28 @@ int main() } { - boost::source_location loc = BOOST_CURRENT_LOCATION; + boost::source_location loc( __FILE__, __LINE__, "main" ); BOOST_TEST_CSTR_EQ( loc.file_name(), __FILE__ ); BOOST_TEST_EQ( loc.line(), 20 ); - -#if !( defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L ) - - BOOST_TEST_CSTR_EQ( loc.function_name(), BOOST_CURRENT_FUNCTION ); + BOOST_TEST_CSTR_EQ( loc.function_name(), "main" ); BOOST_TEST_EQ( loc.column(), 0 ); + } -#endif + { + boost::source_location loc( "file", 1, "main", 2 ); + + BOOST_TEST_CSTR_EQ( loc.file_name(), "file" ); + BOOST_TEST_EQ( loc.line(), 1 ); + BOOST_TEST_CSTR_EQ( loc.function_name(), "main" ); + BOOST_TEST_EQ( loc.column(), 2 ); + } + + { + boost::source_location loc = BOOST_CURRENT_LOCATION; + + BOOST_TEST_CSTR_EQ( loc.file_name(), __FILE__ ); + BOOST_TEST_EQ( loc.line(), 38 ); } #if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L diff --git a/test/source_location_test3.cpp b/test/source_location_test3.cpp index ae73dd7..4e0bb86 100644 --- a/test/source_location_test3.cpp +++ b/test/source_location_test3.cpp @@ -23,34 +23,66 @@ int main() } { - boost::source_location loc( __FILE__, __LINE__, BOOST_CURRENT_FUNCTION ); - BOOST_TEST_EQ( loc.to_string(), std::string( __FILE__ ) + ":26 in function '" + BOOST_CURRENT_FUNCTION + "'" ); + boost::source_location loc( "file", 5, "" ); + BOOST_TEST_EQ( loc.to_string(), std::string( "file:5" ) ); } { - boost::source_location loc( __FILE__, __LINE__, BOOST_CURRENT_FUNCTION ); + boost::source_location loc( "file", 5, "" ); std::ostringstream os; os << loc; - BOOST_TEST_EQ( os.str(), std::string( __FILE__ ) + ":31 in function '" + BOOST_CURRENT_FUNCTION + "'" ); + BOOST_TEST_EQ( os.str(), std::string( "file:5" ) ); + } + + { + boost::source_location loc( "file", 7, "main" ); + BOOST_TEST_EQ( loc.to_string(), std::string( "file:7 in function 'main'" ) ); + } + + { + boost::source_location loc( "file", 7, "main" ); + + std::ostringstream os; + os << loc; + + BOOST_TEST_EQ( os.str(), std::string( "file:7 in function 'main'" ) ); + } + + { + boost::source_location loc( "file", 11, "main", 13 ); + BOOST_TEST_EQ( loc.to_string(), std::string( "file:11:13 in function 'main'" ) ); + } + + { + boost::source_location loc( "file", 11, "main", 13 ); + + std::ostringstream os; + os << loc; + + BOOST_TEST_EQ( os.str(), std::string( "file:11:13 in function 'main'" ) ); + } + + { + boost::source_location loc( "file", 17, "", 19 ); + BOOST_TEST_EQ( loc.to_string(), std::string( "file:17:19" ) ); + } + + { + boost::source_location loc( "file", 17, "", 19 ); + + std::ostringstream os; + os << loc; + + BOOST_TEST_EQ( os.str(), std::string( "file:17:19" ) ); } { boost::source_location loc = BOOST_CURRENT_LOCATION; - std::string prefix = std::string( __FILE__ ) + ":40"; - -#if !( defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L ) - - BOOST_TEST_EQ( loc.to_string(), prefix + " in function '" + BOOST_CURRENT_FUNCTION + "'" ); - -#else - - // column and function vary when coming from std::source_location::current() + std::string prefix = std::string( __FILE__ ) + ":82"; BOOST_TEST_EQ( loc.to_string().substr( 0, prefix.size() ), prefix ); - -#endif } { @@ -59,18 +91,8 @@ int main() std::ostringstream os; os << loc; - std::string prefix = std::string( __FILE__ ) + ":57"; - -#if !( defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L ) - - BOOST_TEST_EQ( os.str(), prefix + " in function '" + BOOST_CURRENT_FUNCTION + "'" ); - -#else - - // column and function vary when coming from std::source_location::current() + std::string prefix = std::string( __FILE__ ) + ":89"; BOOST_TEST_EQ( os.str().substr( 0, prefix.size() ), prefix ); - -#endif } return boost::report_errors(); diff --git a/test/source_location_test4.cpp b/test/source_location_test4.cpp new file mode 100644 index 0000000..35c78b5 --- /dev/null +++ b/test/source_location_test4.cpp @@ -0,0 +1,42 @@ +// Copyright 2022 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +boost::source_location s_loc = BOOST_CURRENT_LOCATION; + +boost::source_location f( boost::source_location const& loc = BOOST_CURRENT_LOCATION ) +{ + return loc; +} + +int main() +{ + { + BOOST_TEST_CSTR_EQ( s_loc.file_name(), __FILE__ ); + BOOST_TEST_EQ( s_loc.line(), 8 ); + BOOST_TEST_CSTR_EQ( s_loc.function_name(), "" ); + } + + { + boost::source_location loc = f(); + +#if defined(__cpp_lib_source_location) && __cpp_lib_source_location >= 201907L && !BOOST_WORKAROUND(BOOST_MSVC, < 1931) + + BOOST_TEST_CSTR_EQ( loc.file_name(), std::source_location::current().file_name() ); + BOOST_TEST_CSTR_EQ( loc.function_name(), std::source_location::current().function_name() ); + BOOST_TEST_EQ( loc.line(), 24 ); + +#else + + BOOST_TEST_CSTR_EQ( loc.file_name(), __FILE__ ); + BOOST_TEST_EQ( loc.line(), 10 ); + BOOST_TEST_CSTR_EQ( loc.function_name(), "" ); + +#endif + } + + return boost::report_errors(); +}