diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/ADT/ilist.h | 24 | ||||
-rw-r--r-- | llvm/unittests/ADT/ilistTest.cpp | 21 |
2 files changed, 34 insertions, 11 deletions
diff --git a/llvm/include/llvm/ADT/ilist.h b/llvm/include/llvm/ADT/ilist.h index 3723039bbad..f64413d5869 100644 --- a/llvm/include/llvm/ADT/ilist.h +++ b/llvm/include/llvm/ADT/ilist.h @@ -85,12 +85,15 @@ template <class TraitsT, class NodeT> struct HasGetNext { template <size_t N> struct SFINAE {}; template <class U> - static Yes &hasGetNext( - SFINAE<sizeof(static_cast<NodeT *>(make<U>().getNext(&make<NodeT>())))> - * = 0); - template <class U> static No &hasGetNext(...); + static Yes &test(U *I, decltype(I->getNext(&make<NodeT>())) * = 0); + template <class> static No &test(...); - static const bool value = sizeof(hasGetNext<TraitsT>(nullptr)) == sizeof(Yes); +public: + static const bool value = sizeof(test<TraitsT>(nullptr)) == sizeof(Yes); +}; + +template <class TraitsT, class NodeT> struct HasObsoleteCustomization { + static const bool value = HasGetNext<TraitsT, NodeT>::value; }; } // end namespace ilist_detail @@ -378,12 +381,11 @@ template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > { /// template <typename NodeTy, typename Traits = ilist_traits<NodeTy>> class iplist : public Traits, ilist_node_access { -#if !defined(_MSC_VER) - // FIXME: This fails in MSVC, but it's worth keeping around to help - // non-Windows users root out bugs in their ilist_traits. - static_assert(!ilist_detail::HasGetNext<Traits, NodeTy>::value, - "ilist next and prev links are not customizable!"); -#endif + // TODO: Drop this assertion and the transitive type traits anytime after + // v4.0 is branched (i.e,. keep them for one release to help out-of-tree code + // update). + static_assert(!ilist_detail::HasObsoleteCustomization<Traits, NodeTy>::value, + "ilist customization points have changed!"); mutable NodeTy *Head; diff --git a/llvm/unittests/ADT/ilistTest.cpp b/llvm/unittests/ADT/ilistTest.cpp index b63cfd6310c..c2ad3d0dce3 100644 --- a/llvm/unittests/ADT/ilistTest.cpp +++ b/llvm/unittests/ADT/ilistTest.cpp @@ -128,4 +128,25 @@ TEST(ilistTest, UnsafeClear) { EXPECT_EQ(6, List.back().Value); } +struct Empty {}; +TEST(ilistTest, HasObsoleteCustomizationTrait) { + // Negative test for HasObsoleteCustomization. + static_assert(!ilist_detail::HasObsoleteCustomization<Empty, Node>::value, + "Empty has no customizations"); } + +struct GetNext { + Node *getNext(Node *); +}; +TEST(ilistTest, HasGetNextTrait) { + static_assert(ilist_detail::HasGetNext<GetNext, Node>::value, + "GetNext has a getNext(Node*)"); + static_assert(ilist_detail::HasObsoleteCustomization<GetNext, Node>::value, + "Empty should be obsolete because of getNext()"); + + // Negative test for HasGetNext. + static_assert(!ilist_detail::HasGetNext<Empty, Node>::value, + "Empty does not have a getNext(Node*)"); +} + +} // end namespace |