diff --git a/AK/BigIntBase.h b/AK/BigIntBase.h index 4a42f8e7330..ad74b112dc2 100644 --- a/AK/BigIntBase.h +++ b/AK/BigIntBase.h @@ -188,7 +188,18 @@ ALWAYS_INLINE constexpr Word extend_sign(bool sign) template ALWAYS_INLINE constexpr WordType add_words(WordType word1, WordType word2, bool& carry) { - if (!is_constant_evaluated()) { + if consteval { + // Note: This is usually too confusing for both GCC and Clang. + WordType output; + bool ncarry = __builtin_add_overflow(word1, word2, &output); + if (carry) { + ++output; + if (output == 0) + ncarry = true; + } + carry = ncarry; + return output; + } else { #if __has_builtin(__builtin_addc) WordType ncarry, output; if constexpr (SameAs) @@ -215,22 +226,23 @@ ALWAYS_INLINE constexpr WordType add_words(WordType word1, WordType word2, bool& } #endif } - // Note: This is usually too confusing for both GCC and Clang. - WordType output; - bool ncarry = __builtin_add_overflow(word1, word2, &output); - if (carry) { - ++output; - if (output == 0) - ncarry = true; - } - carry = ncarry; - return output; } template ALWAYS_INLINE constexpr WordType sub_words(WordType word1, WordType word2, bool& carry) { - if (!is_constant_evaluated()) { + if consteval { + // Note: This is usually too confusing for both GCC and Clang. + WordType output; + bool ncarry = __builtin_sub_overflow(word1, word2, &output); + if (carry) { + if (output == 0) + ncarry = true; + --output; + } + carry = ncarry; + return output; + } else { #if __has_builtin(__builtin_subc) WordType ncarry, output; if constexpr (SameAs) @@ -257,16 +269,6 @@ ALWAYS_INLINE constexpr WordType sub_words(WordType word1, WordType word2, bool& } #endif } - // Note: This is usually too confusing for both GCC and Clang. - WordType output; - bool ncarry = __builtin_sub_overflow(word1, word2, &output); - if (carry) { - if (output == 0) - ncarry = true; - --output; - } - carry = ncarry; - return output; } template diff --git a/AK/Math.h b/AK/Math.h index 600d0619da5..108b1785c68 100644 --- a/AK/Math.h +++ b/AK/Math.h @@ -65,12 +65,12 @@ constexpr T to_degrees(T radians) } #define CONSTEXPR_STATE(function, args...) \ - if (is_constant_evaluated()) { \ - if (IsSame) \ + if consteval { \ + if constexpr (IsSame) \ return __builtin_##function##l(args); \ - if (IsSame) \ + if constexpr (IsSame) \ return __builtin_##function(args); \ - if (IsSame) \ + if constexpr (IsSame) \ return __builtin_##function##f(args); \ } @@ -110,7 +110,7 @@ template constexpr T ceil(T num) { // FIXME: SSE4.1 rounds[sd] num, res, 0b110 - if (is_constant_evaluated()) { + if consteval { if (num < NumericLimits::min() || num > NumericLimits::max()) return num; return (static_cast(static_cast(num)) == num) @@ -133,7 +133,7 @@ template constexpr T floor(T num) { // FIXME: SSE4.1 rounds[sd] num, res, 0b101 - if (is_constant_evaluated()) { + if consteval { if (num < NumericLimits::min() || num > NumericLimits::max()) return num; return (static_cast(static_cast(num)) == num) @@ -156,7 +156,7 @@ template constexpr T trunc(T num) { #if ARCH(AARCH64) - if (is_constant_evaluated()) { + if consteval { if (num < NumericLimits::min() || num > NumericLimits::max()) return num; return static_cast(static_cast(num)); @@ -601,7 +601,7 @@ constexpr T cos(T angle) template constexpr void sincos(T angle, T& sin_val, T& cos_val) { - if (is_constant_evaluated()) { + if consteval { sin_val = sin(angle); cos_val = cos(angle); return; diff --git a/AK/Optional.h b/AK/Optional.h index 79ea4e50f2c..e944a310b9b 100644 --- a/AK/Optional.h +++ b/AK/Optional.h @@ -376,22 +376,23 @@ public: } private: - ALWAYS_INLINE constexpr void construct_null_if_necessary(bool should_construct = is_constant_evaluated()) + ALWAYS_INLINE constexpr void construct_null_if_necessary() { - // OPTIMIZATION: Only construct the `m_null` member when we are constant-evaluating. - // Otherwise, this generates an unnecessary zero-fill. + // OPTIMIZATION: Only construct the `m_null` member when we are constant-evaluating. Otherwise, this generates + // an unnecessary zero-fill. #if defined(AK_COMPILER_GCC) - // NOTE: GCCs -Wuninitialized warning ends up checking this as well. - should_construct = true; -#endif - if (should_construct) + // GCC's -Wuninitialized warning ends up checking this as well. + construct_at(&m_null); +#else + if consteval { construct_at(&m_null); + } +#endif } union { - // FIXME: GCC seems to have an issue with uninitialized unions and non trivial types, - // which forces us to have an equally sized trivial null member in the union - // to pseudo-initialize the union. + // FIXME: GCC seems to have an issue with uninitialized unions and non trivial types, which forces us to have an + // equally sized trivial null member in the union to pseudo-initialize the union. struct { u8 _[sizeof(T)]; } m_null; diff --git a/AK/StdLibExtras.h b/AK/StdLibExtras.h index a7b6863595a..cb83b457529 100644 --- a/AK/StdLibExtras.h +++ b/AK/StdLibExtras.h @@ -122,20 +122,11 @@ requires(IsEnum) return static_cast>(value); } -constexpr bool is_constant_evaluated() -{ -#if __has_builtin(__builtin_is_constant_evaluated) - return __builtin_is_constant_evaluated(); -#else - return false; -#endif -} - template ALWAYS_INLINE constexpr void taint_for_optimizer(T& value) requires(IsIntegral) { - if (!is_constant_evaluated()) { + if !consteval { asm volatile("" : "+r"(value)); } @@ -145,7 +136,7 @@ template ALWAYS_INLINE constexpr void taint_for_optimizer(T& value) requires(!IsIntegral) { - if (!is_constant_evaluated()) { + if !consteval { asm volatile("" : : "m"(value) @@ -158,9 +149,11 @@ requires(!IsIntegral) #define __DEFINE_GENERIC_ABS(type, zero, intrinsic) \ constexpr type abs(type num) \ { \ - if (is_constant_evaluated()) \ + if consteval { \ return num < (zero) ? -num : num; \ - return __builtin_##intrinsic(num); \ + } else { \ + return __builtin_##intrinsic(num); \ + } \ } __DEFINE_GENERIC_ABS(int, 0, abs); @@ -180,7 +173,6 @@ using AK::ceil_div; using AK::clamp; using AK::exchange; using AK::forward; -using AK::is_constant_evaluated; using AK::is_power_of_two; using AK::max; using AK::min; diff --git a/AK/StringBase.h b/AK/StringBase.h index 9494c6d2d8d..bf5d48b33ea 100644 --- a/AK/StringBase.h +++ b/AK/StringBase.h @@ -59,16 +59,19 @@ public: constexpr ~StringBase() { - if (!is_constant_evaluated()) + if !consteval { destroy_string(); + } } // NOTE: This is primarily interesting to unit tests. [[nodiscard]] constexpr bool is_short_string() const { - if (is_constant_evaluated()) + if consteval { return (m_impl.short_string.byte_count_and_short_string_flag & SHORT_STRING_FLAG) != 0; - return (short_string_without_union_member_assertion().byte_count_and_short_string_flag & SHORT_STRING_FLAG) != 0; + } else { + return (short_string_without_union_member_assertion().byte_count_and_short_string_flag & SHORT_STRING_FLAG) != 0; + } } // Returns the underlying UTF-8 encoded bytes. diff --git a/AK/StringView.h b/AK/StringView.h index ed65bbbfb83..4590905f5a4 100644 --- a/AK/StringView.h +++ b/AK/StringView.h @@ -27,8 +27,9 @@ public: : m_characters(characters) , m_length(length) { - if (!is_constant_evaluated()) + if !consteval { VERIFY(!Checked::addition_would_overflow(reinterpret_cast(characters), length)); + } } ALWAYS_INLINE StringView(unsigned char const* characters, size_t length) @@ -67,8 +68,9 @@ public: constexpr char const& operator[](size_t index) const { - if (!is_constant_evaluated()) + if !consteval { VERIFY(index < m_length); + } return m_characters[index]; } @@ -116,15 +118,17 @@ public: [[nodiscard]] constexpr StringView substring_view(size_t start, size_t length) const { - if (!is_constant_evaluated()) + if !consteval { VERIFY(start + length <= m_length); + } return { m_characters + start, length }; } [[nodiscard]] constexpr StringView substring_view(size_t start) const { - if (!is_constant_evaluated()) + if !consteval { VERIFY(start <= length()); + } return substring_view(start, length() - start); } diff --git a/AK/Time.h b/AK/Time.h index f7ab54f2718..4dc81e81d05 100644 --- a/AK/Time.h +++ b/AK/Time.h @@ -60,10 +60,12 @@ unsigned day_of_week(int year, unsigned month, int day); // can be negative. constexpr int day_of_year(int year, unsigned month, int day) { - if (is_constant_evaluated()) + if consteval { VERIFY(month >= 1 && month <= 12); // Note that this prevents bad constexpr months, but never actually prints anything. - else if (!(month >= 1 && month <= 12)) - return 0; + } else { + if (!(month >= 1 && month <= 12)) + return 0; + } constexpr Array seek_table = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; int day_of_year = seek_table[month - 1] + day - 1; diff --git a/AK/Utf16StringBase.h b/AK/Utf16StringBase.h index 8c1af29a513..d434a483aad 100644 --- a/AK/Utf16StringBase.h +++ b/AK/Utf16StringBase.h @@ -49,8 +49,9 @@ public: constexpr ~Utf16StringBase() { - if (!is_constant_evaluated()) + if !consteval { destroy_string(); + } } ALWAYS_INLINE operator Utf16View() const& LIFETIME_BOUND { return utf16_view(); } @@ -278,9 +279,11 @@ public: // This is primarily interesting to unit tests. [[nodiscard]] constexpr bool has_short_ascii_storage() const { - if (is_constant_evaluated()) + if consteval { return (m_value.short_ascii_string.byte_count_and_short_string_flag & StringBase::SHORT_STRING_FLAG) != 0; - return (short_ascii_string_without_union_member_assertion().byte_count_and_short_string_flag & StringBase::SHORT_STRING_FLAG) != 0; + } else { + return (short_ascii_string_without_union_member_assertion().byte_count_and_short_string_flag & StringBase::SHORT_STRING_FLAG) != 0; + } } // This is primarily interesting to unit tests. diff --git a/Libraries/LibGfx/Matrix.h b/Libraries/LibGfx/Matrix.h index 5fd6165e80c..dcb189fc397 100644 --- a/Libraries/LibGfx/Matrix.h +++ b/Libraries/LibGfx/Matrix.h @@ -46,7 +46,7 @@ public: constexpr Matrix& operator=(Matrix const& other) { #ifndef __clang__ - if (is_constant_evaluated()) { + if consteval { for (size_t i = 0; i < N; i++) { for (size_t j = 0; j < N; j++) { (*this)[i, j] = other[i, j];