Merge pull request #282 from ethereum/fix_result_move

cpp: Fix evmc::result's move assignment operator
This commit is contained in:
Paweł Bylica 2019-05-15 16:42:32 +02:00 committed by GitHub
commit 703b661826
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 8 deletions

View File

@ -3,7 +3,9 @@
## [6.2.2] - unreleased
- Fixed: [[#281](https://github.com/ethereum/evmc/pull/281)]
Compilation error of evmc::result::raw() in Visual Studio fixed.
Compilation error of `evmc::result::raw()` in Visual Studio fixed.
- Fixed: [[#282](https://github.com/ethereum/evmc/pull/282)]
The `evmc::result`'s move assignment operator fixed.
## [6.2.1] - 2019-04-29

View File

@ -39,16 +39,20 @@ public:
/// Move constructor.
result(result&& other) noexcept : evmc_result{other}
{
// Disable releaser of the rvalue object.
other.release = nullptr;
other.release = nullptr; // Disable releasing of the rvalue object.
}
result(result const&) = delete;
/// Move-and-swap assignment operator.
result& operator=(result other) noexcept
/// Move assignment operator.
///
/// The self-assigment MUST never happen.
///
/// @param other The other result object.
/// @return The reference to the left-hand side object.
result& operator=(result&& other) noexcept
{
std::swap(*this, other);
this->~result(); // Release this object.
static_cast<evmc_result&>(*this) = other; // Copy data.
other.release = nullptr; // Disable releasing of the rvalue object.
return *this;
}

View File

@ -161,3 +161,40 @@ TEST(cpp, result_raii)
}
EXPECT_EQ(release_called, 1);
}
TEST(cpp, result_move)
{
static auto release_called = 0;
auto release_fn = [](const evmc_result*) noexcept { ++release_called; };
release_called = 0;
{
auto raw = evmc_result{};
raw.gas_left = -1;
raw.release = release_fn;
auto r0 = evmc::result{raw};
EXPECT_EQ(r0.gas_left, raw.gas_left);
auto r1 = std::move(r0);
EXPECT_EQ(r1.gas_left, raw.gas_left);
}
EXPECT_EQ(release_called, 1);
release_called = 0;
{
auto raw1 = evmc_result{};
raw1.gas_left = 1;
raw1.release = release_fn;
auto raw2 = evmc_result{};
raw2.gas_left = 1;
raw2.release = release_fn;
auto r1 = evmc::result{raw1};
auto r2 = evmc::result{raw2};
r2 = std::move(r1);
}
EXPECT_EQ(release_called, 2);
}