trompeloeil: Segmentation fault / infinite loop in regular expression when handling fmt::is_formattable types
So this is weird, but in
#include <fmt/format.h>
#include <trompeloeil.hpp>
#include <type_traits>
#if 1
namespace trompeloeil {
template<typename T>
struct printer<T, typename std::enable_if<fmt::is_formattable<T>::value>::type>
{
static void print(std::ostream& os, const T& t) noexcept { os << fmt::format("{}", t); }
};
}
#endif
class mock
{
public:
MAKE_MOCK1(function_call, void(const std::string& text));
};
int main() {
mock test;
REQUIRE_CALL_V(test, function_call(trompeloeil::re("A")));
#if 0
test.function_call("A");
#else
test.function_call("B");
#endif
}
I get an infinite loop (optimized build) or segmentation fault with a backtrace with a loooooong recursion of trompeloeil::duck_typed_matcher<trompeloeil::lambdas::regex_check, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::operator char const*&&<char const*, void, bool>() const ( this=0x4632b8) at trompeloeil/include/trompeloeil.hpp:1151 (debug build) as long as those #if are as they are. If you remove the printer, or make the regular expression match, the problem goes away.
The problem happens with both gcc 11.2 and clang 13.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 19 (10 by maintainers)
I think
fmtotherwise concludes thattrompeloeil::reis printable as a C-string, since it wants to instantiate the conversion toconst char*operator, which triggers the infinite recursion.Yes, that makes it work. As does using
fmt::print(os, "{}", t);(after includingfmt/ostream.h) instead ofos << fmt::format("{}", t);About versions, it’s easy to use the latest ones, specially if you go for header-only