CaseyCarter created this revision. NOTE: Unlike my typical `variant` test PRs, this one is actually safe to merge - crazy, I know - since it only adds coverage while testing the VC++ STL.
- Define a new macro `_MSVC_STL_VER` to distinguish testing the VC++ standard library implementation in the style of `_LIBCPP_VER`. - Enable the "constexpr extension" tests for variant's copy/move constructors on VC++ - Add some new "triviality extension" tests for variant's conformance to P0602, currently only enabled on VC++ - Workaround C1XX's buggy `__is_trivially_copyable` in the variant tests. https://reviews.llvm.org/D32671 Files: test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp test/support/msvc_stdlib_force_include.hpp test/support/test.workarounds/c1xx_broken_is_trivially_copyable.pass.cpp test/support/test_workarounds.h
Index: test/support/test_workarounds.h =================================================================== --- test/support/test_workarounds.h +++ test/support/test_workarounds.h @@ -15,6 +15,7 @@ #if defined(TEST_COMPILER_C1XX) # define TEST_WORKAROUND_C1XX_BROKEN_NULLPTR_CONVERSION_OPERATOR +# define TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE #endif #endif // SUPPORT_TEST_WORKAROUNDS_H Index: test/support/test.workarounds/c1xx_broken_is_trivially_copyable.pass.cpp =================================================================== --- /dev/null +++ test/support/test.workarounds/c1xx_broken_is_trivially_copyable.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03 + +// Verify TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE. + +#include <type_traits> + +#include "test_workarounds.h" + +struct S { + S(S const&) = default; + S(S&&) = default; + S& operator=(S const&) = delete; + S& operator=(S&&) = delete; +}; + +int main() { +#if defined(TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE) + static_assert(!std::is_trivially_copyable<S>::value, ""); +#else + static_assert(std::is_trivially_copyable<S>::value, ""); +#endif +} Index: test/support/msvc_stdlib_force_include.hpp =================================================================== --- test/support/msvc_stdlib_force_include.hpp +++ test/support/msvc_stdlib_force_include.hpp @@ -26,6 +26,11 @@ #error This header may not be used when targeting libc++ #endif +// Indicates that we are using the MSVC standard library. +#ifndef _MSVC_STL_VER +#define _MSVC_STL_VER 42 +#endif + struct AssertionDialogAvoider { AssertionDialogAvoider() { _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); Index: test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp =================================================================== --- test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp +++ test/std/utilities/variant/variant.variant/variant.ctor/move.pass.cpp @@ -22,6 +22,7 @@ #include <variant> #include "test_macros.h" +#include "test_workarounds.h" struct ThrowsMove { ThrowsMove(ThrowsMove &&) noexcept(false) {} @@ -178,20 +179,48 @@ } void test_constexpr_move_ctor_extension() { -#ifdef _LIBCPP_VERSION +#if defined(_LIBCPP_VER) || defined(_MSVC_STL_VER) using V = std::variant<long, void*, const int>; +#ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE + static_assert(std::is_trivially_destructible<V>::value, ""); + static_assert(std::is_trivially_copy_constructible<V>::value, ""); + static_assert(std::is_trivially_move_constructible<V>::value, ""); + static_assert(!std::is_copy_assignable<V>::value, ""); + static_assert(!std::is_move_assignable<V>::value, ""); +#else static_assert(std::is_trivially_copyable<V>::value, ""); +#endif static_assert(std::is_trivially_move_constructible<V>::value, ""); static_assert(test_constexpr_ctor_extension_imp<0>(V(42l)), ""); static_assert(test_constexpr_ctor_extension_imp<1>(V(nullptr)), ""); static_assert(test_constexpr_ctor_extension_imp<2>(V(101)), ""); #endif } +template<class...Ts> +constexpr bool triviality_test = + std::is_trivially_move_constructible<std::variant<Ts...>>::value == + std::conjunction<std::is_trivially_move_constructible<Ts>...>::value; + +void test_triviality_extension() { +#if defined(_MSVC_STL_VER) + static_assert(triviality_test<int>, ""); + static_assert(triviality_test<MoveOnly>, ""); + static_assert(triviality_test<MoveOnlyNT>, ""); + static_assert(triviality_test<int, long>, ""); + static_assert(triviality_test<int, MoveOnly>, ""); + static_assert(triviality_test<int, MoveOnlyNT>, ""); + static_assert(triviality_test<int, ThrowsMove>, ""); + static_assert(triviality_test<int, NoCopy>, ""); + static_assert(triviality_test<int, MakeEmptyT>, ""); +#endif +} + int main() { test_move_ctor_basic(); test_move_ctor_valueless_by_exception(); test_move_noexcept(); test_move_ctor_sfinae(); test_constexpr_move_ctor_extension(); + test_triviality_extension(); } Index: test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp =================================================================== --- test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp +++ test/std/utilities/variant/variant.variant/variant.ctor/copy.pass.cpp @@ -21,6 +21,7 @@ #include <variant> #include "test_macros.h" +#include "test_workarounds.h" struct NonT { NonT(int v) : value(v) {} @@ -137,23 +138,48 @@ auto v2 = v; return v2.index() == v.index() && v2.index() == Idx && - std::get<Idx>(v2) == std::get<Idx>(v); + std::get<Idx>(v2) == std::get<Idx>(v); } void test_constexpr_copy_ctor_extension() { -#ifdef _LIBCPP_VERSION +#if defined(_LIBCPP_VER) || defined(_MSVC_STL_VER) using V = std::variant<long, void*, const int>; - static_assert(std::is_trivially_copyable<V>::value, ""); +#ifdef TEST_WORKAROUND_C1XX_BROKEN_IS_TRIVIALLY_COPYABLE + static_assert(std::is_trivially_destructible<V>::value, ""); static_assert(std::is_trivially_copy_constructible<V>::value, ""); + static_assert(std::is_trivially_move_constructible<V>::value, ""); + static_assert(!std::is_copy_assignable<V>::value, ""); + static_assert(!std::is_move_assignable<V>::value, ""); +#else + static_assert(std::is_trivially_copyable<V>::value, ""); +#endif static_assert(test_constexpr_copy_ctor_extension_imp<0>(V(42l)), ""); static_assert(test_constexpr_copy_ctor_extension_imp<1>(V(nullptr)), ""); static_assert(test_constexpr_copy_ctor_extension_imp<2>(V(101)), ""); #endif } +template<class...Ts> +constexpr bool triviality_test = + std::is_trivially_copy_constructible<std::variant<Ts...>>::value == + std::conjunction<std::is_trivially_copy_constructible<Ts>...>::value; + +void test_triviality_extension() { +#if defined(_MSVC_STL_VER) + static_assert(triviality_test<int>, ""); + static_assert(triviality_test<NonT>, ""); + static_assert(triviality_test<int, long>, ""); + static_assert(triviality_test<int, NoCopy>, ""); + static_assert(triviality_test<int, MoveOnly>, ""); + static_assert(triviality_test<int, MoveOnlyNT>, ""); + static_assert(triviality_test<int, MakeEmptyT>, ""); +#endif +} + int main() { test_copy_ctor_basic(); test_copy_ctor_valueless_by_exception(); test_copy_ctor_sfinae(); test_constexpr_copy_ctor_extension(); + test_triviality_extension(); } Index: test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp =================================================================== --- test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp +++ test/std/utilities/variant/variant.variant/variant.assign/move.pass.cpp @@ -308,12 +308,40 @@ #endif } +template<class...Ts> +constexpr bool triviality_test = + std::is_trivially_move_assignable<std::variant<Ts...>>::value == + std::conjunction< + std::is_trivially_destructible<Ts>..., + std::disjunction< + std::conjunction< + std::is_trivially_move_constructible<Ts>..., + std::is_trivially_move_assignable<Ts>...>, + std::conjunction< + std::is_trivially_copy_constructible<Ts>..., + std::is_trivially_copy_assignable<Ts>...>>>::value; + +void test_triviality_extension() { +#if defined(_MSVC_STL_VER) + static_assert(triviality_test<int>, ""); + static_assert(triviality_test<std::string>, ""); + static_assert(triviality_test<int, long>, ""); + static_assert(triviality_test<int, std::string>, ""); + static_assert(triviality_test<int, NoCopy>, ""); + static_assert(triviality_test<int, CopyOnly>, ""); + static_assert(triviality_test<int, MoveOnly>, ""); + static_assert(triviality_test<int, MoveAssign>, ""); + static_assert(triviality_test<int, MoveAssignOnly>, ""); +#endif +} + int main() { test_move_assignment_empty_empty(); test_move_assignment_non_empty_empty(); test_move_assignment_empty_non_empty(); test_move_assignment_same_index(); test_move_assignment_different_index(); test_move_assignment_sfinae(); test_move_assignment_noexcept(); + test_triviality_extension(); } Index: test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp =================================================================== --- test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp +++ test/std/utilities/variant/variant.variant/variant.assign/copy.pass.cpp @@ -385,6 +385,27 @@ #endif } +template<class...Ts> +constexpr bool triviality_test = + std::is_trivially_copy_assignable<std::variant<Ts...>>::value == + std::conjunction< + std::is_trivially_destructible<Ts>..., + std::is_trivially_copy_constructible<Ts>..., + std::is_trivially_copy_assignable<Ts>...>::value; + +void test_triviality_extension() { +#if defined(_MSVC_STL_VER) + static_assert(triviality_test<int>, ""); + static_assert(triviality_test<std::string>, ""); + static_assert(triviality_test<int, long>, ""); + static_assert(triviality_test<int, std::string>, ""); + static_assert(triviality_test<int, NoCopy>, ""); + static_assert(triviality_test<int, NothrowCopy>, ""); + static_assert(triviality_test<int, CopyOnly>, ""); + static_assert(triviality_test<int, MoveOnly>, ""); + static_assert(triviality_test<int, CopyAssign>, ""); +#endif +} int main() { test_copy_assignment_empty_empty(); @@ -394,4 +415,5 @@ test_copy_assignment_different_index(); test_copy_assignment_sfinae(); test_copy_assignment_not_noexcept(); + test_triviality_extension(); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits