Repository: dotnet/runtime
File: src/coreclr/interpreter/simdhash.h (C/C++)

Code before:
    bool HasValue()
    {
        return Value != nullptr;
    }

    dn_simdhash_u64_ptr_holder(const dn_simdhash_u64_ptr_holder&) = delete;
    dn_simdhash_u64_ptr_holder& operator=(const dn_simdhash_u64_ptr_holder&) = delete;
    dn_simdhash_u64_ptr_holder(dn_simdhash_u64_ptr_holder&& other)
    {
        Value = other.Value;
        other.Value = nullptr;
    }
    dn_simdhash_u64_ptr_holder& operator=(dn_simdhash_u64_ptr_holder&& other)
    {
        if (this != &other)
        {
            free_hash_and_values();
            Value = other.Value;
            other.Value = nullptr;
        }
        return *this;
    }

    ~dn_simdhash_u64_ptr_holder()
    {
        free_hash_and_values();
    }
};

// Asserts that no error occurred during a simdhash add, but does not mind if no new item was inserted
inline void checkNoError(dn_simdhash_add_result result)
{
    if (result == DN_SIMDHASH_OUT_OF_MEMORY)
        NOMEM();
    else if (result < 0)
        NO_WAY("Internal error in simdhash");
}

// Asserts that a new item was successfully inserted into the simdhash
inline void checkAddedNew(dn_simdhash_add_result result)
{
    if (result == DN_SIMDHASH_OUT_OF_MEMORY)
        NOMEM();
    else if (result != DN_SIMDHASH_ADD_INSERTED)
        NO_WAY("Failed to add new item into simdhash");
}

#endif // _SIMDHASH_H_


Review comment (bug):
Missing `ValueDestroyCallback` transfer in move assignment operator: The move assignment operator should transfer the `ValueDestroyCallback` member from `other` and set it to `nullptr` in `other`, similar to how `Value` is handled. Without this, if `other` is destroyed after the move, it may still try to invoke the callback on values that now belong to the moved-to object. Add `ValueDestroyCallback = other.ValueDestroyCallback; other.ValueDestroyCallback = nullptr;` after line 130.
```suggestion
            other.Value = nullptr;
            ValueDestroyCallback = other.ValueDestroyCallback;
            other.ValueDestroyCallback = nullptr;
```

Code after:

        return Value;
    }

    bool HasValue()
    {
        return Value != nullptr;
    }

    dn_simdhash_u32_ptr_holder(const dn_simdhash_u32_ptr_holder&) = delete;
    dn_simdhash_u32_ptr_holder& operator=(const dn_simdhash_u32_ptr_holder&) = delete;
    dn_simdhash_u32_ptr_holder(dn_simdhash_u32_ptr_holder&& other)
    {
        Value = other.Value;
        ValueDestroyCallback = other.ValueDestroyCallback;
        other.Value = nullptr;
        other.ValueDestroyCallback = nullptr;
    }
    dn_simdhash_u32_ptr_holder& operator=(dn_simdhash_u32_ptr_holder&& other)
    {
        if (this != &other)
        {
            free_hash_and_values();
            Value = other.Value;
            ValueDestroyCallback = other.ValueDestroyCallback;
            other.Value = nullptr;
            other.ValueDestroyCallback = nullptr;
        }
        return *this;
    }

    ~dn_simdhash_u32_ptr_holder()
    {
        free_hash_and_values();
    }
};

// Asserts that no error occurred during a simdhash add, but does not mind if no new item was inserted
inline void checkNoError(dn_simdhash_add_result result)
{
    if (result == DN_SIMDHASH_OUT_OF_MEMORY)
        NOMEM();
    else if (result < 0)
        NO_WAY("Internal error in simdhash");
}

// Asserts that a new item was successfully inserted into the simdhash
inline void checkAddedNew(dn_simdhash_add_result result)
{
    if (result == DN_SIMDHASH_OUT_OF_MEMORY)
        NOMEM();