Bug 1120059 - Removing unnecessary MOZ_EXPLICIT_CONVERSION macros. r?jwalden draft
authorMichelangelo De Simone <mdesimone@mozilla.com>
Wed, 13 Jul 2016 15:07:52 -0700
changeset 387794 637a6c3431856c47c4167182eaf11c60fca32404
parent 387623 08f8a5aacd8308a73f6040fe522be7ba38497561
child 525459 cd6c99413b38d2942727761ff97ce576c1881a55
push id23080
push usermdesimone@mozilla.com
push dateThu, 14 Jul 2016 21:40:04 +0000
reviewersjwalden
bugs1120059
milestone50.0a1
Bug 1120059 - Removing unnecessary MOZ_EXPLICIT_CONVERSION macros. r?jwalden MozReview-Commit-ID: 7CX1VnBRDpk
gfx/layers/LayerMetricsWrapper.h
mfbt/Attributes.h
mfbt/TypedEnumBits.h
mfbt/tests/TestTypedEnum.cpp
widget/BasicEvents.h
--- a/gfx/layers/LayerMetricsWrapper.h
+++ b/gfx/layers/LayerMetricsWrapper.h
@@ -164,17 +164,17 @@ public:
     MOZ_ASSERT(mIndex == 0 || mIndex < mLayer->GetScrollMetadataCount());
   }
 
   bool IsValid() const
   {
     return mLayer != nullptr;
   }
 
-  MOZ_EXPLICIT_CONVERSION operator bool() const
+  explicit operator bool() const
   {
     return IsValid();
   }
 
   bool IsScrollInfoLayer() const
   {
     MOZ_ASSERT(IsValid());
 
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -40,94 +40,50 @@
 #if defined(_MSC_VER)
 /*
  * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
  * without warnings (functionality used by the macros below).  These modes are
  * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
  * standardly, by checking whether __cplusplus has a C++11 or greater value.
  * Current versions of g++ do not correctly set __cplusplus, so we check both
  * for forward compatibility.
- *
- * Even though some versions of MSVC support explicit conversion operators, we
- * don't indicate support for them here, due to
- * http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug
  */
 #  define MOZ_HAVE_NEVER_INLINE          __declspec(noinline)
 #  define MOZ_HAVE_NORETURN              __declspec(noreturn)
-#  if _MSC_VER >= 1900
-#    define MOZ_HAVE_EXPLICIT_CONVERSION
-#  endif
-#  ifdef __clang__
-     /* clang-cl probably supports explicit conversions. */
-#    if __has_extension(cxx_explicit_conversions)
-#      define MOZ_HAVE_EXPLICIT_CONVERSION
-#    endif
-#  endif
 #elif defined(__clang__)
    /*
     * Per Clang documentation, "Note that marketing version numbers should not
     * be used to check for language features, as different vendors use different
     * numbering schemes. Instead, use the feature checking macros."
     */
 #  ifndef __has_extension
 #    define __has_extension __has_feature /* compatibility, for older versions of clang */
 #  endif
-#  if __has_extension(cxx_explicit_conversions)
-#    define MOZ_HAVE_EXPLICIT_CONVERSION
-#  endif
 #  if __has_attribute(noinline)
 #    define MOZ_HAVE_NEVER_INLINE        __attribute__((noinline))
 #  endif
 #  if __has_attribute(noreturn)
 #    define MOZ_HAVE_NORETURN            __attribute__((noreturn))
 #  endif
 #elif defined(__GNUC__)
-#  if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
-#    define MOZ_HAVE_EXPLICIT_CONVERSION
-#  endif
 #  define MOZ_HAVE_NEVER_INLINE          __attribute__((noinline))
 #  define MOZ_HAVE_NORETURN              __attribute__((noreturn))
 #endif
 
 /*
  * When built with clang analyzer (a.k.a scan-build), define MOZ_HAVE_NORETURN
  * to mark some false positives
  */
 #ifdef __clang_analyzer__
 #  if __has_extension(attribute_analyzer_noreturn)
 #    define MOZ_HAVE_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
 #  endif
 #endif
 
 /*
- * MOZ_EXPLICIT_CONVERSION is a specifier on a type conversion
- * overloaded operator that declares that a C++11 compiler should restrict
- * this operator to allow only explicit type conversions, disallowing
- * implicit conversions.
- *
- * Example:
- *
- *   template<typename T>
- *   class Ptr
- *   {
- *     T* mPtr;
- *     MOZ_EXPLICIT_CONVERSION operator bool() const
- *     {
- *       return mPtr != nullptr;
- *     }
- *   };
- *
- */
-#ifdef MOZ_HAVE_EXPLICIT_CONVERSION
-#  define MOZ_EXPLICIT_CONVERSION explicit
-#else
-#  define MOZ_EXPLICIT_CONVERSION /* no support */
-#endif
-
-/*
  * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the
  * method decorated with it must never be inlined, even if the compiler would
  * otherwise choose to inline the method.  Compilers aren't absolutely
  * guaranteed to support this, but most do.
  */
 #if defined(MOZ_HAVE_NEVER_INLINE)
 #  define MOZ_NEVER_INLINE      MOZ_HAVE_NEVER_INLINE
 #else
--- a/mfbt/TypedEnumBits.h
+++ b/mfbt/TypedEnumBits.h
@@ -49,17 +49,17 @@ private:
 public:
   explicit constexpr CastableTypedEnumResult(E aValue)
     : mValue(aValue)
   {}
 
   constexpr operator E() const { return mValue; }
 
   template<typename DestinationType>
-  MOZ_EXPLICIT_CONVERSION constexpr
+  explicit constexpr
   operator DestinationType() const { return DestinationType(mValue); }
 
   constexpr bool operator !() const { return !bool(mValue); }
 };
 
 #define MOZ_CASTABLETYPEDENUMRESULT_BINOP(Op, OtherType, ReturnType) \
 template<typename E> \
 constexpr ReturnType \
