diff --git a/src/realm/sync/changeset.cpp b/src/realm/sync/changeset.cpp index cf42ec07080..0e57ce506b5 100644 --- a/src/realm/sync/changeset.cpp +++ b/src/realm/sync/changeset.cpp @@ -44,30 +44,15 @@ InternString Changeset::find_string(StringData string) const noexcept PrimaryKey Changeset::get_key(const Instruction::PrimaryKey& key) const noexcept { - // we do not use the expected `mpark::visit(overload...` because in MSVC 2019 this - // code produces a segfault for something that works on other compilers. - // See https://github.com/realm/realm-core/issues/4624 - if (const auto int64_ptr = mpark::get_if(&key)) { - return *int64_ptr; - } - else if (const auto intern_string_ptr = mpark::get_if(&key)) { - return this->get_string(*intern_string_ptr); - } - else if (const auto monostate_ptr = mpark::get_if(&key)) { - return *monostate_ptr; - } - else if (const auto global_key_ptr = mpark::get_if(&key)) { - return *global_key_ptr; - } - else if (const auto oid_ptr = mpark::get_if(&key)) { - return *oid_ptr; - } - else if (const auto uuid_ptr = mpark::get_if(&key)) { - return *uuid_ptr; - } - else { - REALM_UNREACHABLE(); // unhandled primary key type - } + return mpark::visit(overload{ + [this](InternString str) -> PrimaryKey { + return get_string(str); + }, + [](auto otherwise) -> PrimaryKey { + return otherwise; + }, + }, + key); } bool Changeset::operator==(const Changeset& that) const noexcept diff --git a/src/realm/util/overload.hpp b/src/realm/util/overload.hpp index f2ff2aac5b3..14796174610 100644 --- a/src/realm/util/overload.hpp +++ b/src/realm/util/overload.hpp @@ -23,6 +23,12 @@ namespace realm::util { template struct overload : Ts... { using Ts::operator()...; +#ifdef _MSC_VER + // https://developercommunity.visualstudio.com/t/runtime-stack-corruption-using-stdvisit/346200 + // A bug in VC++'s Empty Base Optimization causes it to compute the wrong + // size if both the type and last lambda used have zero size + char dummy = 0; +#endif }; template overload(Ts...) -> overload;