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 187315 d7dc39d162348d21bd2b51b3a3b56fa2fe969dd5
parent 187314 a0b0886c3ed13c85b3d1daacbde121ba3aa252e9
child 187316 dbb05142c66657d6b6928ef24caa2755f5073725
push id44565
push usereakhgari@mozilla.com
push dateSat, 07 Jun 2014 03:17:16 +0000
treeherdermozilla-inbound@d7dc39d16234 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj, Waldo
bugs1013662
milestone32.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 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);