Disable unsafe implicit conversion to std::string (#729)
This commit is contained in:
parent
d2bf93fe22
commit
d940fa679c
@ -629,8 +629,9 @@ inline typename std::enable_if<
|
|||||||
template <typename C, typename T, typename Char = typename C::char_type>
|
template <typename C, typename T, typename Char = typename C::char_type>
|
||||||
inline typename std::enable_if<
|
inline typename std::enable_if<
|
||||||
!convert_to_int<T, Char>::value &&
|
!convert_to_int<T, Char>::value &&
|
||||||
!std::is_convertible<T, basic_string_view<Char>>::value &&
|
!std::is_convertible<T, basic_string_view<Char>>::value,
|
||||||
!std::is_convertible<T, std::basic_string<Char>>::value,
|
// Implicit conversion to std::string is not handled here because it's
|
||||||
|
// unsafe: https://github.com/fmtlib/fmt/issues/729
|
||||||
typed_value<C, custom_type>>::type
|
typed_value<C, custom_type>>::type
|
||||||
make_value(const T &val) { return val; }
|
make_value(const T &val) { return val; }
|
||||||
|
|
||||||
|
@ -9,8 +9,7 @@ set(CMAKE_REQUIRED_FLAGS ${CPP14_FLAG})
|
|||||||
function (generate_source result fragment)
|
function (generate_source result fragment)
|
||||||
set(${result} "
|
set(${result} "
|
||||||
#define FMT_HEADER_ONLY 1
|
#define FMT_HEADER_ONLY 1
|
||||||
#include \"fmt/posix.h\"
|
#include \"fmt/format.h\"
|
||||||
#include \"fmt/ostream.h\"
|
|
||||||
int main() {
|
int main() {
|
||||||
${fragment}
|
${fragment}
|
||||||
}
|
}
|
||||||
@ -58,6 +57,14 @@ expect_compile_error("fmt::format(\"{}\", L\"foo\");")
|
|||||||
# mixing UTF-8 with UTF-16/32 can result in an invalid output.
|
# mixing UTF-8 with UTF-16/32 can result in an invalid output.
|
||||||
expect_compile_error("fmt::format(L\"{}\", \"foo\");")
|
expect_compile_error("fmt::format(L\"{}\", \"foo\");")
|
||||||
|
|
||||||
|
# Formatting a wide string with a narrow format string is forbidden.
|
||||||
|
expect_compile_error("
|
||||||
|
struct S {
|
||||||
|
operator std::string() const { return std::string(); }
|
||||||
|
};
|
||||||
|
fmt::format(\"{}\", S());
|
||||||
|
")
|
||||||
|
|
||||||
# Make sure that compiler features detected in the header
|
# Make sure that compiler features detected in the header
|
||||||
# match the features detected in CMake.
|
# match the features detected in CMake.
|
||||||
if (SUPPORTS_USER_DEFINED_LITERALS)
|
if (SUPPORTS_USER_DEFINED_LITERALS)
|
||||||
|
@ -1072,16 +1072,6 @@ TEST(FormatterTest, FormatStdStringView) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ConvertibleToString {
|
|
||||||
std::string s;
|
|
||||||
ConvertibleToString() : s("foo") {}
|
|
||||||
operator const std::string &() const { return s; }
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST(FormatterTest, FormatConvertibleToString) {
|
|
||||||
EXPECT_EQ("foo", format("{}", ConvertibleToString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ConvertibleToStringView {
|
struct ConvertibleToStringView {
|
||||||
operator fmt::string_view() const { return "foo"; }
|
operator fmt::string_view() const { return "foo"; }
|
||||||
};
|
};
|
||||||
|
@ -402,7 +402,7 @@ TEST(UtilTest, BitCast) {
|
|||||||
uint32_t u[2];
|
uint32_t u[2];
|
||||||
};
|
};
|
||||||
auto s = fmt::internal::bit_cast<S>(uint64_t(42));
|
auto s = fmt::internal::bit_cast<S>(uint64_t(42));
|
||||||
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), 42);
|
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), 42u);
|
||||||
s = fmt::internal::bit_cast<S>(uint64_t(~0ull));
|
s = fmt::internal::bit_cast<S>(uint64_t(~0ull));
|
||||||
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), ~0ull);
|
EXPECT_EQ(fmt::internal::bit_cast<uint64_t>(s), ~0ull);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user