[libc-commits] [libc] [libc] fix -Wshift-count-overflow in UInt.h (PR #74649)

Nick Desaulniers via libc-commits libc-commits at lists.llvm.org
Wed Dec 6 12:01:53 PST 2023


https://github.com/nickdesaulniers created https://github.com/llvm/llvm-project/pull/74649

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: #74623


>From 60977590b601fc730376ba35c088c247f660de7e Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Wed, 6 Dec 2023 11:45:41 -0800
Subject: [PATCH] [libc] fix -Wshift-count-overflow in UInt.h

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: #74623
---
 libc/src/__support/UInt.h | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h
index 3bec2e3a47130..f72b995f8788d 100644
--- a/libc/src/__support/UInt.h
+++ b/libc/src/__support/UInt.h
@@ -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]);
 
@@ -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);
     }
   }



More information about the libc-commits mailing list