From 422b6138cd307c9413aab4bf16dab042e1a9c53f Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Tue, 27 Aug 2019 03:22:34 +0200 Subject: [PATCH] Lift control flow compiler intrinsics into the used scope * Also make UNREACHABLE trap in debug mode --- include/continuable/detail/core/base.hpp | 12 ++-- .../continuable/detail/other/coroutines.hpp | 4 +- .../continuable/detail/other/transforms.hpp | 2 +- include/continuable/detail/utility/util.hpp | 64 +++++++++++-------- 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/include/continuable/detail/core/base.hpp b/include/continuable/detail/core/base.hpp index 96313c9..d6d7f14 100644 --- a/include/continuable/detail/core/base.hpp +++ b/include/continuable/detail/core/base.hpp @@ -140,7 +140,7 @@ struct proxy_continuable, Continuation> : Continuation { } std::tuple operator()(query_arg_t) { - util::unreachable(); + CTI_DETAIL_UNREACHABLE(); } }; @@ -671,12 +671,12 @@ struct final_callback : util::non_copyable { std::rethrow_exception(error); } catch (std::exception const& exception) { (void)exception; - util::trap(); + CTI_DETAIL_TRAP(); } catch (...) { - util::trap(); + CTI_DETAIL_TRAP(); } #else - util::trap(); + CTI_DETAIL_TRAP(); #endif #endif // CONTINUABLE_WITH_UNHANDLED_EXCEPTIONS } @@ -800,7 +800,7 @@ struct chained_continuation, identity, } std::tuple operator()(query_arg_t) { - util::unreachable(); + CTI_DETAIL_UNREACHABLE(); } }; // Specialization to unpack ready continuables directly @@ -843,7 +843,7 @@ struct chained_continuation, identity, } std::tuple operator()(query_arg_t) { - util::unreachable(); + CTI_DETAIL_UNREACHABLE(); } }; diff --git a/include/continuable/detail/other/coroutines.hpp b/include/continuable/detail/other/coroutines.hpp index c7d0a51..db47c70 100644 --- a/include/continuable/detail/other/coroutines.hpp +++ b/include/continuable/detail/other/coroutines.hpp @@ -119,7 +119,7 @@ public: std::rethrow_exception(result_.get_exception()); #else // CONTINUABLE_HAS_EXCEPTIONS // Returning error types in await isn't supported as of now - util::trap(); + CTI_DETAIL_TRAP(); #endif // CONTINUABLE_HAS_EXCEPTIONS } @@ -222,7 +222,7 @@ struct promise_type promise_.set_exception(std::current_exception()); #else // CONTINUABLE_HAS_EXCEPTIONS // Returning error types from coroutines isn't supported - cti::detail::util::trap(); + CTI_DETAIL_TRAP(); #endif // CONTINUABLE_HAS_EXCEPTIONS } }; diff --git a/include/continuable/detail/other/transforms.hpp b/include/continuable/detail/other/transforms.hpp index 2188570..95bd748 100644 --- a/include/continuable/detail/other/transforms.hpp +++ b/include/continuable/detail/other/transforms.hpp @@ -103,7 +103,7 @@ public: // 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(); + CTI_DETAIL_TRAP(); #endif // CONTINUABLE_HAS_EXCEPTIONS } diff --git a/include/continuable/detail/utility/util.hpp b/include/continuable/detail/utility/util.hpp index 912b664..f15e9c7 100644 --- a/include/continuable/detail/utility/util.hpp +++ b/include/continuable/detail/utility/util.hpp @@ -39,6 +39,35 @@ #include #include +/// 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 detail { /// Utility namespace which provides useful meta-programming support @@ -251,39 +280,22 @@ private: bool frozen_ : 1; }; -/// Hint for the compiler that this point should be unreachable -[[noreturn]] inline void unreachable() { -#if defined(_MSC_VER) - __assume(false); -#elif defined(__GNUC__) - __builtin_unreachable(); -#elif defined(__has_builtin) && __has_builtin(__builtin_unreachable) - __builtin_unreachable(); -#else +#ifndef NDEBUG +[[noreturn]] inline void unreachable_debug() { + CTI_DETAIL_TRAP(); 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 -} } // namespace util } // namespace detail } // namespace cti -#ifdef CONTINUABLE_CONSTEXPR_IF -#define CONTINUABLE_CONSTEXPR_IF(EXPR, TRUE_BRANCH, FALSE_BRANCH) +#ifndef NDEBUG +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define CTI_DETAIL_UNREACHABLE() ::cti::detail::util::unreachable_debug() #else -#define CONTINUABLE_CONSTEXPR_IF(EXPR, TRUE_BRANCH, FALSE_BRANCH) -#endif // CONTINUABLE_CONSTEXPR_IF +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define CTI_DETAIL_UNREACHABLE() CTI_DETAIL_UNREACHABLE_INTRINSIC() +#endif #endif // CONTINUABLE_DETAIL_UTIL_HPP_INCLUDED