Skip to content

Commit

Permalink
[libc] fix -Wshift-count-overflow in UInt.h
Browse files Browse the repository at this point in the history
Not that I'm very good at SFINAE, but it seems that conversion operators are
perhaps difficult to compose with SFINAE.  I saw an example that used one layer
of indirection to have an explicit return type that could then be used with
enable_if_t.

Link: https://stackoverflow.com/a/7604580
Fixes: llvm#74623
  • Loading branch information
nickdesaulniers committed Dec 6, 2023
1 parent 1f283a6 commit 6097759
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions libc/src/__support/UInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,20 @@ template <size_t Bits, bool Signed> struct BigInt {
val[i] = words[i];
}

template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T> &&
sizeof(T) <= 16 &&
!cpp::is_same_v<T, bool>>>
LIBC_INLINE constexpr explicit operator T() const {
if constexpr (sizeof(T) <= 8)
return static_cast<T>(val[0]);
template <typename T> LIBC_INLINE constexpr explicit operator T() const {
return to<T>();
}

template <typename T>
LIBC_INLINE constexpr cpp::enable_if_t<
cpp::is_integral_v<T> && sizeof(T) <= 8 && !cpp::is_same_v<T, bool>, T>
to() const {
return static_cast<T>(val[0]);
}
template <typename T>
LIBC_INLINE constexpr cpp::enable_if_t<
cpp::is_integral_v<T> && sizeof(T) == 16, T>
to() const {
// T is 128-bit.
T lo = static_cast<T>(val[0]);

Expand All @@ -121,7 +128,6 @@ template <size_t Bits, bool Signed> struct BigInt {
return lo;
}
} else {
// TODO: silence shift warning
return static_cast<T>((static_cast<T>(val[1]) << 64) + lo);
}
}
Expand Down

0 comments on commit 6097759

Please sign in to comment.