From 7d4ca9c88b473ea641a0c589699bba242dbb6a33 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Fri, 16 Sep 2016 17:23:55 +1000 Subject: [PATCH] Bug 1303302 - Add IsDestructible trait in TypeTraits and use it for refcounted type static check. r=froydnj MozReview-Commit-ID: G3YFhrJngq0 --HG-- extra : rebase_source : da0aa325eb7772c1a156440ed46be9d0d429c91e --- mfbt/TypeTraits.h | 21 +++++++++++++++ mfbt/tests/TestTypeTraits.cpp | 22 +++++++++++++++ xpcom/glue/nsISupportsImpl.h | 51 +---------------------------------- 3 files changed, 44 insertions(+), 50 deletions(-) diff --git a/mfbt/TypeTraits.h b/mfbt/TypeTraits.h index b3f467649704..084f608caa1e 100644 --- a/mfbt/TypeTraits.h +++ b/mfbt/TypeTraits.h @@ -572,6 +572,27 @@ struct IsUnsignedHelper : FalseType {}; template struct IsUnsigned : detail::IsUnsignedHelper {}; +namespace detail { + +struct DoIsDestructibleImpl +{ + template().~T())> + static TrueType test(int); + template + static FalseType test(...); +}; + +template +struct IsDestructibleImpl : public DoIsDestructibleImpl +{ + typedef decltype(test(0)) Type; +}; + +} // namespace detail + +template +struct IsDestructible : public detail::IsDestructibleImpl::Type {}; + /* 20.9.5 Type property queries [meta.unary.prop.query] */ /* 20.9.6 Relationships between types [meta.rel] */ diff --git a/mfbt/tests/TestTypeTraits.cpp b/mfbt/tests/TestTypeTraits.cpp index bad834055afa..f0a565142928 100644 --- a/mfbt/tests/TestTypeTraits.cpp +++ b/mfbt/tests/TestTypeTraits.cpp @@ -31,6 +31,7 @@ using mozilla::IsRvalueReference; using mozilla::IsSame; using mozilla::IsSigned; using mozilla::IsUnsigned; +using mozilla::IsDestructible; using mozilla::MakeSigned; using mozilla::MakeUnsigned; using mozilla::RemoveExtent; @@ -352,6 +353,27 @@ static_assert(!IsSigned::value, static_assert(!IsUnsigned::value, "non-arithmetic types are not unsigned"); +class PublicDestructible +{ +public: + ~PublicDestructible(); +}; +class PrivateDestructible +{ +private: + ~PrivateDestructible(); +}; +class TrivialDestructible +{ +}; + +static_assert(IsDestructible::value, + "public destructible class is destructible"); +static_assert(!IsDestructible::value, + "private destructible class is not destructible"); +static_assert(IsDestructible::value, + "trivial destructible class is destructible"); + namespace CPlusPlus11IsBaseOf { // Adapted from C++11 ยง 20.9.6. diff --git a/xpcom/glue/nsISupportsImpl.h b/xpcom/glue/nsISupportsImpl.h index 3c61e52980a0..50c827b8154a 100644 --- a/xpcom/glue/nsISupportsImpl.h +++ b/xpcom/glue/nsISupportsImpl.h @@ -29,59 +29,10 @@ #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 -# define MOZ_IS_DESTRUCTIBLE(X) (std::is_destructible::value) -#elif defined MOZ_CAN_USE_IS_DESTRUCTIBLE_FALLBACK - namespace mozilla { - struct IsDestructibleFallbackImpl - { - template().~T())> - static TrueType Test(int); - - template - static FalseType Test(...); - - template - struct Selector - { - typedef decltype(Test(0)) type; - }; - }; - - template - struct IsDestructibleFallback - : IsDestructibleFallbackImpl::Selector::type - { - }; - } // namespace mozilla -# define MOZ_IS_DESTRUCTIBLE(X) (mozilla::IsDestructibleFallback::value) -#endif - -#ifdef MOZ_IS_DESTRUCTIBLE #define MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(X) \ - static_assert(!MOZ_IS_DESTRUCTIBLE(X), \ + static_assert(!mozilla::IsDestructible::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)