From 75f3115c94167de32e1ae18ffd489a13ad863297 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 23 Nov 2021 21:09:06 +0200 Subject: [PATCH 1/6] thou shall not pass --- include/fmt/core.h | 50 +++++++++++++++++++++++++- test/compile-error-test/CMakeLists.txt | 6 ++++ test/core-test.cc | 7 ++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index bb56da7fffd6..de6164feb620 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1146,6 +1146,9 @@ constexpr bool is_arithmetic_type(type t) { struct unformattable {}; struct unformattable_char : unformattable {}; struct unformattable_const : unformattable {}; +struct unformattable_function_pointer : unformattable {}; +struct unformattable_member_function_pointer : unformattable {}; +struct unformattable_member_object_pointer : unformattable {}; struct unformattable_pointer : unformattable {}; template struct string_value { @@ -1228,6 +1231,9 @@ template class value { value(unformattable_char); value(unformattable_const); value(unformattable_pointer); + value(unformattable_function_pointer); + value(unformattable_member_function_pointer); + value(unformattable_member_object_pointer); private: // Formats an argument of a custom type, such as a user-defined class. @@ -1368,11 +1374,32 @@ template struct arg_mapper { return val; } + template >::type>::value)> + FMT_CONSTEXPR auto map(const T&) -> unformattable_function_pointer { + return {}; + } + + template ::value)> + FMT_CONSTEXPR auto map(const T&) -> unformattable_member_object_pointer { + return {}; + } + + template ::value)> + FMT_CONSTEXPR auto map(const T&) -> unformattable_member_function_pointer { + return {}; + } + // We use SFINAE instead of a const T* parameter to avoid conflicting with // the C array overload. + template < typename T, - FMT_ENABLE_IF(std::is_convertible::value && + FMT_ENABLE_IF(!std::is_function>::type>::value && + std::is_convertible::value && !std::is_convertible::value)> FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { return {}; @@ -1677,6 +1704,27 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T&& val) -> value { static_assert(formattable_pointer, "Formatting of non-void pointers is disallowed."); + // Formatting of function pointers is disallowed. + constexpr bool formattable_function_pointer = + !std::is_same::value; + static_assert(formattable_function_pointer, + "Formatting of function pointers is disallowed."); + + // Formatting of member function pointers is disallowed. + constexpr bool formattable_member_function_pointer = + !std::is_same::value; + static_assert(formattable_member_function_pointer, + "Formatting of member function pointers is disallowed."); + + // Formatting of member object pointers is disallowed. + constexpr bool formattable_member_object_pointer = + !std::is_same::value; + static_assert(formattable_member_object_pointer, + "Formatting of member object pointers is disallowed."); + constexpr bool formattable = !std::is_same::value; static_assert( diff --git a/test/compile-error-test/CMakeLists.txt b/test/compile-error-test/CMakeLists.txt index 8202f279434e..44bbb1aba020 100644 --- a/test/compile-error-test/CMakeLists.txt +++ b/test/compile-error-test/CMakeLists.txt @@ -67,6 +67,12 @@ expect_compile_error(" fmt::format(\"{}\", S()); ") +# Formatting a function +expect_compile_error(" + void (*f)(); + fmt::format(\"{}\", f); +") + # Make sure that compiler features detected in the header # match the features detected in CMake. if (SUPPORTS_USER_DEFINED_LITERALS) diff --git a/test/core-test.cc b/test/core-test.cc index da3bc0f96cd1..e1383e841569 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -770,6 +770,13 @@ TEST(core_test, is_formattable) { static_assert(!fmt::is_formattable::value, ""); static_assert(!fmt::is_formattable::value, ""); static_assert(!fmt::is_formattable::value, ""); + + static_assert(!fmt::is_formattable::value, ""); + + struct S; + + static_assert(!fmt::is_formattable::value, ""); + static_assert(!fmt::is_formattable::value, ""); } TEST(core_test, format) { EXPECT_EQ(fmt::format("{}", 42), "42"); } From 22235d2a6621c339ea23480f01a55157149b687c Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 23 Nov 2021 21:21:46 +0200 Subject: [PATCH 2/6] tiny_snake --- test/core-test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/core-test.cc b/test/core-test.cc index e1383e841569..4f39c7ab5c77 100644 --- a/test/core-test.cc +++ b/test/core-test.cc @@ -773,10 +773,10 @@ TEST(core_test, is_formattable) { static_assert(!fmt::is_formattable::value, ""); - struct S; + struct s; - static_assert(!fmt::is_formattable::value, ""); - static_assert(!fmt::is_formattable::value, ""); + static_assert(!fmt::is_formattable::value, ""); + static_assert(!fmt::is_formattable::value, ""); } TEST(core_test, format) { EXPECT_EQ(fmt::format("{}", 42), "42"); } From c010b42d07f1725dd0fccd9d1bf8a8e1b92ba105 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 23 Nov 2021 21:56:05 +0200 Subject: [PATCH 3/6] Simplify --- include/fmt/core.h | 45 +++++++++------------------------------------ 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index de6164feb620..029d941bd688 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1146,9 +1146,6 @@ constexpr bool is_arithmetic_type(type t) { struct unformattable {}; struct unformattable_char : unformattable {}; struct unformattable_const : unformattable {}; -struct unformattable_function_pointer : unformattable {}; -struct unformattable_member_function_pointer : unformattable {}; -struct unformattable_member_object_pointer : unformattable {}; struct unformattable_pointer : unformattable {}; template struct string_value { @@ -1231,9 +1228,6 @@ template class value { value(unformattable_char); value(unformattable_const); value(unformattable_pointer); - value(unformattable_function_pointer); - value(unformattable_member_function_pointer); - value(unformattable_member_object_pointer); private: // Formats an argument of a custom type, such as a user-defined class. @@ -1375,20 +1369,20 @@ template struct arg_mapper { } template >::type>::value)> - FMT_CONSTEXPR auto map(const T&) -> unformattable_function_pointer { + FMT_ENABLE_IF( + std::is_function::type>::value)> + FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { return {}; } template ::value)> - FMT_CONSTEXPR auto map(const T&) -> unformattable_member_object_pointer { + FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { return {}; } template ::value)> - FMT_CONSTEXPR auto map(const T&) -> unformattable_member_function_pointer { + FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { return {}; } @@ -1397,10 +1391,10 @@ template struct arg_mapper { template < typename T, - FMT_ENABLE_IF(!std::is_function>::type>::value && - std::is_convertible::value && - !std::is_convertible::value)> + FMT_ENABLE_IF( + !std::is_function::type>::value && + std::is_convertible::value && + !std::is_convertible::value)> FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { return {}; } @@ -1704,27 +1698,6 @@ FMT_CONSTEXPR FMT_INLINE auto make_arg(T&& val) -> value { static_assert(formattable_pointer, "Formatting of non-void pointers is disallowed."); - // Formatting of function pointers is disallowed. - constexpr bool formattable_function_pointer = - !std::is_same::value; - static_assert(formattable_function_pointer, - "Formatting of function pointers is disallowed."); - - // Formatting of member function pointers is disallowed. - constexpr bool formattable_member_function_pointer = - !std::is_same::value; - static_assert(formattable_member_function_pointer, - "Formatting of member function pointers is disallowed."); - - // Formatting of member object pointers is disallowed. - constexpr bool formattable_member_object_pointer = - !std::is_same::value; - static_assert(formattable_member_object_pointer, - "Formatting of member object pointers is disallowed."); - constexpr bool formattable = !std::is_same::value; static_assert( From 17024c259fed5e49a143f564dca3b0c5deffb91b Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 23 Nov 2021 21:59:51 +0200 Subject: [PATCH 4/6] Simplify more --- include/fmt/core.h | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 029d941bd688..3b0537eaabc1 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1368,33 +1368,17 @@ template struct arg_mapper { return val; } - template ::type>::value)> - FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { - return {}; - } - - template ::value)> - FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { - return {}; - } - - template ::value)> - FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { - return {}; - } - // We use SFINAE instead of a const T* parameter to avoid conflicting with // the C array overload. template < typename T, FMT_ENABLE_IF( - !std::is_function::type>::value && - std::is_convertible::value && - !std::is_convertible::value)> + std::is_member_object_pointer::value || + std::is_member_function_pointer::value || + std::is_function::type>::value || + (std::is_convertible::value && + !std::is_convertible::value))> FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { return {}; } From ad48b6ee91d21023a2e735ca5c6b938443325e78 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 23 Nov 2021 22:02:11 +0200 Subject: [PATCH 5/6] and more --- include/fmt/core.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 3b0537eaabc1..4ddf17eb6c9b 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1374,8 +1374,7 @@ template struct arg_mapper { template < typename T, FMT_ENABLE_IF( - std::is_member_object_pointer::value || - std::is_member_function_pointer::value || + std::is_member_pointer::value || std::is_function::type>::value || (std::is_convertible::value && !std::is_convertible::value))> From 705292aaccf169f588cf3684a7b88c5a26c6000e Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Tue, 23 Nov 2021 22:05:22 +0200 Subject: [PATCH 6/6] -newline --- include/fmt/core.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/fmt/core.h b/include/fmt/core.h index 4ddf17eb6c9b..e2abdece31c5 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1370,7 +1370,6 @@ template struct arg_mapper { // We use SFINAE instead of a const T* parameter to avoid conflicting with // the C array overload. - template < typename T, FMT_ENABLE_IF(