Bug 1303302 - Add IsDestructible trait in TypeTraits and use it for refcounted type static check. r=froydnj
authorXidorn Quan <me@upsuper.org>
Fri, 16 Sep 2016 17:23:55 +1000
changeset 314271 60d0e1dbddc00e146462d067c56d79b7b51faf3f
parent 314270 89d35548d4fc7868351c5e7c6cc59048b66ff530
child 314272 0a60d2f3b7027f9230d07e764fa2a48bf92140ee
push id30717
push userphilringnalda@gmail.com
push dateSat, 17 Sep 2016 20:38:05 +0000
treeherdermozilla-central@b3aa1f62ce68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1303302
milestone51.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 1303302 - Add IsDestructible trait in TypeTraits and use it for refcounted type static check. r=froydnj MozReview-Commit-ID: G3YFhrJngq0
mfbt/TypeTraits.h
mfbt/tests/TestTypeTraits.cpp
xpcom/glue/nsISupportsImpl.h
--- a/mfbt/TypeTraits.h
+++ b/mfbt/TypeTraits.h
@@ -567,16 +567,37 @@ struct IsUnsignedHelper<T, false, false,
  * mozilla::IsUnsigned<int>::value is false;
  * mozilla::IsUnsigned<const unsigned int>::value is true;
  * mozilla::IsUnsigned<unsigned char>::value is true;
  * mozilla::IsUnsigned<float>::value is false.
  */
 template<typename T>
 struct IsUnsigned : detail::IsUnsignedHelper<T> {};
 
+namespace detail {
+
+struct DoIsDestructibleImpl
+{
+  template<typename T, typename = decltype(DeclVal<T&>().~T())>
+  static TrueType test(int);
+  template<typename T>
+  static FalseType test(...);
+};
+
+template<typename T>
+struct IsDestructibleImpl : public DoIsDestructibleImpl
+{
+  typedef decltype(test<T>(0)) Type;
+};
+
+} // namespace detail
+
+template<typename T>
+struct IsDestructible : public detail::IsDestructibleImpl<T>::Type {};
+
 /* 20.9.5 Type property queries [meta.unary.prop.query] */
 
 /* 20.9.6 Relationships between types [meta.rel] */
 
 /**
  * IsSame tests whether two types are the same type.
  *
  * mozilla::IsSame<int, int>::value is true;
--- a/mfbt/tests/TestTypeTraits.cpp
+++ b/mfbt/tests/TestTypeTraits.cpp
@@ -26,16 +26,17 @@ using mozilla::IsConvertible;
 using mozilla::IsEmpty;
 using mozilla::IsLvalueReference;
 using mozilla::IsPointer;
 using mozilla::IsReference;
 using mozilla::IsRvalueReference;
 using mozilla::IsSame;
 using mozilla::IsSigned;
 using mozilla::IsUnsigned;
+using mozilla::IsDestructible;
 using mozilla::MakeSigned;
 using mozilla::MakeUnsigned;
 using mozilla::RemoveExtent;
 using mozilla::RemovePointer;
 
 static_assert(!IsFunction<int>::value,
               "int is not a function type");
 static_assert(IsFunction<void(int)>::value,
@@ -347,16 +348,37 @@ class NotIntConstructible
   NotIntConstructible(int) = delete;
 };
 
 static_assert(!IsSigned<NotIntConstructible>::value,
               "non-arithmetic types are not signed");
 static_assert(!IsUnsigned<NotIntConstructible>::value,
               "non-arithmetic types are not unsigned");
 
+class PublicDestructible
+{
+public:
+  ~PublicDestructible();
+};
+class PrivateDestructible
+{
+private:
+  ~PrivateDestructible();
+};
+class TrivialDestructible
+{
+};
+
+static_assert(IsDestructible<PublicDestructible>::value,
+              "public destructible class is destructible");
+static_assert(!IsDestructible<PrivateDestructible>::value,
+              "private destructible class is not destructible");
+static_assert(IsDestructible<TrivialDestructible>::value,
+              "trivial destructible class is destructible");
+
 namespace CPlusPlus11IsBaseOf {
 
 // Adapted from C++11 ยง 20.9.6.
 struct B {};
 struct B1 : B {};
 struct B2 : B {};
 struct D : private B1, private B2 {};
 
--- a/xpcom/glue/nsISupportsImpl.h
+++ b/xpcom/glue/nsISupportsImpl.h
@@ -24,69 +24,20 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Compiler.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MacroArgs.h"
 #include "mozilla/MacroForEach.h"
 #include "mozilla/TypeTraits.h"
 
-#if defined(__clang__)
-   // bug 1028428 shows that at least in FreeBSD 10.0 with Clang 3.4 and libc++ 3.4,
-   // std::is_destructible is buggy in that it returns false when it should return true
-   // on ipc::SharedMemory. On the other hand, all Clang versions currently in use
-   // seem to handle the fallback just fine.
-#  define MOZ_CAN_USE_IS_DESTRUCTIBLE_FALLBACK
-#elif defined(__GNUC__)
-   // GCC 4.7 has buggy std::is_destructible.
-#  if MOZ_USING_LIBSTDCXX
-#    define MOZ_HAVE_STD_IS_DESTRUCTIBLE
-#  endif
-   // Some GCC versions have an ICE when using destructors in decltype().
-   // Works on GCC 4.8 at least.
-#  define MOZ_CAN_USE_IS_DESTRUCTIBLE_FALLBACK
-#endif
-
-#ifdef MOZ_HAVE_STD_IS_DESTRUCTIBLE
-#  include <type_traits>
-#  define MOZ_IS_DESTRUCTIBLE(X) (std::is_destructible<X>::value)
-#elif defined MOZ_CAN_USE_IS_DESTRUCTIBLE_FALLBACK
-  namespace mozilla {
-    struct IsDestructibleFallbackImpl
-    {
-      template<typename T, typename = decltype(DeclVal<T>().~T())>
-      static TrueType Test(int);
-
-      template<typename>
-      static FalseType Test(...);
-
-      template<typename T>
-      struct Selector
-      {
-        typedef decltype(Test<T>(0)) type;
-      };
-    };
-
-    template<typename T>
-    struct IsDestructibleFallback
-      : IsDestructibleFallbackImpl::Selector<T>::type
-    {
-    };
-  } // namespace mozilla
-#  define MOZ_IS_DESTRUCTIBLE(X) (mozilla::IsDestructibleFallback<X>::value)
-#endif
-
-#ifdef MOZ_IS_DESTRUCTIBLE
 #define MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(X) \
-  static_assert(!MOZ_IS_DESTRUCTIBLE(X), \
+  static_assert(!mozilla::IsDestructible<X>::value, \
                 "Reference-counted class " #X " should not have a public destructor. " \
                 "Make this class's destructor non-public");
-#else
-#define MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(X)
-#endif
 
 inline nsISupports*
 ToSupports(nsISupports* aSupports)
 {
   return aSupports;
 }
 
 inline nsISupports*