Workaround for gcc issue with FMT_STRING within if constexpr.

This fixes issue #1455 by making the return type explicit,
and adds a C++17-specific test to demonstrate the bug.
This commit is contained in:
Dair Grant 2020-03-05 12:48:01 +00:00
parent db4a6cfbf9
commit dac909b1dd
2 changed files with 22 additions and 12 deletions

View File

@ -3544,18 +3544,18 @@ FMT_CONSTEXPR internal::udl_arg<wchar_t> operator"" _a(const wchar_t* s,
#endif // FMT_USE_USER_DEFINED_LITERALS #endif // FMT_USE_USER_DEFINED_LITERALS
FMT_END_NAMESPACE FMT_END_NAMESPACE
#define FMT_STRING_IMPL(s, ...) \ #define FMT_STRING_IMPL(s, ...) \
[] { \ []() -> fmt::basic_string_view<fmt::remove_cvref_t<decltype(*s)>> { \
/* Use a macro-like name to avoid shadowing warnings. */ \ /* Use a macro-like name to avoid shadowing warnings. */ \
struct FMT_COMPILE_STRING : fmt::compile_string { \ struct FMT_COMPILE_STRING : fmt::compile_string { \
using char_type = fmt::remove_cvref_t<decltype(*s)>; \ using char_type = fmt::remove_cvref_t<decltype(*s)>; \
__VA_ARGS__ FMT_CONSTEXPR \ __VA_ARGS__ FMT_CONSTEXPR \
operator fmt::basic_string_view<char_type>() const { \ operator fmt::basic_string_view<char_type>() const { \
/* FMT_STRING only accepts string literals. */ \ /* FMT_STRING only accepts string literals. */ \
return fmt::internal::literal_to_view(s); \ return fmt::internal::literal_to_view(s); \
} \ } \
}; \ }; \
return FMT_COMPILE_STRING(); \ return FMT_COMPILE_STRING(); \
}() }()
/** /**

View File

@ -2570,3 +2570,13 @@ TEST(FormatTest, FormatUTF8Precision) {
EXPECT_EQ(result.size(), 5); EXPECT_EQ(result.size(), 5);
EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5))); EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5)));
} }
TEST(FormatTest, Issue1455) {
#if (__cplusplus >= 201703L)
if constexpr(true) {
EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), "foo"));
} else {
EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), "foo"));
}
#endif
}