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 131143 cff7378485bcfc4693ee192c71d16fece9101e92
parent 131142 a6934b3ae7cae9281983427cb9f43df4b45ee124
child 131144 11a3ee38afff9c5108e053ec4e9a5db730f3fd20
push id27712
push userjwalden@mit.edu
push dateTue, 07 May 2013 20:20:58 +0000
treeherdermozilla-inbound@cff7378485bc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs869238
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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>