Bug 1013662 - Fix bad implicit conversion constructors in MFBT; r=froydnj,Waldo
authorEhsan Akhgari <ehsan@mozilla.com>
Fri, 06 Jun 2014 23:17:06 -0400
changeset 187368 d7dc39d162348d21bd2b51b3a3b56fa2fe969dd5
parent 187367 a0b0886c3ed13c85b3d1daacbde121ba3aa252e9
child 187369 dbb05142c66657d6b6928ef24caa2755f5073725
push id7176
push userryanvm@gmail.com
push dateSat, 07 Jun 2014 18:15:31 +0000
treeherderfx-team@a2f0e0619332 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj, Waldo
bugs1013662
milestone32.0a1
Bug 1013662 - Fix bad implicit conversion constructors in MFBT; r=froydnj,Waldo
content/html/content/src/HTMLInputElement.cpp
layout/forms/nsRangeFrame.cpp
mfbt/Atomics.h
mfbt/DebugOnly.h
mfbt/EnumSet.h
mfbt/LinkedList.h
mfbt/MathAlgorithms.h
mfbt/RefPtr.h
mfbt/RollingMean.h
mfbt/Vector.h
mfbt/WeakPtr.h
mfbt/decimal/Decimal.h
mfbt/tests/TestBinarySearch.cpp
mfbt/tests/TestBloomFilter.cpp
mfbt/tests/TestRollingMean.cpp
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -185,23 +185,23 @@ static const nsAttrValue::EnumTable kInp
   { "titlecase", NS_INPUT_INPUTMODE_TITLECASE },
   { "autocapitalized", NS_INPUT_INPUTMODE_AUTOCAPITALIZED },
   { 0 }
 };
 
 // Default inputmode value is "auto".
 static const nsAttrValue::EnumTable* kInputDefaultInputmode = &kInputInputmodeTable[0];
 
-const Decimal HTMLInputElement::kStepScaleFactorDate = 86400000;
-const Decimal HTMLInputElement::kStepScaleFactorNumberRange = 1;
-const Decimal HTMLInputElement::kStepScaleFactorTime = 1000;
-const Decimal HTMLInputElement::kDefaultStepBase = 0;
-const Decimal HTMLInputElement::kDefaultStep = 1;
-const Decimal HTMLInputElement::kDefaultStepTime = 60;
-const Decimal HTMLInputElement::kStepAny = 0;
+const Decimal HTMLInputElement::kStepScaleFactorDate = Decimal(86400000);
+const Decimal HTMLInputElement::kStepScaleFactorNumberRange = Decimal(1);
+const Decimal HTMLInputElement::kStepScaleFactorTime = Decimal(1000);
+const Decimal HTMLInputElement::kDefaultStepBase = Decimal(0);
+const Decimal HTMLInputElement::kDefaultStep = Decimal(1);
+const Decimal HTMLInputElement::kDefaultStepTime = Decimal(60);
+const Decimal HTMLInputElement::kStepAny = Decimal(0);
 
 #define NS_INPUT_ELEMENT_STATE_IID                 \
 { /* dc3b3d14-23e2-4479-b513-7b369343e3a0 */       \
   0xdc3b3d14,                                      \
   0x23e2,                                          \
   0x4479,                                          \
   {0xb5, 0x13, 0x7b, 0x36, 0x93, 0x43, 0xe3, 0xa0} \
 }
@@ -1749,17 +1749,17 @@ HTMLInputElement::ConvertStringToNumber(
         return true;
       }
     case NS_FORM_INPUT_TIME:
       uint32_t milliseconds;
       if (!ParseTime(aValue, &milliseconds)) {
         return false;
       }
 
-      aResultValue = int32_t(milliseconds);
+      aResultValue = Decimal(int32_t(milliseconds));
       return true;
     default:
       MOZ_ASSERT(false, "Unrecognized input type");
       return false;
   }
 }
 
 Decimal
