Lift control flow compiler intrinsics into the used scope

* Also make UNREACHABLE trap in debug mode
This commit is contained in:
Denis Blank 2019-08-27 03:22:34 +02:00
parent 42af23fa03
commit 422b6138cd
4 changed files with 47 additions and 35 deletions

View File

@ -140,7 +140,7 @@ struct proxy_continuable<identity<Args...>, Continuation> : Continuation {
} }
std::tuple<Args...> operator()(query_arg_t) { std::tuple<Args...> operator()(query_arg_t) {
util::unreachable(); CTI_DETAIL_UNREACHABLE();
} }
}; };
@ -671,12 +671,12 @@ struct final_callback : util::non_copyable {
std::rethrow_exception(error); std::rethrow_exception(error);
} catch (std::exception const& exception) { } catch (std::exception const& exception) {
(void)exception; (void)exception;
util::trap(); CTI_DETAIL_TRAP();
} catch (...) { } catch (...) {
util::trap(); CTI_DETAIL_TRAP();
} }
#else #else
util::trap(); CTI_DETAIL_TRAP();
#endif #endif
#endif // CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS #endif // CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS
} }
@ -800,7 +800,7 @@ struct chained_continuation<identity<Args...>, identity<NextArgs...>,
} }
std::tuple<NextArgs...> operator()(query_arg_t) { std::tuple<NextArgs...> operator()(query_arg_t) {
util::unreachable(); CTI_DETAIL_UNREACHABLE();
} }
}; };
// Specialization to unpack ready continuables directly // Specialization to unpack ready continuables directly
@ -843,7 +843,7 @@ struct chained_continuation<identity<Args...>, identity<NextArgs...>,
} }
std::tuple<NextArgs...> operator()(query_arg_t) { std::tuple<NextArgs...> operator()(query_arg_t) {
util::unreachable(); CTI_DETAIL_UNREACHABLE();
} }
}; };

View File

@ -119,7 +119,7 @@ public:
std::rethrow_exception(result_.get_exception()); std::rethrow_exception(result_.get_exception());
#else // CONTINUABLE_HAS_EXCEPTIONS #else // CONTINUABLE_HAS_EXCEPTIONS
// Returning error types in await isn't supported as of now // Returning error types in await isn't supported as of now
util::trap(); CTI_DETAIL_TRAP();
#endif // CONTINUABLE_HAS_EXCEPTIONS #endif // CONTINUABLE_HAS_EXCEPTIONS
} }
@ -222,7 +222,7 @@ struct promise_type
promise_.set_exception(std::current_exception()); promise_.set_exception(std::current_exception());
#else // CONTINUABLE_HAS_EXCEPTIONS #else // CONTINUABLE_HAS_EXCEPTIONS
// Returning error types from coroutines isn't supported // Returning error types from coroutines isn't supported
cti::detail::util::trap(); CTI_DETAIL_TRAP();
#endif // CONTINUABLE_HAS_EXCEPTIONS #endif // CONTINUABLE_HAS_EXCEPTIONS
} }
}; };

View File

@ -103,7 +103,7 @@ public:
// Can't forward a std::error_condition or custom error type // Can't forward a std::error_condition or custom error type
// to a std::promise. Handle the error first in order // to a std::promise. Handle the error first in order
// to prevent this trap! // to prevent this trap!
util::trap(); CTI_DETAIL_TRAP();
#endif // CONTINUABLE_HAS_EXCEPTIONS #endif // CONTINUABLE_HAS_EXCEPTIONS
} }

View File

@ -39,6 +39,35 @@
#include <continuable/detail/features.hpp> #include <continuable/detail/features.hpp>
#include <continuable/detail/utility/traits.hpp> #include <continuable/detail/utility/traits.hpp>
/// Hint for the compiler that this point should be unreachable
#if defined(_MSC_VER)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_UNREACHABLE_INTRINSIC() __assume(false)
#elif defined(__GNUC__)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_UNREACHABLE_INTRINSIC() __builtin_unreachable()
#elif defined(__has_builtin) && __has_builtin(__builtin_unreachable)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_UNREACHABLE_INTRINSIC() __builtin_unreachable()
#else
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_UNREACHABLE_INTRINSIC() abort()
#endif
/// Causes the application to exit abnormally
#if defined(_MSC_VER)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_TRAP() __debugbreak()
#elif defined(__GNUC__)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_TRAP() __builtin_trap()
#elif defined(__has_builtin) && __has_builtin(__builtin_trap)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_TRAP() __builtin_trap()
#else
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_TRAP() *(volatile int*)0x11 = 0
#endif
namespace cti { namespace cti {
namespace detail { namespace detail {
/// Utility namespace which provides useful meta-programming support /// Utility namespace which provides useful meta-programming support
@ -251,39 +280,22 @@ private:
bool frozen_ : 1; bool frozen_ : 1;
}; };
/// Hint for the compiler that this point should be unreachable #ifndef NDEBUG
[[noreturn]] inline void unreachable() { [[noreturn]] inline void unreachable_debug() {
#if defined(_MSC_VER) CTI_DETAIL_TRAP();
__assume(false);
#elif defined(__GNUC__)
__builtin_unreachable();
#elif defined(__has_builtin) && __has_builtin(__builtin_unreachable)
__builtin_unreachable();
#else
std::abort(); std::abort();
#endif
} }
/// Causes the application to exit abnormally.
[[noreturn]] inline void trap() {
#if defined(_MSC_VER)
__debugbreak();
#elif defined(__GNUC__)
__builtin_trap();
#elif defined(__has_builtin) && __has_builtin(__builtin_trap)
__builtin_trap();
#else
*(volatile int*)0 = 0;
#endif #endif
}
} // namespace util } // namespace util
} // namespace detail } // namespace detail
} // namespace cti } // namespace cti
#ifdef CONTINUABLE_CONSTEXPR_IF #ifndef NDEBUG
#define CONTINUABLE_CONSTEXPR_IF(EXPR, TRUE_BRANCH, FALSE_BRANCH) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CTI_DETAIL_UNREACHABLE() ::cti::detail::util::unreachable_debug()
#else #else
#define CONTINUABLE_CONSTEXPR_IF(EXPR, TRUE_BRANCH, FALSE_BRANCH) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#endif // CONTINUABLE_CONSTEXPR_IF #define CTI_DETAIL_UNREACHABLE() CTI_DETAIL_UNREACHABLE_INTRINSIC()
#endif
#endif // CONTINUABLE_DETAIL_UTIL_HPP_INCLUDED #endif // CONTINUABLE_DETAIL_UTIL_HPP_INCLUDED