diff --git a/include/nvexec/detail/variant.cuh b/include/nvexec/detail/variant.cuh index 16bb64ab5..0ec55b386 100644 --- a/include/nvexec/detail/variant.cuh +++ b/include/nvexec/detail/variant.cuh @@ -192,7 +192,7 @@ namespace nv::execution } union_t storage_; - index_t index_; + index_t index_{detail::npos()}; }; } // namespace nv::execution diff --git a/test/nvexec/variant.cpp b/test/nvexec/variant.cpp index 610d1cf9e..fd63181f8 100644 --- a/test/nvexec/variant.cpp +++ b/test/nvexec/variant.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include + #include "common.cuh" #include "nvexec/detail/variant.cuh" @@ -31,6 +34,19 @@ using nvexec::visit; namespace { + int variant_destructor_calls = 0; + + struct variant_destructor_probe + { + STDEXEC_ATTRIBUTE(host, device) + variant_destructor_probe() = default; + + STDEXEC_ATTRIBUTE(host, device) + ~variant_destructor_probe() + { + NV_IF_TARGET(NV_IS_HOST, (++variant_destructor_calls;)); + } + }; TEST_CASE("nvexec variant max size is correct", "[cuda][stream][containers][variant]") { @@ -57,6 +73,21 @@ namespace STATIC_REQUIRE(variant_t::size == 3); } + TEST_CASE("nvexec variant initializes its index before constructing the first alternative", + "[cuda][stream][containers][variant]") + { + using variant_type = variant_t; + + alignas(variant_type) std::byte storage[sizeof(variant_type)]{}; + variant_destructor_calls = 0; + + auto* variant = ::new (storage) variant_type; + CHECK(variant_destructor_calls == 0); + + variant->~variant_type(); + CHECK(variant_destructor_calls == 1); + } + TEST_CASE("nvexec variant emplaces alternative from CPU", "[cuda][stream][containers][variant]") { variant_t v;