Files
ladybird/Tests/AK/TestFunction.cpp
Zaggy1024 d5bf929699 AK+Tests: Destroy moved-from CallableWrappers
We won't attempt to destroy this wrapper later because m_kind gets set
to NullPointer. If any fields of the CallableType are not movable, this
results in a leak.

A test replicating the issue before the fix is added to a new
TestFunction.cpp file.
2026-02-18 13:13:32 -06:00

78 lines
1.4 KiB
C++

/*
* Copyright (c) 2026, Gregory Bertilson <gregory@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibTest/TestCase.h>
#include <AK/Function.h>
#include <AK/NonnullRefPtr.h>
#include <AK/RefCounted.h>
namespace {
struct CopyOnly {
int& instance_count;
CopyOnly(int& count)
: instance_count(count)
{
instance_count++;
}
CopyOnly(CopyOnly const& other)
: instance_count(other.instance_count)
{
instance_count++;
}
~CopyOnly()
{
instance_count--;
}
};
}
TEST_CASE(move_construction_destroys_old_inline_wrapper)
{
int instance_count = 0;
{
Function<void()> source = [captured = CopyOnly(instance_count)]() {
(void)captured;
};
EXPECT_EQ(instance_count, 1);
Function<void()> destination = move(source);
EXPECT_EQ(instance_count, 1);
source = nullptr;
EXPECT_EQ(instance_count, 1);
}
EXPECT_EQ(instance_count, 0);
}
TEST_CASE(move_assignment_destroys_old_inline_wrapper)
{
int instance_count = 0;
{
Function<void()> source = [captured = CopyOnly(instance_count)]() {
(void)captured;
};
EXPECT_EQ(instance_count, 1);
Function<void()> destination;
destination = move(source);
EXPECT_EQ(instance_count, 1);
source = nullptr;
EXPECT_EQ(instance_count, 1);
}
EXPECT_EQ(instance_count, 0);
}