Bug 869238 - Silence various -Wtype-limit warnings in Casting.h when instantiated with types with various size relationships. r=froydnj
☠☠ backed out by 3baae116d26f ☠ ☠
authorJeff Walden <jwalden@mit.edu>
Mon, 06 May 2013 16:38:42 -0700
changeset 131178 cff7378485bcfc4693ee192c71d16fece9101e92
parent 131177 a6934b3ae7cae9281983427cb9f43df4b45ee124
child 131179 11a3ee38afff9c5108e053ec4e9a5db730f3fd20
push id1590
push userphilringnalda@gmail.com
push dateWed, 08 May 2013 02:55:52 +0000
treeherderfx-team@b3a6bee35493 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs869238
milestone23.0a1
Bug 869238 - Silence various -Wtype-limit warnings in Casting.h when instantiated with types with various size relationships. r=froydnj
mfbt/Casting.h
--- a/mfbt/Casting.h
+++ b/mfbt/Casting.h
@@ -26,63 +26,115 @@ template<typename From,
          ToSignedness = IsSigned<To>::value ? ToIsSigned : ToIsUnsigned>
 struct BoundsCheckImpl;
 
 // Implicit conversions on operands to binary operations make this all a bit
 // hard to verify.  Attempt to ease the pain below by *only* comparing values
 // that are obviously the same type (and will undergo no further conversions),
 // even when it's not strictly necessary, for explicitness.
 
+enum UUComparison { FromIsBigger, FromIsNotBigger };
+
+// Unsigned-to-unsigned range check
+
+template<typename From, typename To,
+         UUComparison = (sizeof(From) > sizeof(To)) ? FromIsBigger : FromIsNotBigger>
+struct UnsignedUnsignedCheck;
+
+template<typename From, typename To>
+struct UnsignedUnsignedCheck<From, To, FromIsBigger>
+{
+  public:
+    static bool check(const From from) {
+      return from <= From(To(-1));
+    }
+};
+
+template<typename From, typename To>
+struct UnsignedUnsignedCheck<From, To, FromIsNotBigger>
+{
+  public:
+    static bool check(const From from) {
+      return true;
+    }
+};
+
 template<typename From, typename To>
 struct BoundsCheckImpl<From, To, FromIsUnsigned, ToIsUnsigned>
 {
   public:
     static bool check(const From from) {
-      typedef typename Conditional<sizeof(From) >= sizeof(To), From, To>::Type
-              LargerType;
-      return LargerType(from) <= LargerType(To(-1));
+      return UnsignedUnsignedCheck<From, To>::check(from);
     }
 };
 
+// Signed-to-unsigned range check
+
 template<typename From, typename To>
 struct BoundsCheckImpl<From, To, FromIsSigned, ToIsUnsigned>
 {
   public:
     static bool check(const From from) {
       if (from < 0)
         return false;
       if (sizeof(To) >= sizeof(From))
-        return To(from) <= To(-1);
+        return true;
       return from <= From(To(-1));
     }
 };
 
+// Unsigned-to-signed range check
+
+enum USComparison { FromIsSmaller, FromIsNotSmaller };
+
+template<typename From, typename To,
+         USComparison = sizeof(From) < sizeof(To) ? FromIsSmaller : FromIsNotSmaller>
+struct UnsignedSignedCheck;
+
+template<typename From, typename To>
+struct UnsignedSignedCheck<From, To, FromIsSmaller>
+{
+  public:
+    static bool check(const From from) {
+      return true;
+    }
+};
+
+template<typename From, typename To>
+struct UnsignedSignedCheck<From, To, FromIsNotSmaller>
+{
+  public:
+    static bool check(const From from) {
+      const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1);
+      return from <= From(MaxValue);
+    }
+};
+
 template<typename From, typename To>
 struct BoundsCheckImpl<From, To, FromIsUnsigned, ToIsSigned>
 {
   public:
     static bool check(const From from) {
-      if (sizeof(From) < sizeof(To))
-        return true;
-      const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1);
-      return from <= From(MaxValue);
+      return UnsignedSignedCheck<From, To>::check(from);
     }
 };
 
+// Signed-to-signed range check
+
 template<typename From, typename To>
 struct BoundsCheckImpl<From, To, FromIsSigned, ToIsSigned>
 {
   public:
     static bool check(const From from) {
-      typedef typename Conditional<sizeof(To) >= sizeof(From), To, From>::Type
-              LargerType;
+      if (sizeof(From) <= sizeof(To))
+        return true;
       const To MaxValue = To((1ULL << (CHAR_BIT * sizeof(To) - 1)) - 1);
       const To MinValue = -MaxValue - To(1);
-      return LargerType(MinValue) <= LargerType(from) &&
-             LargerType(from) <= LargerType(MaxValue);
+      return From(MinValue) <= from &&
+             From(from) <= From(MaxValue);
     }
 };
 
 template<typename From, typename To,
          bool TypesAreIntegral = IsIntegral<From>::value && IsIntegral<To>::value>
 class BoundsChecker;
 
 template<typename From>