From b86d6ed4d7aedde857b3adee858fa025a8f6fedf Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Thu, 22 Aug 2024 00:22:11 +0800 Subject: [PATCH 1/2] Workaround for LLVM-59854 in the case of destructor of `variant` --- stl/inc/variant | 6 +- tests/std/tests/P0088R3_variant_msvc/test.cpp | 81 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/stl/inc/variant b/stl/inc/variant index 7ebf3b6cf60..f27bddbc911 100644 --- a/stl/inc/variant +++ b/stl/inc/variant @@ -378,7 +378,11 @@ public: _Variant_storage<_Rest...> _Tail; }; - _CONSTEXPR20 ~_Variant_storage_() noexcept { + _CONSTEXPR20 ~_Variant_storage_() +#ifndef __clang__ // TRANSITION, LLVM-59854 + noexcept +#endif // ^^^ no workaround ^^^ + { // explicitly non-trivial destructor (which would otherwise be defined as deleted // since the class has a variant member with a non-trivial destructor) } diff --git a/tests/std/tests/P0088R3_variant_msvc/test.cpp b/tests/std/tests/P0088R3_variant_msvc/test.cpp index adcb2967aee..3a699cbe41d 100644 --- a/tests/std/tests/P0088R3_variant_msvc/test.cpp +++ b/tests/std/tests/P0088R3_variant_msvc/test.cpp @@ -741,6 +741,87 @@ namespace msvc { } } // namespace gh2770 + namespace gh4901 { +#if _HAS_CXX20 +#define CONSTEXPR20 constexpr +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv +#define CONSTEXPR20 inline +#endif // ^^^ !_HAS_CXX20 ^^^ + struct X { + CONSTEXPR20 ~X() {} + }; + + struct Y { + X _; + }; + + struct ZA { + std::variant z; + }; + + struct ZB { + std::variant z; + }; + +#if _HAS_CXX20 + static_assert(ZA{0}.z.index() == 1); + static_assert(ZA{Y{}}.z.index() == 0); + static_assert(ZB{0}.z.index() == 0); + static_assert(ZB{Y{}}.z.index() == 1); +#endif // _HAS_CXX20 + + static_assert(std::is_nothrow_destructible_v); + static_assert(std::is_nothrow_destructible_v); + static_assert(std::is_nothrow_destructible_v>); + static_assert(std::is_nothrow_destructible_v>); + static_assert(std::is_nothrow_destructible_v); + static_assert(std::is_nothrow_destructible_v); + + // Verify that variant::~variant is always noexcept, per N4988 [res.on.exception.handling]/3. + struct X2 { + CONSTEXPR20 ~X2() noexcept(false) {} + }; + + struct Y2 { + X2 _; + }; + + struct ZA2 { + std::variant z; + }; + + struct ZB2 { + std::variant z; + }; + +#if _HAS_CXX20 + static_assert(ZA2{0}.z.index() == 1); + static_assert(ZA2{Y2{}}.z.index() == 0); + static_assert(ZB2{0}.z.index() == 0); + static_assert(ZB2{Y2{}}.z.index() == 1); +#endif // _HAS_CXX20 + + static_assert(!std::is_nothrow_destructible_v); + static_assert(!std::is_nothrow_destructible_v); + static_assert(std::is_nothrow_destructible_v>); + static_assert(std::is_nothrow_destructible_v>); + static_assert(std::is_nothrow_destructible_v); + static_assert(std::is_nothrow_destructible_v); + + struct ZC { + std::variant z; + }; + +#if _HAS_CXX20 + static_assert(ZC{Y{}}.z.index() == 0); + static_assert(ZC{0}.z.index() == 1); + static_assert(ZC{Y2{}}.z.index() == 2); +#endif // _HAS_CXX20 + + static_assert(std::is_nothrow_destructible_v>); + static_assert(std::is_nothrow_destructible_v); + } // namespace gh4901 + namespace assign_cv { template struct TypeIdentityImpl { From a43173268439cada4f7936aa8275a15d601f67e0 Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Wed, 21 Aug 2024 10:27:05 -0700 Subject: [PATCH 2/2] Casey's review comments --- tests/std/tests/P0088R3_variant_msvc/test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/std/tests/P0088R3_variant_msvc/test.cpp b/tests/std/tests/P0088R3_variant_msvc/test.cpp index 3a699cbe41d..412d93d68e4 100644 --- a/tests/std/tests/P0088R3_variant_msvc/test.cpp +++ b/tests/std/tests/P0088R3_variant_msvc/test.cpp @@ -777,7 +777,8 @@ namespace msvc { static_assert(std::is_nothrow_destructible_v); static_assert(std::is_nothrow_destructible_v); - // Verify that variant::~variant is always noexcept, per N4988 [res.on.exception.handling]/3. + // Verify that variant::~variant is noexcept even when an alternative has a potentially-throwing destructor, + // per N4988 [res.on.exception.handling]/3. struct X2 { CONSTEXPR20 ~X2() noexcept(false) {} }; @@ -820,6 +821,7 @@ namespace msvc { static_assert(std::is_nothrow_destructible_v>); static_assert(std::is_nothrow_destructible_v); +#undef CONSTEXPR20 } // namespace gh4901 namespace assign_cv {