@@ -1924,17 +1924,17 @@ HTMLInputElement::ConvertNumberToString(
 
         return true;
       }
     case NS_FORM_INPUT_TIME:
       {
         // Per spec, we need to truncate |aValue| and we should only represent
         // times inside a day [00:00, 24:00[, which means that we should do a
         // modulo on |aValue| using the number of milliseconds in a day (86400000).
-        uint32_t value = NS_floorModulo(aValue.floor(), 86400000).toDouble();
+        uint32_t value = NS_floorModulo(aValue.floor(), Decimal(86400000)).toDouble();
 
         uint16_t milliseconds = value % 1000;
         value /= 1000;
 
         uint8_t seconds = value % 60;
         value /= 60;
 
         uint8_t minutes = value % 60;
@@ -2050,17 +2050,17 @@ HTMLInputElement::SetValueAsNumber(doubl
 Decimal
 HTMLInputElement::GetMinimum() const
 {
   MOZ_ASSERT(DoesValueAsNumberApply(),
              "GetMinimum() should only be used for types that allow .valueAsNumber");
 
   // Only type=range has a default minimum
   Decimal defaultMinimum =
-    mType == NS_FORM_INPUT_RANGE ? 0 : Decimal::nan();
+    mType == NS_FORM_INPUT_RANGE ? Decimal(0) : Decimal::nan();
 
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::min)) {
     return defaultMinimum;
   }
 
   nsAutoString minStr;
   GetAttr(kNameSpaceID_None, nsGkAtoms::min, minStr);
 
@@ -2071,17 +2071,17 @@ HTMLInputElement::GetMinimum() const
 Decimal
 HTMLInputElement::GetMaximum() const
 {
   MOZ_ASSERT(DoesValueAsNumberApply(),
              "GetMaximum() should only be used for types that allow .valueAsNumber");
 
   // Only type=range has a default maximum
   Decimal defaultMaximum =
-    mType == NS_FORM_INPUT_RANGE ? 100 : Decimal::nan();
+    mType == NS_FORM_INPUT_RANGE ? Decimal(100) : Decimal::nan();
 
   if (!HasAttr(kNameSpaceID_None, nsGkAtoms::max)) {
     return defaultMaximum;
   }
 
   nsAutoString maxStr;
   GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxStr);
 
@@ -2133,17 +2133,17 @@ HTMLInputElement::GetValueIfStepped(int3
       return NS_ERROR_DOM_INVALID_STATE_ERR;
     }
     // Allow the spin buttons and up/down arrow keys to do something sensible:
     step = GetDefaultStep();
   }
 
   Decimal value = GetValueAsDecimal();
   if (value.isNaN()) {
-    value = 0;
+    value = Decimal(0);
   }
 
   Decimal minimum = GetMinimum();
 
   Decimal maximum = GetMaximum();
   if (!maximum.isNaN()) {
     // "max - (max - stepBase) % step" is the nearest valid value to max.
     maximum = maximum - NS_floorModulo(maximum - GetStepBase(), step);
@@ -2171,24 +2171,24 @@ HTMLInputElement::GetValueIfStepped(int3
     if (aStep > 0) {
       value -= NS_floorModulo(value - GetStepBase(), step);
     } else if (aStep < 0) {
       value -= NS_floorModulo(value - GetStepBase(), step);
       value += step;
     }
   }
 
-  value += step * aStep;
+  value += step * Decimal(aStep);
 
   // For date inputs, the value can hold a string that is not a day. We do not
   // want to round it, as it might result in a step mismatch. Instead we want to
   // clamp to the next valid value.
   if (mType == NS_FORM_INPUT_DATE &&
-      NS_floorModulo(value - GetStepBase(), GetStepScaleFactor()) != 0) {
-    MOZ_ASSERT(GetStep() > 0);
+      NS_floorModulo(Decimal(value - GetStepBase()), GetStepScaleFactor()) != Decimal(0)) {
+    MOZ_ASSERT(GetStep() > Decimal(0));
     Decimal validStep = EuclidLCM<Decimal>(GetStep().floor(),
                                            GetStepScaleFactor().floor());
     if (aStep > 0) {
       value -= NS_floorModulo(value - GetStepBase(), validStep);
       value += validStep;
     } else if (aStep < 0) {
       value -= NS_floorModulo(value - GetStepBase(), validStep);
     }
@@ -4111,20 +4111,20 @@ HTMLInputElement::PostHandleEvent(EventC
                   newValue = minimum;
                   break;
                 case  NS_VK_END:
                   newValue = maximum;
                   break;
                 case  NS_VK_PAGE_UP:
                   // For PgUp/PgDn we jump 10% of the total range, unless step
                   // requires us to jump more.
-                  newValue = value + std::max(step, (maximum - minimum) / 10);
+                  newValue = value + std::max(step, (maximum - minimum) / Decimal(10));
                   break;
                 case  NS_VK_PAGE_DOWN:
-                  newValue = value - std::max(step, (maximum - minimum) / 10);
+                  newValue = value - std::max(step, (maximum - minimum) / Decimal(10));
                   break;
               }
               SetValueOfRangeForUserEvent(newValue);
               aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
             }
           }
 
         } break; // NS_KEY_PRESS || NS_KEY_UP
