Add trap and unreachable

* Use both functions to exit on invalid behaviour
This commit is contained in:
Denis Blank 2017-10-03 21:03:27 +02:00
parent 54fb32ae56
commit 60c73a1a48
4 changed files with 43 additions and 7 deletions

View File

@ -387,9 +387,9 @@ struct error_callback<hints::signature_hint_tag<Args...>, Callback, Executor,
} }
}; };
/// Workaround for GCC bug: /// Once this was a workaround for GCC bug:
/// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095 /// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64095
struct empty_callback { struct final_callback {
template <typename... Args> template <typename... Args>
void operator()(Args... /*args*/) { void operator()(Args... /*args*/) {
} }
@ -398,7 +398,14 @@ struct empty_callback {
void set_value(Args... /*args*/) { void set_value(Args... /*args*/) {
} }
void set_exception(types::error_type /*error*/) { void set_exception(types::error_type error) {
(void)error;
#ifndef CONTINUABLE_WITH_UNHANDLED_ERRORS
// There were unhandled errors inside the asynchronous call chain!
// Define `CONTINUABLE_WITH_UNHANDLED_ERRORS` in order
// to ignore unhandled errors!"
util::trap();
#endif // CONTINUABLE_WITH_UNHANDLED_ERRORS
} }
}; };
} // namespace callbacks } // namespace callbacks
@ -518,7 +525,7 @@ auto chain_error_handler(Continuation&& continuation, Callback&& callback,
template <typename Continuation> template <typename Continuation>
void finalize_continuation(Continuation&& continuation) { void finalize_continuation(Continuation&& continuation) {
attorney::invoke_continuation(std::forward<Continuation>(continuation), attorney::invoke_continuation(std::forward<Continuation>(continuation),
callbacks::empty_callback{}); callbacks::final_callback{});
} }
/// Workaround for GCC bug: /// Workaround for GCC bug:

View File

@ -34,6 +34,7 @@
#include <type_traits> #include <type_traits>
#include <continuable/detail/api.hpp> #include <continuable/detail/api.hpp>
#include <continuable/detail/traits.hpp>
#include <continuable/detail/util.hpp> #include <continuable/detail/util.hpp>
namespace cti { namespace cti {

View File

@ -37,6 +37,7 @@
#include <continuable/detail/features.hpp> #include <continuable/detail/features.hpp>
#include <continuable/detail/hints.hpp> #include <continuable/detail/hints.hpp>
#include <continuable/detail/types.hpp> #include <continuable/detail/types.hpp>
#include <continuable/detail/util.hpp>
namespace cti { namespace cti {
namespace detail { namespace detail {
@ -92,13 +93,19 @@ public:
void operator()(Args... args) { void operator()(Args... args) {
this->resolve(promise_, std::move(args)...); this->resolve(promise_, std::move(args)...);
} }
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \
!defined(CONTINUABLE_WITH_NO_EXCEPTIONS)
/// Resolves the promise through the exception /// Resolves the promise through the exception
void operator()(types::dispatch_error_tag, types::error_type error) { void operator()(types::dispatch_error_tag, types::error_type error) {
#if !defined(CONTINUABLE_WITH_CUSTOM_ERROR_TYPE) && \
!defined(CONTINUABLE_WITH_NO_EXCEPTIONS)
promise_.set_exception(error); promise_.set_exception(error);
} #else
// Can't forward a std::error_condition or custom error type
// to a std::promise. Handle the error first in order
// to prevent this trap!
util::trap();
#endif #endif
}
/// Returns the future from the promise /// Returns the future from the promise
auto get_future() { auto get_future() {

View File

@ -241,6 +241,27 @@ private:
/// Is true when the automatic invocation on destruction is disabled /// Is true when the automatic invocation on destruction is disabled
bool frozen_ : 1; bool frozen_ : 1;
}; };
/// Hint for the compiler that this point should be unreachable
[[noreturn]] inline void unreachable() {
#ifdef _MSC_VER
__assume(false);
#elif __has_builtin(__builtin_unreachable)
__builtin_unreachable();
#endif
}
/// Causes the application to exit abnormally because we are
/// in an invalid state.
[[noreturn]] inline void trap() {
#ifdef _MSC_VER
__debugbreak();
#elif __has_builtin(__builtin_trap)
__builtin_trap();
#else
*(volatile int*)0 = 0;
#endif
}
} // namespace util } // namespace util
} // namespace detail } // namespace detail
} // namespace cti } // namespace cti