diff --git a/include/fmt/core.h b/include/fmt/core.h index bb56da7fffd6..e2abdece31c5 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1372,8 +1372,11 @@ template struct arg_mapper { // the C array overload. template < typename T, - FMT_ENABLE_IF(std::is_convertible::value && - !std::is_convertible::value)> + FMT_ENABLE_IF( + std::is_member_pointer::value || + std::is_function::type>::value || + (std::is_convertible::value && + !std::is_convertible::value))> FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { return {}; } 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..4f39c7ab5c77 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"); }