@@ -4562,43 +4562,43 @@ HTMLInputElement::SanitizeValue(nsAStrin
         // parse out from aValue needs to be sanitized.
         bool needSanitization = false;
 
         Decimal value;
         bool ok = ConvertStringToNumber(aValue, value);
         if (!ok) {
           needSanitization = true;
           // Set value to midway between minimum and maximum.
-          value = maximum <= minimum ? minimum : minimum + (maximum - minimum)/2;
+          value = maximum <= minimum ? minimum : minimum + (maximum - minimum)/Decimal(2);
         } else if (value < minimum || maximum < minimum) {
           needSanitization = true;
           value = minimum;
         } else if (value > maximum) {
           needSanitization = true;
           value = maximum;
         }
 
         Decimal step = GetStep();
         if (step != kStepAny) {
           Decimal stepBase = GetStepBase();
           // There could be rounding issues below when dealing with fractional
           // numbers, but let's ignore that until ECMAScript supplies us with a
           // decimal number type.
           Decimal deltaToStep = NS_floorModulo(value - stepBase, step);
-          if (deltaToStep != 0) {
+          if (deltaToStep != Decimal(0)) {
             // "suffering from a step mismatch"
             // Round the element's value to the nearest number for which the
             // element would not suffer from a step mismatch, and which is
             // greater than or equal to the minimum, and, if the maximum is not
             // less than the minimum, which is less than or equal to the
             // maximum, if there is a number that matches these constraints:
-            MOZ_ASSERT(deltaToStep > 0, "stepBelow/stepAbove will be wrong");
+            MOZ_ASSERT(deltaToStep > Decimal(0), "stepBelow/stepAbove will be wrong");
             Decimal stepBelow = value - deltaToStep;
             Decimal stepAbove = value - deltaToStep + step;
-            Decimal halfStep = step / 2;
+            Decimal halfStep = step / Decimal(2);
             bool stepAboveIsClosest = (stepAbove - value) <= halfStep;
             bool stepAboveInRange = stepAbove >= minimum &&
                                     stepAbove <= maximum;
             bool stepBelowInRange = stepBelow >= minimum &&
                                     stepBelow <= maximum;
 
             if ((stepAboveIsClosest || !stepBelowInRange) && stepAboveInRange) {
               needSanitization = true;
@@ -6271,17 +6271,17 @@ HTMLInputElement::GetStep() const
   GetAttr(kNameSpaceID_None, nsGkAtoms::step, stepStr);
 
   if (stepStr.LowerCaseEqualsLiteral("any")) {
     // The element can't suffer from step mismatch if there is no step.
     return kStepAny;
   }
 
   Decimal step = StringToDecimal(stepStr);
-  if (!step.isFinite() || step <= 0) {
+  if (!step.isFinite() || step <= Decimal(0)) {
     step = GetDefaultStep();
   }
 
   return step * GetStepScaleFactor();
 }
 
 // nsIConstraintValidation
 
@@ -6457,30 +6457,30 @@ HTMLInputElement::HasStepMismatch(bool a
 {
   if (!DoesStepApply()) {
     return false;
   }
 
   Decimal value = GetValueAsDecimal();
   if (value.isNaN()) {
     if (aUseZeroIfValueNaN) {
-      value = 0;
+      value = Decimal(0);
     } else {
       // The element can't suffer from step mismatch if it's value isn't a number.
       return false;
     }
   }
 
   Decimal step = GetStep();
   if (step == kStepAny) {
     return false;
   }
 
   // Value has to be an integral multiple of step.
-  return NS_floorModulo(value - GetStepBase(), step) != 0;
+  return NS_floorModulo(value - GetStepBase(), step) != Decimal(0);
 }
 
 /**
  * Splits the string on the first "@" character and punycode encodes the first
  * and second parts separately before rejoining them with an "@" and returning
  * the result via the aEncodedEmail out-param. Returns false if there is no
  * "@" caracter, if the "@" character is at the start or end, or if the
  * conversion to punycode fails.
@@ -6876,17 +6876,17 @@ HTMLInputElement::GetValidationMessage(n
     case VALIDITY_STATE_STEP_MISMATCH:
     {
       nsXPIDLString message;
 
       Decimal value = GetValueAsDecimal();
       MOZ_ASSERT(!value.isNaN());
 
       Decimal step = GetStep();
-      MOZ_ASSERT(step != kStepAny && step > 0);
+      MOZ_ASSERT(step != kStepAny && step > Decimal(0));
 
       // In case this is a date and the step is not an integer, we don't want to
       // display the dates corresponding to the truncated timestamps of valueLow
       // and valueHigh because they might suffer from a step mismatch as well.
       // Instead we want the timestamps to correspond to a rounded day. That is,
       // we want a multiple of the step scale factor (1 day) as well as of step.
       if (mType == NS_FORM_INPUT_DATE) {
         step = EuclidLCM<Decimal>(step.floor(),
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -521,34 +521,34 @@ nsRangeFrame::GetValueAtEventPoint(Widge
   if (IsHorizontal()) {
     nscoord traversableDistance = rangeContentRect.width - thumbSize.width;
     if (traversableDistance <= 0) {
       return minimum;
     }
     nscoord posAtStart = rangeContentRect.x + thumbSize.width/2;
     nscoord posAtEnd = posAtStart + traversableDistance;
     nscoord posOfPoint = mozilla::clamped(point.x, posAtStart, posAtEnd);
-    fraction = Decimal(posOfPoint - posAtStart) / traversableDistance;
+    fraction = Decimal(posOfPoint - posAtStart) / Decimal(traversableDistance);
     if (StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
       fraction = Decimal(1) - fraction;
     }
   } else {
     nscoord traversableDistance = rangeContentRect.height - thumbSize.height;
     if (traversableDistance <= 0) {
       return minimum;
     }
     nscoord posAtStart = rangeContentRect.y + thumbSize.height/2;
     nscoord posAtEnd = posAtStart + traversableDistance;
     nscoord posOfPoint = mozilla::clamped(point.y, posAtStart, posAtEnd);
     // For a vertical range, the top (posAtStart) is the highest value, so we
     // subtract the fraction from 1.0 to get that polarity correct.
-    fraction = Decimal(1) - Decimal(posOfPoint - posAtStart) / traversableDistance;
+    fraction = Decimal(1) - Decimal(posOfPoint - posAtStart) / Decimal(traversableDistance);
   }
 
-  MOZ_ASSERT(fraction >= 0 && fraction <= 1);
+  MOZ_ASSERT(fraction >= Decimal(0) && fraction <= Decimal(1));
   return minimum + fraction * range;
 }
 
 void
 nsRangeFrame::UpdateForValueChange()
 {
   if (NS_SUBTREE_DIRTY(this)) {
     return; // we're going to be updated when we reflow
--- a/mfbt/Atomics.h
+++ b/mfbt/Atomics.h
@@ -937,17 +937,17 @@ class AtomicBase
                 "mozilla/Atomics.h only supports 32-bit and pointer-sized types");
 
 protected:
   typedef typename detail::AtomicIntrinsics<T, Order> Intrinsics;
   typename Intrinsics::ValueType mValue;
 
 public:
   MOZ_CONSTEXPR AtomicBase() : mValue() {}
-  MOZ_CONSTEXPR AtomicBase(T aInit) : mValue(aInit) {}
+  explicit MOZ_CONSTEXPR AtomicBase(T aInit) : mValue(aInit) {}
 
   // Note: we can't provide operator T() here because Atomic<bool> inherits
   // from AtomcBase with T=uint32_t and not T=bool. If we implemented
   // operator T() here, it would cause errors when comparing Atomic<bool> with
   // a regular bool.
 
   T operator=(T aVal)
   {
@@ -987,17 +987,17 @@ private:
 
 template<typename T, MemoryOrdering Order>
 class AtomicBaseIncDec : public AtomicBase<T, Order>
 {
   typedef typename detail::AtomicBase<T, Order> Base;
 
 public:
   MOZ_CONSTEXPR AtomicBaseIncDec() : Base() {}
-  MOZ_CONSTEXPR AtomicBaseIncDec(T aInit) : Base(aInit) {}
+  explicit MOZ_CONSTEXPR AtomicBaseIncDec(T aInit) : Base(aInit) {}
 
   using Base::operator=;
 
   operator T() const { return Base::Intrinsics::load(Base::mValue); }
   T operator++(int) { return Base::Intrinsics::inc(Base::mValue); }
   T operator--(int) { return Base::Intrinsics::dec(Base::mValue); }
   T operator++() { return Base::Intrinsics::inc(Base::mValue) + 1; }
   T operator--() { return Base::Intrinsics::dec(Base::mValue) - 1; }
@@ -1043,17 +1043,17 @@ template<typename T, MemoryOrdering Orde
 class Atomic<T, Order, typename EnableIf<IsIntegral<T>::value &&
                        !IsSame<T, bool>::value>::Type>
   : public detail::AtomicBaseIncDec<T, Order>
 {
   typedef typename detail::AtomicBaseIncDec<T, Order> Base;
 
 public:
   MOZ_CONSTEXPR Atomic() : Base() {}
-  MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {}
+  explicit MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {}
 
   using Base::operator=;
 
   T operator+=(T aDelta)
   {
     return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta;
   }
 
@@ -1091,17 +1091,17 @@ private:
  */
 template<typename T, MemoryOrdering Order>
 class Atomic<T*, Order> : public detail::AtomicBaseIncDec<T*, Order>
 {
   typedef typename detail::AtomicBaseIncDec<T*, Order> Base;
 
 public:
   MOZ_CONSTEXPR Atomic() : Base() {}
-  MOZ_CONSTEXPR Atomic(T* aInit) : Base(aInit) {}
+  explicit MOZ_CONSTEXPR Atomic(T* aInit) : Base(aInit) {}
 
   using Base::operator=;
 
   T* operator+=(ptrdiff_t aDelta)
   {
     return Base::Intrinsics::add(Base::mValue, aDelta) + aDelta;
   }
 
@@ -1122,17 +1122,17 @@ private:
 template<typename T, MemoryOrdering Order>
 class Atomic<T, Order, typename EnableIf<IsEnum<T>::value>::Type>
   : public detail::AtomicBase<T, Order>
 {
   typedef typename detail::AtomicBase<T, Order> Base;
 
 public:
   MOZ_CONSTEXPR Atomic() : Base() {}
-  MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {}
+  explicit MOZ_CONSTEXPR Atomic(T aInit) : Base(aInit) {}
 
   operator T() const { return Base::Intrinsics::load(Base::mValue); }
 
   using Base::operator=;
 
 private:
   Atomic(Atomic<T, Order>& aOther) MOZ_DELETE;
 };
@@ -1156,17 +1156,17 @@ private:
 template<MemoryOrdering Order>
 class Atomic<bool, Order>
   : protected detail::AtomicBase<uint32_t, Order>
 {
   typedef typename detail::AtomicBase<uint32_t, Order> Base;
 
 public:
   MOZ_CONSTEXPR Atomic() : Base() {}
-  MOZ_CONSTEXPR Atomic(bool aInit) : Base(aInit) {}
+  explicit MOZ_CONSTEXPR Atomic(bool aInit) : Base(aInit) {}
 
   // We provide boolean wrappers for the underlying AtomicBase methods.
   operator bool() const
   {
     return Base::Intrinsics::load(Base::mValue);
   }
 
   bool operator=(bool aVal)
--- a/mfbt/DebugOnly.h
+++ b/mfbt/DebugOnly.h
@@ -7,16 +7,18 @@
 /*
  * Provides DebugOnly, a type for variables used only in debug builds (i.e. by
  * assertions).
  */
 
 #ifndef mozilla_DebugOnly_h
 #define mozilla_DebugOnly_h
 
+#include "mozilla/Attributes.h"
+
 namespace mozilla {
 
 /**
  * DebugOnly contains a value of type T, but only in debug builds.  In release
  * builds, it does not contain a value.  This helper is intended to be used with
  * MOZ_ASSERT()-style macros, allowing one to write:
  *
  *   DebugOnly<bool> check = func();
@@ -34,17 +36,17 @@ namespace mozilla {
 template<typename T>
 class DebugOnly
 {
 public:
 #ifdef DEBUG
   T value;
 
   DebugOnly() { }
-  DebugOnly(const T& aOther) : value(aOther) { }
+  MOZ_IMPLICIT DebugOnly(const T& aOther) : value(aOther) { }
   DebugOnly(const DebugOnly& aOther) : value(aOther.value) { }
   DebugOnly& operator=(const T& aRhs) {
     value = aRhs;
     return *this;
   }
 
   void operator++(int) { value++; }
   void operator--(int) { value--; }
@@ -54,17 +56,17 @@ public:
   operator T&() { return value; }
   operator const T&() const { return value; }
 
   T& operator->() { return value; }
   const T& operator->() const { return value; }
 
 #else
   DebugOnly() { }
-  DebugOnly(const T&) { }
+  MOZ_IMPLICIT DebugOnly(const T&) { }
   DebugOnly(const DebugOnly&) { }
   DebugOnly& operator=(const T&) { return *this; }
   void operator++(int) { }
   void operator--(int) { }
 #endif
 
   /*
    * DebugOnly must always have a destructor or else it will
--- a/mfbt/EnumSet.h
+++ b/mfbt/EnumSet.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* A set abstraction for enumeration values. */
 
 #ifndef mozilla_EnumSet_h
 #define mozilla_EnumSet_h
 
 #include "mozilla/Assertions.h"
+#include "mozilla/Attributes.h"
 
 #include <stdint.h>
 
 namespace mozilla {
 
 /**
  * EnumSet<T> is a set of values defined by an enumeration. It is implemented
  * using a 32 bit mask for each value so it will only work for enums with an int
@@ -23,17 +24,17 @@ namespace mozilla {
 template<typename T>
 class EnumSet
 {
   public:
     EnumSet()
       : mBitField(0)
     { }
 
-    EnumSet(T aEnum)
+    MOZ_IMPLICIT EnumSet(T aEnum)
       : mBitField(bitFor(aEnum))
     { }
 
     EnumSet(T aEnum1, T aEnum2)
       : mBitField(bitFor(aEnum1) |
                   bitFor(aEnum2))
     { }
 
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -227,17 +227,17 @@ class LinkedListElement
   private:
     friend class LinkedList<T>;
 
     enum NodeKind {
       NODE_KIND_NORMAL,
       NODE_KIND_SENTINEL
     };
 
-    LinkedListElement(NodeKind nodeKind)
+    explicit LinkedListElement(NodeKind nodeKind)
       : next(MOZ_THIS_IN_INITIALIZER_LIST()),
         prev(MOZ_THIS_IN_INITIALIZER_LIST()),
         isSentinel(nodeKind == NODE_KIND_SENTINEL)
     { }
 
     /*
      * Return |this| cast to T* if we're a normal node, or return nullptr if
      * we're a sentinel node.
--- a/mfbt/MathAlgorithms.h
+++ b/mfbt/MathAlgorithms.h
@@ -20,18 +20,18 @@ namespace mozilla {
 
 // Greatest Common Divisor
 template<typename IntegerType>
 MOZ_ALWAYS_INLINE IntegerType
 EuclidGCD(IntegerType a, IntegerType b)
 {
   // Euclid's algorithm; O(N) in the worst case.  (There are better
   // ways, but we don't need them for the current use of this algo.)
-  MOZ_ASSERT(a > 0);
-  MOZ_ASSERT(b > 0);
+  MOZ_ASSERT(a > IntegerType(0));
+  MOZ_ASSERT(b > IntegerType(0));
 
   while (a != b) {
     if (a > b) {
       a = a - b;
     } else {
       b = b - a;
     }
   }
--- a/mfbt/RefPtr.h
+++ b/mfbt/RefPtr.h
@@ -217,18 +217,18 @@ class RefPtr
     friend class TemporaryRef<T>;
     friend class OutParamRef<T>;
 
     struct DontRef {};
 
   public:
     RefPtr() : ptr(0) { }
     RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {}
-    RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {}
-    RefPtr(T* t) : ptr(ref(t)) {}
+    MOZ_IMPLICIT RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {}
+    MOZ_IMPLICIT RefPtr(T* t) : ptr(ref(t)) {}
 
     template<typename U>
     RefPtr(const RefPtr<U>& o) : ptr(ref(o.get())) {}
 
     ~RefPtr() { unref(ptr); }
 
     RefPtr& operator=(const RefPtr& o) {
       assign(ref(o.ptr));
@@ -292,17 +292,17 @@ template<typename T>
 class TemporaryRef
 {
     // To allow it to construct TemporaryRef from a bare T*
     friend class RefPtr<T>;
 
     typedef typename RefPtr<T>::DontRef DontRef;
 
   public:
-    TemporaryRef(T* t) : ptr(RefPtr<T>::ref(t)) {}
+    MOZ_IMPLICIT TemporaryRef(T* t) : ptr(RefPtr<T>::ref(t)) {}
     TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {}
 
     template<typename U>
     TemporaryRef(const TemporaryRef<U>& o) : ptr(o.drop()) {}
 
     ~TemporaryRef() { RefPtr<T>::unref(ptr); }
 
     T* drop() const {
@@ -343,17 +343,17 @@ class OutParamRef
     ~OutParamRef() {
       RefPtr<T>::unref(refPtr.ptr);
       refPtr.ptr = tmp;
     }
 
     operator T**() { return &tmp; }
 
   private:
-    OutParamRef(RefPtr<T>& p) : refPtr(p), tmp(p.get()) {}
+    explicit OutParamRef(RefPtr<T>& p) : refPtr(p), tmp(p.get()) {}
 
     RefPtr<T>& refPtr;
     T* tmp;
 
     OutParamRef() MOZ_DELETE;
     OutParamRef& operator=(const OutParamRef&) MOZ_DELETE;
 };
 
--- a/mfbt/RollingMean.h
+++ b/mfbt/RollingMean.h
@@ -34,17 +34,17 @@ class RollingMean
     Vector<T> mValues;
     S mTotal;
 
   public:
     static_assert(!IsFloatingPoint<T>::value,
                   "floating-point types are unsupported due to rounding "
                   "errors");
 
-    RollingMean(size_t aMaxValues)
+    explicit RollingMean(size_t aMaxValues)
       : mInsertIndex(0),
         mMaxValues(aMaxValues),
         mTotal(0)
     {
       MOZ_ASSERT(aMaxValues > 0);
     }
 
     RollingMean& operator=(RollingMean&& aOther) {
--- a/mfbt/Vector.h
+++ b/mfbt/Vector.h
@@ -314,18 +314,18 @@ class VectorBase : private AllocPolicy
     void internalAppendN(const T& t, size_t n);
     template<typename U> void internalAppend(const U* begin, size_t length);
 
   public:
     static const size_t sMaxInlineStorage = N;
 
     typedef T ElementType;
 
-    VectorBase(AllocPolicy = AllocPolicy());
-    VectorBase(ThisVector&&); /* Move constructor. */
+    explicit VectorBase(AllocPolicy = AllocPolicy());
+    explicit VectorBase(ThisVector&&); /* Move constructor. */
     ThisVector& operator=(ThisVector&&); /* Move assignment. */
     ~VectorBase();
 
     /* accessors */
 
     const AllocPolicy& allocPolicy() const {
       return *this;
     }
@@ -1204,17 +1204,17 @@ class Vector
   : public VectorBase<T,
                       MinInlineCapacity,
                       AllocPolicy,
                       Vector<T, MinInlineCapacity, AllocPolicy> >
 {
     typedef VectorBase<T, MinInlineCapacity, AllocPolicy, Vector> Base;
 
   public:
-    Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {}
+    explicit Vector(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {}
     Vector(Vector&& vec) : Base(Move(vec)) {}
     Vector& operator=(Vector&& vec) {
       return Base::operator=(Move(vec));
     }
 };
 
 } // namespace mozilla
 
--- a/mfbt/WeakPtr.h
+++ b/mfbt/WeakPtr.h
@@ -186,15 +186,15 @@ class WeakPtrBase
 };
 
 template <typename T>
 class WeakPtr : public WeakPtrBase<T, detail::WeakReference<T> >
 {
     typedef WeakPtrBase<T, detail::WeakReference<T> > Base;
   public:
     WeakPtr(const WeakPtr<T>& o) : Base(o) {}
-    WeakPtr(const Base& o) : Base(o) {}
+    MOZ_IMPLICIT WeakPtr(const Base& o) : Base(o) {}
     WeakPtr() {}
 };
 
 } // namespace mozilla
 
 #endif /* mozilla_WeakPtr_h */
--- a/mfbt/decimal/Decimal.h
+++ b/mfbt/decimal/Decimal.h
@@ -107,17 +107,17 @@ public:
         FormatClass formatClass() const { return m_formatClass; }
 
         uint64_t m_coefficient;
         int16_t m_exponent;
         FormatClass m_formatClass;
         Sign m_sign;
     };
 
-    MFBT_API Decimal(int32_t = 0);
+    MFBT_API explicit Decimal(int32_t = 0);
     MFBT_API Decimal(Sign, int exponent, uint64_t coefficient);
     MFBT_API Decimal(const Decimal&);
 
     MFBT_API Decimal& operator=(const Decimal&);
     MFBT_API Decimal& operator+=(const Decimal&);
     MFBT_API Decimal& operator-=(const Decimal&);
     MFBT_API Decimal& operator*=(const Decimal&);
     MFBT_API Decimal& operator/=(const Decimal&);
@@ -180,17 +180,17 @@ public:
 
 private:
     struct AlignedOperands {
         uint64_t lhsCoefficient;
         uint64_t rhsCoefficient;
         int exponent;
     };
 
-    MFBT_API Decimal(double);
+    MFBT_API explicit Decimal(double);
     MFBT_API Decimal compareTo(const Decimal&) const;
 
     static MFBT_API AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs);
     static inline Sign invertSign(Sign sign) { return sign == Negative ? Positive : Negative; }
 
     Sign sign() const { return m_data.sign(); }
 
     EncodedData m_data;
--- a/mfbt/tests/TestBinarySearch.cpp
+++ b/mfbt/tests/TestBinarySearch.cpp
@@ -15,17 +15,17 @@ struct Person
   int age;
   int id;
   Person(int age, int id) : age(age), id(id) {}
 };
 
 struct GetAge
 {
   Vector<Person> &v;
-  GetAge(Vector<Person> &v) : v(v) {}
+  explicit GetAge(Vector<Person> &v) : v(v) {}
   int operator[](size_t index) const { return v[index].age; }
 };
 
 int main()
 {
   size_t m;
 
   Vector<int> v1;
--- a/mfbt/tests/TestBloomFilter.cpp
+++ b/mfbt/tests/TestBloomFilter.cpp
@@ -9,17 +9,17 @@
 #include <stddef.h>
 #include <stdio.h>
 
 using mozilla::BloomFilter;
 
 class FilterChecker
 {
   public:
-    FilterChecker(uint32_t hash) : mHash(hash) { }
+    explicit FilterChecker(uint32_t hash) : mHash(hash) { }
 
     uint32_t hash() const { return mHash; }
 
   private:
     uint32_t mHash;
 };
 
 int
--- a/mfbt/tests/TestRollingMean.cpp
+++ b/mfbt/tests/TestRollingMean.cpp
@@ -8,17 +8,17 @@
 
 using mozilla::RollingMean;
 
 class MyClass
 {
   public:
     uint32_t value;
 
-    MyClass(uint32_t val = 0) : value(val) {
+    explicit MyClass(uint32_t val = 0) : value(val) {
     }
 
     bool operator==(const MyClass& other) const {
       return value == other.value;
     }
 
     MyClass operator+(const MyClass& other) const {
       return MyClass(value + other.value);