--- a/mfbt/tests/TestTypedEnum.cpp
+++ b/mfbt/tests/TestTypedEnum.cpp
@@ -148,21 +148,19 @@ MAKE_STANDARD_BITFIELD_FOR_TYPE(unsigned
 #undef MAKE_STANDARD_BITFIELD_FOR_TYPE
 
 template<typename T>
 void
 TestNonConvertibilityForOneType()
 {
   using mozilla::IsConvertible;
 
-#if defined(MOZ_HAVE_EXPLICIT_CONVERSION)
   static_assert(!IsConvertible<T, bool>::value, "should not be convertible");
   static_assert(!IsConvertible<T, int>::value, "should not be convertible");
   static_assert(!IsConvertible<T, uint64_t>::value, "should not be convertible");
-#endif
 
   static_assert(!IsConvertible<bool, T>::value, "should not be convertible");
   static_assert(!IsConvertible<int, T>::value, "should not be convertible");
   static_assert(!IsConvertible<uint64_t, T>::value, "should not be convertible");
 }
 
 template<typename TypedEnum>
 void
@@ -423,28 +421,22 @@ void TestNoConversionsBetweenUnrelatedTy
 
   static_assert(!IsConvertible<decltype(T1::A), T2>::value,
                 "should not be convertible");
   static_assert(!IsConvertible<decltype(T1::A), decltype(T2::A)>::value,
                 "should not be convertible");
   static_assert(!IsConvertible<decltype(T1::A), decltype(T2::A | T2::B)>::value,
                 "should not be convertible");
 
-  // The following are #ifdef MOZ_HAVE_EXPLICIT_CONVERSION because without
-  // support for explicit conversion operators, we can't easily have these bad
-  // conversions completely removed. They still do fail to compile in practice,
-  // but not in a way that we can static_assert on.
-#ifdef MOZ_HAVE_EXPLICIT_CONVERSION
   static_assert(!IsConvertible<decltype(T1::A | T1::B), T2>::value,
                 "should not be convertible");
   static_assert(!IsConvertible<decltype(T1::A | T1::B), decltype(T2::A)>::value,
                 "should not be convertible");
   static_assert(!IsConvertible<decltype(T1::A | T1::B), decltype(T2::A | T2::B)>::value,
                 "should not be convertible");
-#endif
 }
 
 enum class Int8EnumWithHighBits : int8_t {
   A = 0x20,
   B = 0x40
 };
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int8EnumWithHighBits)
 
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -567,23 +567,23 @@ public:
 class NativeEventData final
 {
   nsTArray<uint8_t> mBuffer;
 
   friend struct IPC::ParamTraits<mozilla::NativeEventData>;
 
 public:
 
-  MOZ_EXPLICIT_CONVERSION operator bool() const
+  explicit operator bool() const
   {
     return !mBuffer.IsEmpty();
   }
 
   template<typename T>
-  MOZ_EXPLICIT_CONVERSION operator const T*() const
+  explicit operator const T*() const
   {
     return mBuffer.IsEmpty()
            ? nullptr
            : reinterpret_cast<const T*>(mBuffer.Elements());
   }
 
   template <typename T>
   void Copy(const T& other)