Don't crash if flush fails during unwinding
This commit is contained in:
parent
c1d9e88402
commit
dbdfc99fa1
@ -176,6 +176,13 @@ FMT_END_NAMESPACE_STD
|
|||||||
# define FMT_EXCEPTIONS 1
|
# define FMT_EXCEPTIONS 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
#if FMT_EXCEPTIONS
|
||||||
|
# define FMT_TRY try
|
||||||
|
# define FMT_CATCH(x) catch (x)
|
||||||
|
#else
|
||||||
|
# define FMT_TRY if (true)
|
||||||
|
# define FMT_CATCH(x) if (false)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.
|
// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.
|
||||||
#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && \
|
#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && \
|
||||||
@ -965,7 +972,12 @@ class iterator_buffer : public Traits, public buffer<T> {
|
|||||||
: Traits(other),
|
: Traits(other),
|
||||||
buffer<T>(grow, data_, 0, buffer_size),
|
buffer<T>(grow, data_, 0, buffer_size),
|
||||||
out_(other.out_) {}
|
out_(other.out_) {}
|
||||||
~iterator_buffer() { flush(); }
|
~iterator_buffer() {
|
||||||
|
FMT_TRY { flush(); }
|
||||||
|
FMT_CATCH(...) {
|
||||||
|
// Don't crash if flush fails during unwinding.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto out() -> OutputIt {
|
auto out() -> OutputIt {
|
||||||
flush();
|
flush();
|
||||||
|
@ -137,14 +137,6 @@ FMT_END_NAMESPACE
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_EXCEPTIONS
|
|
||||||
# define FMT_TRY try
|
|
||||||
# define FMT_CATCH(x) catch (x)
|
|
||||||
#else
|
|
||||||
# define FMT_TRY if (true)
|
|
||||||
# define FMT_CATCH(x) if (false)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FMT_MAYBE_UNUSED
|
#ifndef FMT_MAYBE_UNUSED
|
||||||
# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
|
# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
|
||||||
# define FMT_MAYBE_UNUSED [[maybe_unused]]
|
# define FMT_MAYBE_UNUSED [[maybe_unused]]
|
||||||
|
@ -851,3 +851,26 @@ FMT_END_NAMESPACE
|
|||||||
TEST(core_test, trappy_conversion) {
|
TEST(core_test, trappy_conversion) {
|
||||||
EXPECT_EQ(fmt::format("{}", its_a_trap()), "42");
|
EXPECT_EQ(fmt::format("{}", its_a_trap()), "42");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(core_test, throw_in_buffer_dtor) {
|
||||||
|
enum { buffer_size = 256 };
|
||||||
|
|
||||||
|
struct throwing_iterator {
|
||||||
|
int& count;
|
||||||
|
|
||||||
|
auto operator=(char) -> throwing_iterator& {
|
||||||
|
if (++count > buffer_size) throw std::exception();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
auto operator*() -> throwing_iterator& { return *this; }
|
||||||
|
auto operator++() -> throwing_iterator& { return *this; }
|
||||||
|
auto operator++(int) -> throwing_iterator { return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
int count = 0;
|
||||||
|
fmt::format_to(throwing_iterator{count}, fmt::runtime("{:{}}{"), "",
|
||||||
|
buffer_size + 1);
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user